xref: /petsc/src/sys/objects/device/util/memory.c (revision 6220ef827cfb29f143b71dc8d0e16ee8b5f4575d)
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, No Fortran Support
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   Level: intermediate
18 
19   Notes:
20   Currently only CUDA and HIP memtypes are supported.
21 
22   The CUDA and HIP calls needed to determine the `PetscMemType` take a non-trivial amount of time, thus for optimal GPU performance this
23   routine should be used sparingly and instead the code should track the `PetscMemType` for its important arrays.
24 
25 .seealso: `PetscMemType`, `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
26 `PetscDeviceArrayCopy()`, `PetscDeviceArrayZero()`
27 @*/
28 PetscErrorCode PetscGetMemType(const void *ptr, PetscMemType *type)
29 {
30   PetscFunctionBegin;
31   PetscAssertPointer(type, 2);
32   *type = PETSC_MEMTYPE_HOST;
33   if (!ptr) PetscFunctionReturn(PETSC_SUCCESS);
34 #if PetscDefined(HAVE_CUDA)
35   if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
36     cudaError_t                  cerr;
37     struct cudaPointerAttributes attr;
38     enum cudaMemoryType          mtype;
39     cerr = cudaPointerGetAttributes(&attr, ptr); /* Do not check error since before CUDA 11.0, passing a host pointer returns cudaErrorInvalidValue */
40     if (cerr) cerr = cudaGetLastError();         /* If there was an error, return it and then reset it */
41   #if (CUDART_VERSION < 10000)
42     mtype = attr.memoryType;
43   #else
44     mtype = attr.type;
45   #endif
46     if (cerr == cudaSuccess && mtype == cudaMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
47     PetscFunctionReturn(PETSC_SUCCESS);
48   }
49 #endif
50 
51 #if PetscDefined(HAVE_HIP)
52   if (PetscDeviceInitialized(PETSC_DEVICE_HIP)) {
53     hipError_t                   cerr;
54     struct hipPointerAttribute_t attr;
55     enum hipMemoryType           mtype;
56     cerr = hipPointerGetAttributes(&attr, ptr);
57     if (cerr) cerr = hipGetLastError();
58   #if PETSC_PKG_HIP_VERSION_GE(5, 5, 0)
59     mtype = attr.type;
60   #else
61     mtype = attr.memoryType;
62   #endif
63     if (cerr == hipSuccess && mtype == hipMemoryTypeDevice) *type = PETSC_MEMTYPE_DEVICE;
64   }
65 #endif
66   PetscFunctionReturn(PETSC_SUCCESS);
67 }
68