xref: /petsc/include/petscdevice.h (revision 6797ed33bfc5684cca29e5d9b9bbfc6c8aac93e0)
10e6b6b59SJacob Faibussowitsch #ifndef PETSCDEVICE_H
2030f984aSJacob Faibussowitsch #define PETSCDEVICE_H
3030f984aSJacob Faibussowitsch 
4030f984aSJacob Faibussowitsch #include <petscdevicetypes.h>
50e6b6b59SJacob Faibussowitsch #include <petscviewertypes.h>
6030f984aSJacob Faibussowitsch 
7*6797ed33SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 11 // C++11
8*6797ed33SJacob Faibussowitsch #define PETSC_DEVICE_ALIGNOF(...) alignof(decltype(__VA_ARGS__))
9*6797ed33SJacob Faibussowitsch #elif PETSC_C_VERSION >= 11 // C11
10*6797ed33SJacob Faibussowitsch #ifdef __GNUC__
11*6797ed33SJacob Faibussowitsch #define PETSC_DEVICE_ALIGNOF(...) _Alignof(__typeof__(__VA_ARGS__))
12*6797ed33SJacob Faibussowitsch #else
13*6797ed33SJacob Faibussowitsch #include <stddef.h> // max_align_t
14*6797ed33SJacob Faibussowitsch // Note we cannot just do _Alignof(expression) since clang warns that "'_Alignof' applied to an
15*6797ed33SJacob Faibussowitsch // expression is a GNU extension", so we just default to max_align_t which is ultra safe
16*6797ed33SJacob Faibussowitsch #define PETSC_DEVICE_ALIGNOF(...) _Alignof(max_align_t)
17*6797ed33SJacob Faibussowitsch #endif // __GNUC__
18*6797ed33SJacob Faibussowitsch #else
19*6797ed33SJacob Faibussowitsch #define PETSC_DEVICE_ALIGNOF(...) PETSC_MEMALIGN
20*6797ed33SJacob Faibussowitsch #endif
21*6797ed33SJacob Faibussowitsch 
220e6b6b59SJacob Faibussowitsch /* SUBMANSEC = Sys */
23030f984aSJacob Faibussowitsch 
240e6b6b59SJacob Faibussowitsch // REVIEW ME: this should probably go somewhere better, configure-time?
250e6b6b59SJacob Faibussowitsch #define PETSC_HAVE_HOST 1
26030f984aSJacob Faibussowitsch 
270e6b6b59SJacob Faibussowitsch /* logging support */
280e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscClassId PETSC_DEVICE_CLASSID;
290e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscClassId PETSC_DEVICE_CONTEXT_CLASSID;
30030f984aSJacob Faibussowitsch 
31030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceInitializePackage(void);
32030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceFinalizePackage(void);
330e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscGetMemType(const void *, PetscMemType *);
34030f984aSJacob Faibussowitsch 
35030f984aSJacob Faibussowitsch /* PetscDevice */
360e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_CXX)
37a4af0ceeSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceCreate(PetscDeviceType, PetscInt, PetscDevice *);
380e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceDestroy(PetscDevice *);
39030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceConfigure(PetscDevice);
40a4af0ceeSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceView(PetscDevice, PetscViewer);
410e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceGetType(PetscDevice, PetscDeviceType *);
4291e63d38SStefano Zampini PETSC_EXTERN PetscErrorCode  PetscDeviceGetDeviceId(PetscDevice, PetscInt *);
430e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscDeviceType PETSC_DEVICE_DEFAULT(void);
440e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceSetDefaultDeviceType(PetscDeviceType);
450e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode  PetscDeviceInitialize(PetscDeviceType);
460e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscBool       PetscDeviceInitialized(PetscDeviceType);
470e6b6b59SJacob Faibussowitsch #else
480e6b6b59SJacob Faibussowitsch #define PetscDeviceCreate(PetscDeviceType, PetscInt, dev) (*(dev) = PETSC_NULLPTR, 0)
490e6b6b59SJacob Faibussowitsch #define PetscDeviceDestroy(dev)                           (*(dev) = PETSC_NULLPTR, 0)
500e6b6b59SJacob Faibussowitsch #define PetscDeviceConfigure(PetscDevice)                 0
510e6b6b59SJacob Faibussowitsch #define PetscDeviceView(PetscDevice, PetscViewer)         0
520e6b6b59SJacob Faibussowitsch #define PetscDeviceGetType(PetscDevice, type)             (*(type) = PETSC_DEVICE_DEFAULT(), 0)
530e6b6b59SJacob Faibussowitsch #define PetscDeviceGetDeviceId(PetscDevice, id)           (*(id) = 0)
540e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DEFAULT()                            PETSC_DEVICE_HOST
550e6b6b59SJacob Faibussowitsch #define PetscDeviceSetDefaultDeviceType(PetscDeviceType)  0
560e6b6b59SJacob Faibussowitsch #define PetscDeviceInitialize(PetscDeviceType)            0
570e6b6b59SJacob Faibussowitsch #define PetscDeviceInitialized(dtype)                     ((dtype) == PETSC_DEVICE_HOST)
580e6b6b59SJacob Faibussowitsch #endif /* PetscDefined(HAVE_CXX) */
59030f984aSJacob Faibussowitsch 
60030f984aSJacob Faibussowitsch /* PetscDeviceContext */
610e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_CXX)
62030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextCreate(PetscDeviceContext *);
63030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextDestroy(PetscDeviceContext *);
64030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType);
65030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetStreamType(PetscDeviceContext, PetscStreamType *);
660e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice);
670e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDevice(PetscDeviceContext, PetscDevice *);
680e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDeviceType(PetscDeviceContext, PetscDeviceType *);
69030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetUp(PetscDeviceContext);
70030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextDuplicate(PetscDeviceContext, PetscDeviceContext *);
71030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextQueryIdle(PetscDeviceContext, PetscBool *);
72030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextWaitForContext(PetscDeviceContext, PetscDeviceContext);
730e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextForkWithStreamType(PetscDeviceContext, PetscStreamType, PetscInt, PetscDeviceContext **);
74030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextFork(PetscDeviceContext, PetscInt, PetscDeviceContext **);
75030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextJoin(PetscDeviceContext, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContext **);
76030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSynchronize(PetscDeviceContext);
770e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext);
780e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextView(PetscDeviceContext, PetscViewer);
790e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, PetscViewer);
80030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetCurrentContext(PetscDeviceContext *);
81030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetCurrentContext(PetscDeviceContext);
82f61c9696SKaushik Kulkarni #else
830e6b6b59SJacob Faibussowitsch #define PetscDeviceContextCreate(dctx)                                                                            (*(dctx) = PETSC_NULLPTR, 0)
840e6b6b59SJacob Faibussowitsch #define PetscDeviceContextDestroy(dctx)                                                                           (*(dctx) = PETSC_NULLPTR, 0)
850e6b6b59SJacob Faibussowitsch #define PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType)                                      0
860e6b6b59SJacob Faibussowitsch #define PetscDeviceContextGetStreamType(PetscDeviceContext, type)                                                 (*(type) = PETSC_STREAM_GLOBAL_BLOCKING, 0)
870e6b6b59SJacob Faibussowitsch #define PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice)                                              0
880e6b6b59SJacob Faibussowitsch #define PetscDeviceContextGetDevice(PetscDeviceContext, device)                                                   (*(device) = PETSC_NULLPTR, 0)
890e6b6b59SJacob Faibussowitsch #define PetscDeviceContextGetDeviceType(PetscDeviceContext, type)                                                 (*(type) = PETSC_DEVICE_DEFAULT())
900e6b6b59SJacob Faibussowitsch #define PetscDeviceContextSetUp(PetscDeviceContext)                                                               0
910e6b6b59SJacob Faibussowitsch #define PetscDeviceContextDuplicate(PetscDeviceContextl, PetscDeviceContextr)                                     (*(PetscDeviceContextr) = PETSC_NULLPTR, 0)
920e6b6b59SJacob Faibussowitsch #define PetscDeviceContextQueryIdle(PetscDeviceContext, idle)                                                     (*(idle) = PETSC_TRUE, 0)
930e6b6b59SJacob Faibussowitsch #define PetscDeviceContextWaitForContext(PetscDeviceContextl, PetscDeviceContextr)                                0
940e6b6b59SJacob Faibussowitsch #define PetscDeviceContextForkWithStreamType(PetscDeviceContextp, PetscStreamType, PetscInt, PetscDeviceContextc) (*(PetscDeviceContextc) = PETSC_NULLPTR, 0)
950e6b6b59SJacob Faibussowitsch #define PetscDeviceContextFork(PetscDeviceContextp, PetscInt, PetscDeviceContextc)                                (*(PetscDeviceContextc) = PETSC_NULLPTR, 0)
960e6b6b59SJacob Faibussowitsch #define PetscDeviceContextJoin(PetscDeviceContextp, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContextc)    (*(PetscDeviceContextc) = PETSC_NULLPTR, 0)
970e6b6b59SJacob Faibussowitsch #define PetscDeviceContextSynchronize(PetscDeviceContext)                                                         0
980e6b6b59SJacob Faibussowitsch #define PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext)                                            0
990e6b6b59SJacob Faibussowitsch #define PetscDeviceContextView(PetscDeviceContext, PetscViewer)                                                   0
1000e6b6b59SJacob Faibussowitsch #define PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, PetscViewer)                           0
1010e6b6b59SJacob Faibussowitsch #define PetscDeviceContextGetCurrentContext(dctx)                                                                 (*(dctx) = PETSC_NULLPTR, 0)
1020e6b6b59SJacob Faibussowitsch #define PetscDeviceContextSetCurrentContext(PetscDeviceContext)                                                   0
1030e6b6b59SJacob Faibussowitsch #endif /* PetscDefined(HAVE_CXX) */
1040e6b6b59SJacob Faibussowitsch 
1050e6b6b59SJacob Faibussowitsch /* memory */
1060e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_CXX)
107*6797ed33SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceAllocate_Private(PetscDeviceContext, PetscBool, PetscMemType, size_t, size_t, void **PETSC_RESTRICT);
108*6797ed33SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceDeallocate_Private(PetscDeviceContext, void *PETSC_RESTRICT);
1090e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceMemcpy(PetscDeviceContext, void *PETSC_RESTRICT, const void *PETSC_RESTRICT, size_t);
1100e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceMemset(PetscDeviceContext, void *PETSC_RESTRICT, PetscInt, size_t);
1110e6b6b59SJacob Faibussowitsch #else
1120e6b6b59SJacob Faibussowitsch #include <string.h> // memset()
113*6797ed33SJacob Faibussowitsch #define PetscDeviceAllocate_Private(PetscDeviceContext, clear, PetscMemType, size, alignment, ptr) PetscMallocA(1, (clear), __LINE__, PETSC_FUNCTION_NAME, __FILE__, (size), (ptr))
114*6797ed33SJacob Faibussowitsch #define PetscDeviceDeallocate_Private(PetscDeviceContext, ptr)                                     PetscFree((ptr))
1150e6b6b59SJacob Faibussowitsch #define PetscDeviceMemcpy(PetscDeviceContext, dest, src, size)                                     PetscMemcpy((dest), (src), (size))
1160e6b6b59SJacob Faibussowitsch #define PetscDeviceMemset(PetscDeviceContext, ptr, v, size)                                        ((void)memset((ptr), (unsigned char)(v), (size)), 0)
1170e6b6b59SJacob Faibussowitsch #endif /* PetscDefined(HAVE_CXX) */
1180e6b6b59SJacob Faibussowitsch 
1190e6b6b59SJacob Faibussowitsch /*MC
1200e6b6b59SJacob Faibussowitsch   PetscDeviceMalloc - Allocate device-aware memory
1210e6b6b59SJacob Faibussowitsch 
1220e6b6b59SJacob Faibussowitsch   Synopsis:
1230e6b6b59SJacob Faibussowitsch   #include <petscdevice.h>
1240e6b6b59SJacob Faibussowitsch   PetscErrorCode PetscDeviceMalloc(PetscDeviceContext dctx, PetscMemType mtype, size_t n, Type **ptr)
1250e6b6b59SJacob Faibussowitsch 
1260e6b6b59SJacob Faibussowitsch   Not Collective, Asynchronous, Auto-dependency aware
1270e6b6b59SJacob Faibussowitsch 
1280e6b6b59SJacob Faibussowitsch   Input Parameters:
1290e6b6b59SJacob Faibussowitsch + dctx  - The `PetscDeviceContext` used to allocate the memory
1300e6b6b59SJacob Faibussowitsch . mtype - The type of memory to allocate
1310e6b6b59SJacob Faibussowitsch - n     - The amount (in elements) to allocate
1320e6b6b59SJacob Faibussowitsch 
1330e6b6b59SJacob Faibussowitsch   Output Parameter:
1340e6b6b59SJacob Faibussowitsch . ptr - The pointer to store the result in
1350e6b6b59SJacob Faibussowitsch 
1360e6b6b59SJacob Faibussowitsch   Notes:
137*6797ed33SJacob Faibussowitsch   Memory allocated with this function must be freed with `PetscDeviceFree()`.
1380e6b6b59SJacob Faibussowitsch 
139*6797ed33SJacob Faibussowitsch   If `n` is zero, then `ptr` is set to `PETSC_NULLPTR`.
140*6797ed33SJacob Faibussowitsch 
141*6797ed33SJacob Faibussowitsch   This routine falls back to using `PetscMalloc1()` if PETSc was not configured with device
142*6797ed33SJacob Faibussowitsch   support. The user should note that `mtype` is ignored in this case, as `PetscMalloc1()`
143*6797ed33SJacob Faibussowitsch   allocates only host memory.
144*6797ed33SJacob Faibussowitsch 
145*6797ed33SJacob Faibussowitsch   This routine uses the `sizeof()` of the memory type requested to determine the total memory
146*6797ed33SJacob Faibussowitsch   to be allocated, therefore you should not multiply the number of elements requested by the
1470e6b6b59SJacob Faibussowitsch   `sizeof()` the type\:
1480e6b6b59SJacob Faibussowitsch 
1490e6b6b59SJacob Faibussowitsch .vb
1500e6b6b59SJacob Faibussowitsch   PetscInt *arr;
1510e6b6b59SJacob Faibussowitsch 
1520e6b6b59SJacob Faibussowitsch   // correct
1530e6b6b59SJacob Faibussowitsch   PetscDeviceMalloc(dctx,PETSC_MEMTYPE_DEVICE,n,&arr);
1540e6b6b59SJacob Faibussowitsch 
1550e6b6b59SJacob Faibussowitsch   // incorrect
1560e6b6b59SJacob Faibussowitsch   PetscDeviceMalloc(dctx,PETSC_MEMTYPE_DEVICE,n*sizeof(*arr),&arr);
1570e6b6b59SJacob Faibussowitsch .ve
1580e6b6b59SJacob Faibussowitsch 
159*6797ed33SJacob Faibussowitsch   Note result stored `ptr` is immediately valid and the user may freely inspect or manipulate
160*6797ed33SJacob Faibussowitsch   its value on function return, i.e.\:
161*6797ed33SJacob Faibussowitsch 
162*6797ed33SJacob Faibussowitsch .vb
163*6797ed33SJacob Faibussowitsch   PetscInt *ptr;
164*6797ed33SJacob Faibussowitsch 
165*6797ed33SJacob Faibussowitsch   PetscDeviceMalloc(dctx, PETSC_MEMTYPE_DEVICE, 20, &ptr);
166*6797ed33SJacob Faibussowitsch 
167*6797ed33SJacob Faibussowitsch   PetscInt *sub_ptr = ptr + 10; // OK, no need to synchronize
168*6797ed33SJacob Faibussowitsch 
169*6797ed33SJacob Faibussowitsch   ptr[0] = 10; // ERROR, directly accessing contents of ptr is undefined until synchronization
170*6797ed33SJacob Faibussowitsch .ve
171*6797ed33SJacob Faibussowitsch 
172*6797ed33SJacob Faibussowitsch   DAG representation:
173*6797ed33SJacob Faibussowitsch .vb
174*6797ed33SJacob Faibussowitsch   time ->
175*6797ed33SJacob Faibussowitsch 
176*6797ed33SJacob Faibussowitsch   -> dctx - |= CALL =| -\- dctx -->
177*6797ed33SJacob Faibussowitsch                          \- ptr ->
178*6797ed33SJacob Faibussowitsch .ve
1790e6b6b59SJacob Faibussowitsch 
1800e6b6b59SJacob Faibussowitsch   Level: beginner
1810e6b6b59SJacob Faibussowitsch 
1820e6b6b59SJacob Faibussowitsch .N ASYNC_API
1830e6b6b59SJacob Faibussowitsch 
1840e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceFree()`, `PetscDeviceCalloc()`, `PetscDeviceArrayCopy()`,
185*6797ed33SJacob Faibussowitsch `PetscDeviceArrayZero()`
1860e6b6b59SJacob Faibussowitsch M*/
187*6797ed33SJacob Faibussowitsch #define PetscDeviceMalloc(dctx, mtype, n, ptr) PetscDeviceAllocate_Private((dctx), PETSC_FALSE, (mtype), (size_t)(n) * sizeof(**(ptr)), PETSC_DEVICE_ALIGNOF(**(ptr)), (void **)(ptr))
1880e6b6b59SJacob Faibussowitsch 
1890e6b6b59SJacob Faibussowitsch /*MC
1900e6b6b59SJacob Faibussowitsch   PetscDeviceCalloc - Allocate zeroed device-aware memory
1910e6b6b59SJacob Faibussowitsch 
1920e6b6b59SJacob Faibussowitsch   Synopsis:
1930e6b6b59SJacob Faibussowitsch   #include <petscdevice.h>
1940e6b6b59SJacob Faibussowitsch   PetscErrorCode PetscDeviceCalloc(PetscDeviceContext dctx, PetscMemType mtype, size_t n, Type **ptr)
1950e6b6b59SJacob Faibussowitsch 
1960e6b6b59SJacob Faibussowitsch   Not Collective, Asynchronous, Auto-dependency aware
1970e6b6b59SJacob Faibussowitsch 
1980e6b6b59SJacob Faibussowitsch   Input Parameters:
1990e6b6b59SJacob Faibussowitsch + dctx  - The `PetscDeviceContext` used to allocate the memory
2000e6b6b59SJacob Faibussowitsch . mtype - The type of memory to allocate
2010e6b6b59SJacob Faibussowitsch - n     - The amount (in elements) to allocate
2020e6b6b59SJacob Faibussowitsch 
2030e6b6b59SJacob Faibussowitsch   Output Parameter:
2040e6b6b59SJacob Faibussowitsch . ptr - The pointer to store the result in
2050e6b6b59SJacob Faibussowitsch 
2060e6b6b59SJacob Faibussowitsch   Notes:
2070e6b6b59SJacob Faibussowitsch   Has identical usage to `PetscDeviceMalloc()` except that the memory is zeroed before it is
2080e6b6b59SJacob Faibussowitsch   returned. See `PetscDeviceMalloc()` for further discussion.
2090e6b6b59SJacob Faibussowitsch 
2100e6b6b59SJacob Faibussowitsch   This routine falls back to using `PetscCalloc1()` if PETSc was not configured with device
2110e6b6b59SJacob Faibussowitsch   support. The user should note that `mtype` is ignored in this case, as `PetscCalloc1()`
2120e6b6b59SJacob Faibussowitsch   allocates only host memory.
2130e6b6b59SJacob Faibussowitsch 
2140e6b6b59SJacob Faibussowitsch   Level: beginner
2150e6b6b59SJacob Faibussowitsch 
2160e6b6b59SJacob Faibussowitsch .N ASYNC_API
2170e6b6b59SJacob Faibussowitsch 
2180e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceFree()`, `PetscDeviceMalloc()`, `PetscDeviceArrayCopy()`,
219*6797ed33SJacob Faibussowitsch `PetscDeviceArrayZero()`
2200e6b6b59SJacob Faibussowitsch M*/
221*6797ed33SJacob Faibussowitsch #define PetscDeviceCalloc(dctx, mtype, n, ptr) PetscDeviceAllocate_Private((dctx), PETSC_TRUE, (mtype), (size_t)(n) * sizeof(**(ptr)), PETSC_DEVICE_ALIGNOF(**(ptr)), (void **)(ptr))
2220e6b6b59SJacob Faibussowitsch 
2230e6b6b59SJacob Faibussowitsch /*MC
2240e6b6b59SJacob Faibussowitsch   PetscDeviceFree - Free device-aware memory
2250e6b6b59SJacob Faibussowitsch 
2260e6b6b59SJacob Faibussowitsch   Synopsis:
2270e6b6b59SJacob Faibussowitsch   #include <petscdevice.h>
2280e6b6b59SJacob Faibussowitsch   PetscErrorCode PetscDeviceFree(PetscDeviceContext dctx, void *ptr)
2290e6b6b59SJacob Faibussowitsch 
2300e6b6b59SJacob Faibussowitsch   Not Collective, Asynchronous, Auto-dependency aware
2310e6b6b59SJacob Faibussowitsch 
2320e6b6b59SJacob Faibussowitsch   Input Parameters:
2330e6b6b59SJacob Faibussowitsch + dctx - The `PetscDeviceContext` used to free the memory
2340e6b6b59SJacob Faibussowitsch - ptr  - The pointer to free
2350e6b6b59SJacob Faibussowitsch 
2360e6b6b59SJacob Faibussowitsch   Notes:
237*6797ed33SJacob Faibussowitsch   `ptr` may be `NULL`, and is set to `PETSC_NULLPTR` on successful deallocation.
2380e6b6b59SJacob Faibussowitsch 
239*6797ed33SJacob Faibussowitsch   `ptr` must have been allocated using `PetscDeviceMalloc()`, `PetscDeviceCalloc()`.
2400e6b6b59SJacob Faibussowitsch 
2410e6b6b59SJacob Faibussowitsch   This routine falls back to using `PetscFree()` if PETSc was not configured with device
2420e6b6b59SJacob Faibussowitsch   support. The user should note that `PetscFree()` frees only host memory.
2430e6b6b59SJacob Faibussowitsch 
244*6797ed33SJacob Faibussowitsch   DAG representation:
245*6797ed33SJacob Faibussowitsch .vb
246*6797ed33SJacob Faibussowitsch   time ->
247*6797ed33SJacob Faibussowitsch 
248*6797ed33SJacob Faibussowitsch   -> dctx -/- |= CALL =| - dctx ->
249*6797ed33SJacob Faibussowitsch   -> ptr -/
250*6797ed33SJacob Faibussowitsch .ve
2510e6b6b59SJacob Faibussowitsch 
2520e6b6b59SJacob Faibussowitsch   Level: beginner
2530e6b6b59SJacob Faibussowitsch 
2540e6b6b59SJacob Faibussowitsch .N ASYNC_API
2550e6b6b59SJacob Faibussowitsch 
256*6797ed33SJacob Faibussowitsch .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`
2570e6b6b59SJacob Faibussowitsch M*/
258*6797ed33SJacob Faibussowitsch #define PetscDeviceFree(dctx, ptr) (PetscDeviceDeallocate_Private((dctx), (ptr)) || ((ptr) = PETSC_NULLPTR, 0))
2590e6b6b59SJacob Faibussowitsch 
2600e6b6b59SJacob Faibussowitsch /*MC
2610e6b6b59SJacob Faibussowitsch   PetscDeviceArrayCopy - Copy memory in a device-aware manner
2620e6b6b59SJacob Faibussowitsch 
2630e6b6b59SJacob Faibussowitsch   Synopsis:
2640e6b6b59SJacob Faibussowitsch   #include <petscdevice.h>
2650e6b6b59SJacob Faibussowitsch   PetscErrorCode PetscDeviceArrayCopy(PetscDeviceContext dctx, void *PETSC_RESTRICT dest, const void *PETSC_RESTRICT src, size_t n, PetscDeviceCopyMode mode)
2660e6b6b59SJacob Faibussowitsch 
2670e6b6b59SJacob Faibussowitsch   Not Collective, Asynchronous, Auto-dependency aware
2680e6b6b59SJacob Faibussowitsch 
2690e6b6b59SJacob Faibussowitsch   Input Parameters:
2700e6b6b59SJacob Faibussowitsch + dctx - The `PetscDeviceContext` used to copy the memory
2710e6b6b59SJacob Faibussowitsch . dest - The pointer to copy to
2720e6b6b59SJacob Faibussowitsch . src  - The pointer to copy from
2730e6b6b59SJacob Faibussowitsch - n    - The amount (in elements) to copy
2740e6b6b59SJacob Faibussowitsch 
2750e6b6b59SJacob Faibussowitsch   Notes:
2760e6b6b59SJacob Faibussowitsch   Both `dest` and `src` must have been allocated using any of `PetscDeviceMalloc()`,
277*6797ed33SJacob Faibussowitsch   `PetscDeviceCalloc()`.
2780e6b6b59SJacob Faibussowitsch 
2790e6b6b59SJacob Faibussowitsch   This uses the `sizeof()` of the `src` memory type requested to determine the total memory to
2800e6b6b59SJacob Faibussowitsch   be copied, therefore you should not multiply the number of elements by the `sizeof()` the
2810e6b6b59SJacob Faibussowitsch   type\:
2820e6b6b59SJacob Faibussowitsch 
2830e6b6b59SJacob Faibussowitsch .vb
2840e6b6b59SJacob Faibussowitsch   PetscInt *to,*from;
2850e6b6b59SJacob Faibussowitsch 
2860e6b6b59SJacob Faibussowitsch   // correct
2870e6b6b59SJacob Faibussowitsch   PetscDeviceArrayCopy(dctx,to,from,n,PETSC_DEVICE_COPY_AUTO);
2880e6b6b59SJacob Faibussowitsch 
2890e6b6b59SJacob Faibussowitsch   // incorrect
2900e6b6b59SJacob Faibussowitsch   PetscDeviceArrayCopy(dctx,to,from,n*sizeof(*from),PETSC_DEVICE_COPY_AUTO);
2910e6b6b59SJacob Faibussowitsch .ve
2920e6b6b59SJacob Faibussowitsch 
2930e6b6b59SJacob Faibussowitsch   See `PetscDeviceMemcpy()` for further discussion.
2940e6b6b59SJacob Faibussowitsch 
2950e6b6b59SJacob Faibussowitsch   Level: beginner
2960e6b6b59SJacob Faibussowitsch 
2970e6b6b59SJacob Faibussowitsch .N ASYNC_API
2980e6b6b59SJacob Faibussowitsch 
299*6797ed33SJacob Faibussowitsch .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
300*6797ed33SJacob Faibussowitsch `PetscDeviceArrayZero()`, `PetscDeviceMemcpy()`
3010e6b6b59SJacob Faibussowitsch M*/
302*6797ed33SJacob Faibussowitsch #define PetscDeviceArrayCopy(dctx, dest, src, n) PetscDeviceMemcpy((dctx), (dest), (src), (size_t)(n) * sizeof(*(src)))
3030e6b6b59SJacob Faibussowitsch 
3040e6b6b59SJacob Faibussowitsch /*MC
3050e6b6b59SJacob Faibussowitsch   PetscDeviceArrayZero - Zero memory in a device-aware manner
3060e6b6b59SJacob Faibussowitsch 
3070e6b6b59SJacob Faibussowitsch   Synopsis:
3080e6b6b59SJacob Faibussowitsch   #include <petscdevice.h>
3090e6b6b59SJacob Faibussowitsch   PetscErrorCode PetscDeviceArrayZero(PetscDeviceContext dctx, PetscMemType mtype, void *ptr, size_t n)
3100e6b6b59SJacob Faibussowitsch 
3110e6b6b59SJacob Faibussowitsch   Not Collective, Asynchronous, Auto-dependency aware
3120e6b6b59SJacob Faibussowitsch 
3130e6b6b59SJacob Faibussowitsch   Input Parameters:
3140e6b6b59SJacob Faibussowitsch + dctx  - The `PetscDeviceContext` used to zero the memory
3150e6b6b59SJacob Faibussowitsch . ptr   - The pointer to the memory
3160e6b6b59SJacob Faibussowitsch - n     - The amount (in elements) to zero
3170e6b6b59SJacob Faibussowitsch 
3180e6b6b59SJacob Faibussowitsch   Notes:
319*6797ed33SJacob Faibussowitsch   `ptr` must have been allocated using `PetscDeviceMalloc()` or `PetscDeviceCalloc()`.
3200e6b6b59SJacob Faibussowitsch 
3210e6b6b59SJacob Faibussowitsch   This uses the `sizeof()` of the memory type requested to determine the total memory to be
3220e6b6b59SJacob Faibussowitsch   zeroed, therefore you should not multiply the number of elements by the `sizeof()` the type\:
3230e6b6b59SJacob Faibussowitsch 
3240e6b6b59SJacob Faibussowitsch .vb
3250e6b6b59SJacob Faibussowitsch   PetscInt *ptr;
3260e6b6b59SJacob Faibussowitsch 
3270e6b6b59SJacob Faibussowitsch   // correct
3280e6b6b59SJacob Faibussowitsch   PetscDeviceArrayZero(dctx,PETSC_MEMTYPE_DEVICE,ptr,n);
3290e6b6b59SJacob Faibussowitsch 
3300e6b6b59SJacob Faibussowitsch   // incorrect
3310e6b6b59SJacob Faibussowitsch   PetscDeviceArrayZero(dctx,PETSC_MEMTYPE_DEVICE,ptr,n*sizeof(*ptr));
3320e6b6b59SJacob Faibussowitsch .ve
3330e6b6b59SJacob Faibussowitsch 
3340e6b6b59SJacob Faibussowitsch   See `PetscDeviceMemset()` for futher discussion.
3350e6b6b59SJacob Faibussowitsch 
3360e6b6b59SJacob Faibussowitsch   Level: beginner
3370e6b6b59SJacob Faibussowitsch 
3380e6b6b59SJacob Faibussowitsch .N ASYNC_API
3390e6b6b59SJacob Faibussowitsch 
340*6797ed33SJacob Faibussowitsch .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceFree()`,
341*6797ed33SJacob Faibussowitsch `PetscDeviceArrayCopy()`, `PetscDeviceMemset()`
3420e6b6b59SJacob Faibussowitsch M*/
343*6797ed33SJacob Faibussowitsch #define PetscDeviceArrayZero(dctx, ptr, n) PetscDeviceMemset((dctx), (ptr), 0, (size_t)(n) * sizeof(*(ptr)))
34498921bdaSJacob Faibussowitsch 
345030f984aSJacob Faibussowitsch #endif /* PETSCDEVICE_H */
346