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, No Fortran Support
11: Input Parameter:
12: . ptr - The pointer to query (may be `NULL`)
14: Output Parameter:
15: . type - The `PetscMemType` of the pointer
17: Level: intermediate
19: Notes:
20: Currently only CUDA and HIP memtypes are supported.
22: The CUDA and HIP calls needed to determine the `PetscMemType` take a non-trivial amount of time, thus for optimal GPU performance this
23: routine should be used sparingly and instead the code should track the `PetscMemType` for its important arrays.
25: .seealso: `PetscMemType`, `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
26: `PetscDeviceArrayCopy()`, `PetscDeviceArrayZero()`
27: @*/
28: PetscErrorCode PetscGetMemType(const void *ptr, PetscMemType *type)
29: {
30: PetscFunctionBegin;
31: PetscAssertPointer(type, 2);
32: *type = PETSC_MEMTYPE_HOST;
33: if (!ptr) PetscFunctionReturn(PETSC_SUCCESS);
34: #if PetscDefined(HAVE_CUDA)
35: if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
36: cudaError_t cerr;
37: struct cudaPointerAttributes attr;
38: enum cudaMemoryType mtype;
39: cerr = cudaPointerGetAttributes(&attr, ptr); /* Do not check error since before CUDA 11.0, passing a host pointer returns cudaErrorInvalidValue */
40: if (cerr) cerr = cudaGetLastError(); /* If there was an error, return it and then reset it */
41: #if (CUDART_VERSION < 10000)
42: mtype = attr.memoryType;
43: #else
44: mtype = attr.type;
45: #endif
46: // CUDA managed memory is device accessible, so we treat it as device memory?
47: if (cerr == cudaSuccess && (mtype == cudaMemoryTypeDevice || mtype == cudaMemoryTypeManaged)) *type = PETSC_MEMTYPE_DEVICE;
48: PetscFunctionReturn(PETSC_SUCCESS);
49: }
50: #endif
52: #if PetscDefined(HAVE_HIP)
53: if (PetscDeviceInitialized(PETSC_DEVICE_HIP)) {
54: hipError_t cerr;
55: struct hipPointerAttribute_t attr;
56: enum hipMemoryType mtype;
57: cerr = hipPointerGetAttributes(&attr, ptr);
58: if (cerr) cerr = hipGetLastError();
59: #if PETSC_PKG_HIP_VERSION_GE(5, 5, 0)
60: mtype = attr.type;
61: #else
62: mtype = attr.memoryType;
63: #endif
64: if (cerr == hipSuccess && (mtype == hipMemoryTypeDevice || mtype == hipMemoryTypeManaged)) *type = PETSC_MEMTYPE_DEVICE;
65: }
66: #endif
67: PetscFunctionReturn(PETSC_SUCCESS);
68: }