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
9cc4c1da9SBarry 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
17*2f04c522SBarry Smith Level: intermediate
18*2f04c522SBarry Smith
190e6b6b59SJacob Faibussowitsch Notes:
200e6b6b59SJacob Faibussowitsch Currently only CUDA and HIP memtypes are supported.
210e6b6b59SJacob Faibussowitsch
22*2f04c522SBarry Smith The CUDA and HIP calls needed to determine the `PetscMemType` take a non-trivial amount of time, thus for optimal GPU performance this
23*2f04c522SBarry Smith routine should be used sparingly and instead the code should track the `PetscMemType` for its important arrays.
240e6b6b59SJacob Faibussowitsch
25aec76313SJacob Faibussowitsch .seealso: `PetscMemType`, `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
260e6b6b59SJacob Faibussowitsch `PetscDeviceArrayCopy()`, `PetscDeviceArrayZero()`
270e6b6b59SJacob Faibussowitsch @*/
PetscGetMemType(const void * ptr,PetscMemType * type)28d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetMemType(const void *ptr, PetscMemType *type)
29d71ae5a4SJacob Faibussowitsch {
300e6b6b59SJacob Faibussowitsch PetscFunctionBegin;
314f572ea9SToby Isaac PetscAssertPointer(type, 2);
320e6b6b59SJacob Faibussowitsch *type = PETSC_MEMTYPE_HOST;
333ba16761SJacob Faibussowitsch if (!ptr) PetscFunctionReturn(PETSC_SUCCESS);
340e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_CUDA)
350e6b6b59SJacob Faibussowitsch if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
360e6b6b59SJacob Faibussowitsch cudaError_t cerr;
370e6b6b59SJacob Faibussowitsch struct cudaPointerAttributes attr;
380e6b6b59SJacob Faibussowitsch enum cudaMemoryType mtype;
390e6b6b59SJacob Faibussowitsch cerr = cudaPointerGetAttributes(&attr, ptr); /* Do not check error since before CUDA 11.0, passing a host pointer returns cudaErrorInvalidValue */
400e6b6b59SJacob Faibussowitsch if (cerr) cerr = cudaGetLastError(); /* If there was an error, return it and then reset it */
410e6b6b59SJacob Faibussowitsch #if (CUDART_VERSION < 10000)
420e6b6b59SJacob Faibussowitsch mtype = attr.memoryType;
430e6b6b59SJacob Faibussowitsch #else
440e6b6b59SJacob Faibussowitsch mtype = attr.type;
450e6b6b59SJacob Faibussowitsch #endif
460e6b6b59SJacob Faibussowitsch if (cerr == cudaSuccess && mtype == cudaMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
480e6b6b59SJacob Faibussowitsch }
490e6b6b59SJacob Faibussowitsch #endif
500e6b6b59SJacob Faibussowitsch
510e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_HIP)
520e6b6b59SJacob Faibussowitsch if (PetscDeviceInitialized(PETSC_DEVICE_HIP)) {
530e6b6b59SJacob Faibussowitsch hipError_t cerr;
540e6b6b59SJacob Faibussowitsch struct hipPointerAttribute_t attr;
550e6b6b59SJacob Faibussowitsch enum hipMemoryType mtype;
560e6b6b59SJacob Faibussowitsch cerr = hipPointerGetAttributes(&attr, ptr);
570e6b6b59SJacob Faibussowitsch if (cerr) cerr = hipGetLastError();
58bdb83d9fSJed Brown #if PETSC_PKG_HIP_VERSION_GE(5, 5, 0)
59bdb83d9fSJed Brown mtype = attr.type;
60bdb83d9fSJed Brown #else
610e6b6b59SJacob Faibussowitsch mtype = attr.memoryType;
62bdb83d9fSJed Brown #endif
630e6b6b59SJacob Faibussowitsch if (cerr == hipSuccess && mtype == hipMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
640e6b6b59SJacob Faibussowitsch }
650e6b6b59SJacob Faibussowitsch #endif
663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
670e6b6b59SJacob Faibussowitsch }
68