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