Actual source code: memory.c
1: #include <petsc/private/deviceimpl.h>
2: #include <petscdevice_cupm.h>
4: // REVIEW ME: this should probably return PETSC_MEMTYPE_CUDA and PETSC_MEMTYPE_HIP
6: /*@C
7: PetscGetMemType - Query the `PetscMemType` of a pointer
9: Not Collective
11: Input Parameter:
12: . ptr - The pointer to query (may be `NULL`)
14: Output Parameter:
15: . type - The `PetscMemType` of the pointer
17: Notes:
18: Currently only CUDA and HIP memtypes are supported.
20: Level: intermediate
22: .seealso: `PetscMemType`, `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
23: `PetscDeviceArrayCopy()`, `PetscDeviceArrayZero()`
24: @*/
25: PetscErrorCode PetscGetMemType(const void *ptr, PetscMemType *type)
26: {
27: PetscFunctionBegin;
28: PetscAssertPointer(type, 2);
29: *type = PETSC_MEMTYPE_HOST;
30: if (!ptr) PetscFunctionReturn(PETSC_SUCCESS);
31: #if PetscDefined(HAVE_CUDA)
32: if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
33: cudaError_t cerr;
34: struct cudaPointerAttributes attr;
35: enum cudaMemoryType mtype;
36: cerr = cudaPointerGetAttributes(&attr, ptr); /* Do not check error since before CUDA 11.0, passing a host pointer returns cudaErrorInvalidValue */
37: if (cerr) cerr = cudaGetLastError(); /* If there was an error, return it and then reset it */
38: #if (CUDART_VERSION < 10000)
39: mtype = attr.memoryType;
40: #else
41: mtype = attr.type;
42: #endif
43: if (cerr == cudaSuccess && mtype == cudaMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
44: PetscFunctionReturn(PETSC_SUCCESS);
45: }
46: #endif
48: #if PetscDefined(HAVE_HIP)
49: if (PetscDeviceInitialized(PETSC_DEVICE_HIP)) {
50: hipError_t cerr;
51: struct hipPointerAttribute_t attr;
52: enum hipMemoryType mtype;
53: cerr = hipPointerGetAttributes(&attr, ptr);
54: if (cerr) cerr = hipGetLastError();
55: mtype = attr.memoryType;
56: if (cerr == hipSuccess && mtype == hipMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
57: }
58: #endif
59: PetscFunctionReturn(PETSC_SUCCESS);
60: }