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