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