xref: /petsc/src/sys/objects/device/util/memory.c (revision cc4c1da905d89950b196b027190941013bd3e15a)
10e6b6b59SJacob Faibussowitsch #include <petsc/private/deviceimpl.h> /*I <petscdevice.h> I*/
20e6b6b59SJacob Faibussowitsch #include <petscdevice_cupm.h>
30e6b6b59SJacob Faibussowitsch 
40e6b6b59SJacob Faibussowitsch // REVIEW ME: this should probably return PETSC_MEMTYPE_CUDA and PETSC_MEMTYPE_HIP
50e6b6b59SJacob Faibussowitsch 
60e6b6b59SJacob Faibussowitsch /*@C
70e6b6b59SJacob Faibussowitsch   PetscGetMemType - Query the `PetscMemType` of a pointer
80e6b6b59SJacob Faibussowitsch 
9*cc4c1da9SBarry Smith   Not Collective, No Fortran Support
100e6b6b59SJacob Faibussowitsch 
110e6b6b59SJacob Faibussowitsch   Input Parameter:
120e6b6b59SJacob Faibussowitsch . ptr - The pointer to query (may be `NULL`)
130e6b6b59SJacob Faibussowitsch 
140e6b6b59SJacob Faibussowitsch   Output Parameter:
150e6b6b59SJacob Faibussowitsch . type - The `PetscMemType` of the pointer
160e6b6b59SJacob Faibussowitsch 
170e6b6b59SJacob Faibussowitsch   Notes:
180e6b6b59SJacob Faibussowitsch   Currently only CUDA and HIP memtypes are supported.
190e6b6b59SJacob Faibussowitsch 
200e6b6b59SJacob Faibussowitsch   Level: intermediate
210e6b6b59SJacob Faibussowitsch 
22aec76313SJacob Faibussowitsch .seealso: `PetscMemType`, `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
230e6b6b59SJacob Faibussowitsch `PetscDeviceArrayCopy()`, `PetscDeviceArrayZero()`
240e6b6b59SJacob Faibussowitsch @*/
25d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetMemType(const void *ptr, PetscMemType *type)
26d71ae5a4SJacob Faibussowitsch {
270e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
284f572ea9SToby Isaac   PetscAssertPointer(type, 2);
290e6b6b59SJacob Faibussowitsch   *type = PETSC_MEMTYPE_HOST;
303ba16761SJacob Faibussowitsch   if (!ptr) PetscFunctionReturn(PETSC_SUCCESS);
310e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_CUDA)
320e6b6b59SJacob Faibussowitsch   if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
330e6b6b59SJacob Faibussowitsch     cudaError_t                  cerr;
340e6b6b59SJacob Faibussowitsch     struct cudaPointerAttributes attr;
350e6b6b59SJacob Faibussowitsch     enum cudaMemoryType          mtype;
360e6b6b59SJacob Faibussowitsch     cerr = cudaPointerGetAttributes(&attr, ptr); /* Do not check error since before CUDA 11.0, passing a host pointer returns cudaErrorInvalidValue */
370e6b6b59SJacob Faibussowitsch     if (cerr) cerr = cudaGetLastError();         /* If there was an error, return it and then reset it */
380e6b6b59SJacob Faibussowitsch   #if (CUDART_VERSION < 10000)
390e6b6b59SJacob Faibussowitsch     mtype = attr.memoryType;
400e6b6b59SJacob Faibussowitsch   #else
410e6b6b59SJacob Faibussowitsch     mtype = attr.type;
420e6b6b59SJacob Faibussowitsch   #endif
430e6b6b59SJacob Faibussowitsch     if (cerr == cudaSuccess && mtype == cudaMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
443ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
450e6b6b59SJacob Faibussowitsch   }
460e6b6b59SJacob Faibussowitsch #endif
470e6b6b59SJacob Faibussowitsch 
480e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_HIP)
490e6b6b59SJacob Faibussowitsch   if (PetscDeviceInitialized(PETSC_DEVICE_HIP)) {
500e6b6b59SJacob Faibussowitsch     hipError_t                   cerr;
510e6b6b59SJacob Faibussowitsch     struct hipPointerAttribute_t attr;
520e6b6b59SJacob Faibussowitsch     enum hipMemoryType           mtype;
530e6b6b59SJacob Faibussowitsch     cerr = hipPointerGetAttributes(&attr, ptr);
540e6b6b59SJacob Faibussowitsch     if (cerr) cerr = hipGetLastError();
550e6b6b59SJacob Faibussowitsch     mtype = attr.memoryType;
560e6b6b59SJacob Faibussowitsch     if (cerr == hipSuccess && mtype == hipMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
570e6b6b59SJacob Faibussowitsch   }
580e6b6b59SJacob Faibussowitsch #endif
593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
600e6b6b59SJacob Faibussowitsch }
61