xref: /petsc/include/petscdevice.h (revision cf906205f1df435953e2a75894dc7795d3ff0aed)
1 #ifndef PETSCDEVICE_H
2 #define PETSCDEVICE_H
3 
4 #include <petscdevicetypes.h>
5 #include <petscviewertypes.h>
6 
7 /* SUBMANSEC = Sys */
8 
9 // REVIEW ME: this should probably go somewhere better, configure-time?
10 #define PETSC_HAVE_HOST 1
11 
12 /* logging support */
13 PETSC_EXTERN PetscClassId PETSC_DEVICE_CLASSID;
14 PETSC_EXTERN PetscClassId PETSC_DEVICE_CONTEXT_CLASSID;
15 
16 PETSC_EXTERN PetscErrorCode PetscDeviceInitializePackage(void);
17 PETSC_EXTERN PetscErrorCode PetscDeviceFinalizePackage(void);
18 PETSC_EXTERN PetscErrorCode PetscGetMemType(const void *, PetscMemType *);
19 
20 /* PetscDevice */
21 #if PetscDefined(HAVE_CXX)
22 PETSC_EXTERN PetscErrorCode  PetscDeviceCreate(PetscDeviceType, PetscInt, PetscDevice *);
23 PETSC_EXTERN PetscErrorCode  PetscDeviceDestroy(PetscDevice *);
24 PETSC_EXTERN PetscErrorCode  PetscDeviceConfigure(PetscDevice);
25 PETSC_EXTERN PetscErrorCode  PetscDeviceView(PetscDevice, PetscViewer);
26 PETSC_EXTERN PetscErrorCode  PetscDeviceGetType(PetscDevice, PetscDeviceType *);
27 PETSC_EXTERN PetscErrorCode  PetscDeviceGetDeviceId(PetscDevice, PetscInt *);
28 PETSC_EXTERN PetscDeviceType PETSC_DEVICE_DEFAULT(void);
29 PETSC_EXTERN PetscErrorCode  PetscDeviceSetDefaultDeviceType(PetscDeviceType);
30 PETSC_EXTERN PetscErrorCode  PetscDeviceInitialize(PetscDeviceType);
31 PETSC_EXTERN PetscBool       PetscDeviceInitialized(PetscDeviceType);
32 #else
33 #define PetscDeviceCreate(PetscDeviceType, PetscInt, dev) (*(dev) = PETSC_NULLPTR, 0)
34 #define PetscDeviceDestroy(dev)                           (*(dev) = PETSC_NULLPTR, 0)
35 #define PetscDeviceConfigure(PetscDevice)                 0
36 #define PetscDeviceView(PetscDevice, PetscViewer)         0
37 #define PetscDeviceGetType(PetscDevice, type)             (*(type) = PETSC_DEVICE_DEFAULT(), 0)
38 #define PetscDeviceGetDeviceId(PetscDevice, id)           (*(id) = 0)
39 #define PETSC_DEVICE_DEFAULT()                            PETSC_DEVICE_HOST
40 #define PetscDeviceSetDefaultDeviceType(PetscDeviceType)  0
41 #define PetscDeviceInitialize(PetscDeviceType)            0
42 #define PetscDeviceInitialized(dtype)                     ((dtype) == PETSC_DEVICE_HOST)
43 #endif /* PetscDefined(HAVE_CXX) */
44 
45 /* PetscDeviceContext */
46 #if PetscDefined(HAVE_CXX)
47 PETSC_EXTERN PetscErrorCode PetscDeviceContextCreate(PetscDeviceContext *);
48 PETSC_EXTERN PetscErrorCode PetscDeviceContextDestroy(PetscDeviceContext *);
49 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType);
50 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetStreamType(PetscDeviceContext, PetscStreamType *);
51 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice);
52 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDevice(PetscDeviceContext, PetscDevice *);
53 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDeviceType(PetscDeviceContext, PetscDeviceType *);
54 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetUp(PetscDeviceContext);
55 PETSC_EXTERN PetscErrorCode PetscDeviceContextDuplicate(PetscDeviceContext, PetscDeviceContext *);
56 PETSC_EXTERN PetscErrorCode PetscDeviceContextQueryIdle(PetscDeviceContext, PetscBool *);
57 PETSC_EXTERN PetscErrorCode PetscDeviceContextWaitForContext(PetscDeviceContext, PetscDeviceContext);
58 PETSC_EXTERN PetscErrorCode PetscDeviceContextForkWithStreamType(PetscDeviceContext, PetscStreamType, PetscInt, PetscDeviceContext **);
59 PETSC_EXTERN PetscErrorCode PetscDeviceContextFork(PetscDeviceContext, PetscInt, PetscDeviceContext **);
60 PETSC_EXTERN PetscErrorCode PetscDeviceContextJoin(PetscDeviceContext, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContext **);
61 PETSC_EXTERN PetscErrorCode PetscDeviceContextSynchronize(PetscDeviceContext);
62 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext);
63 PETSC_EXTERN PetscErrorCode PetscDeviceContextView(PetscDeviceContext, PetscViewer);
64 PETSC_EXTERN PetscErrorCode PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, PetscViewer);
65 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetCurrentContext(PetscDeviceContext *);
66 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetCurrentContext(PetscDeviceContext);
67 #else
68 #define PetscDeviceContextCreate(dctx)                                                                            (*(dctx) = PETSC_NULLPTR, 0)
69 #define PetscDeviceContextDestroy(dctx)                                                                           (*(dctx) = PETSC_NULLPTR, 0)
70 #define PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType)                                      0
71 #define PetscDeviceContextGetStreamType(PetscDeviceContext, type)                                                 (*(type) = PETSC_STREAM_GLOBAL_BLOCKING, 0)
72 #define PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice)                                              0
73 #define PetscDeviceContextGetDevice(PetscDeviceContext, device)                                                   (*(device) = PETSC_NULLPTR, 0)
74 #define PetscDeviceContextGetDeviceType(PetscDeviceContext, type)                                                 (*(type) = PETSC_DEVICE_DEFAULT())
75 #define PetscDeviceContextSetUp(PetscDeviceContext)                                                               0
76 #define PetscDeviceContextDuplicate(PetscDeviceContextl, PetscDeviceContextr)                                     (*(PetscDeviceContextr) = PETSC_NULLPTR, 0)
77 #define PetscDeviceContextQueryIdle(PetscDeviceContext, idle)                                                     (*(idle) = PETSC_TRUE, 0)
78 #define PetscDeviceContextWaitForContext(PetscDeviceContextl, PetscDeviceContextr)                                0
79 #define PetscDeviceContextForkWithStreamType(PetscDeviceContextp, PetscStreamType, PetscInt, PetscDeviceContextc) (*(PetscDeviceContextc) = PETSC_NULLPTR, 0)
80 #define PetscDeviceContextFork(PetscDeviceContextp, PetscInt, PetscDeviceContextc)                                (*(PetscDeviceContextc) = PETSC_NULLPTR, 0)
81 #define PetscDeviceContextJoin(PetscDeviceContextp, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContextc)    (*(PetscDeviceContextc) = PETSC_NULLPTR, 0)
82 #define PetscDeviceContextSynchronize(PetscDeviceContext)                                                         0
83 #define PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext)                                            0
84 #define PetscDeviceContextView(PetscDeviceContext, PetscViewer)                                                   0
85 #define PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, PetscViewer)                           0
86 #define PetscDeviceContextGetCurrentContext(dctx)                                                                 (*(dctx) = PETSC_NULLPTR, 0)
87 #define PetscDeviceContextSetCurrentContext(PetscDeviceContext)                                                   0
88 #endif /* PetscDefined(HAVE_CXX) */
89 
90 /* memory */
91 #if PetscDefined(HAVE_CXX)
92 PETSC_EXTERN PetscErrorCode PetscDeviceAllocate(PetscDeviceContext, PetscBool, PetscMemType, size_t, void **PETSC_RESTRICT);
93 PETSC_EXTERN PetscErrorCode PetscDeviceDeallocate(PetscDeviceContext, void *PETSC_RESTRICT);
94 PETSC_EXTERN PetscErrorCode PetscDeviceMemcpy(PetscDeviceContext, void *PETSC_RESTRICT, const void *PETSC_RESTRICT, size_t);
95 PETSC_EXTERN PetscErrorCode PetscDeviceMemset(PetscDeviceContext, void *PETSC_RESTRICT, PetscInt, size_t);
96 #else
97 #include <string.h> // memset()
98 #define PetscDeviceAllocate(PetscDeviceContext, clear, PetscMemType, size, ptr) PetscMallocA(1, (clear), __LINE__, PETSC_FUNCTION_NAME, __FILE__, (size), (ptr))
99 #define PetscDeviceDeallocate(PetscDeviceContext, ptr)                          PetscFree((ptr))
100 #define PetscDeviceMemcpy(PetscDeviceContext, dest, src, size)                  PetscMemcpy((dest), (src), (size))
101 #define PetscDeviceMemset(PetscDeviceContext, ptr, v, size)                     ((void)memset((ptr), (unsigned char)(v), (size)), 0)
102 #endif /* PetscDefined(HAVE_CXX) */
103 
104 /*MC
105   PetscDeviceMalloc - Allocate device-aware memory
106 
107   Synopsis:
108   #include <petscdevice.h>
109   PetscErrorCode PetscDeviceMalloc(PetscDeviceContext dctx, PetscMemType mtype, size_t n, Type **ptr)
110 
111   Not Collective, Asynchronous, Auto-dependency aware
112 
113   Input Parameters:
114 + dctx  - The `PetscDeviceContext` used to allocate the memory
115 . mtype - The type of memory to allocate
116 - n     - The amount (in elements) to allocate
117 
118   Output Parameter:
119 . ptr - The pointer to store the result in
120 
121   Notes:
122   See `PetscDeviceAllocate()` for more detailed discussion on usage and async semantics.
123 
124   This uses the `sizeof()` of the memory type requested to determine the total memory to be
125   allocated, therefore you should not multiply the number of elements requested by the
126   `sizeof()` the type\:
127 
128 .vb
129   PetscInt *arr;
130 
131   // correct
132   PetscDeviceMalloc(dctx,PETSC_MEMTYPE_DEVICE,n,&arr);
133 
134   // incorrect
135   PetscDeviceMalloc(dctx,PETSC_MEMTYPE_DEVICE,n*sizeof(*arr),&arr);
136 .ve
137 
138   This routine falls back to using `PetscMalloc1()` (which is fully synchronous) if PETSc was
139   not configured with device support. The user should note that `mtype` is ignored in this
140   case, as `PetscMalloc1()` allocates only host memory.
141 
142   Level: beginner
143 
144 .N ASYNC_API
145 
146 .seealso: `PetscDeviceFree()`, `PetscDeviceCalloc()`, `PetscDeviceArrayCopy()`,
147 `PetscDeviceArrayZero()`, `PetscDeviceAllocate()`, `PetscDeviceDeallocate()`
148 M*/
149 #define PetscDeviceMalloc(dctx, mtype, n, ptr) (PetscDefined(HAVE_DEVICE) ? PetscDeviceAllocate((dctx), PETSC_FALSE, (mtype), (size_t)(n) * sizeof(**(ptr)), (void **)(ptr)) : PetscMalloc1((n), (ptr)))
150 
151 /*MC
152   PetscDeviceCalloc - Allocate zeroed device-aware memory
153 
154   Synopsis:
155   #include <petscdevice.h>
156   PetscErrorCode PetscDeviceCalloc(PetscDeviceContext dctx, PetscMemType mtype, size_t n, Type **ptr)
157 
158   Not Collective, Asynchronous, Auto-dependency aware
159 
160   Input Parameters:
161 + dctx  - The `PetscDeviceContext` used to allocate the memory
162 . mtype - The type of memory to allocate
163 - n     - The amount (in elements) to allocate
164 
165   Output Parameter:
166 . ptr - The pointer to store the result in
167 
168   Notes:
169   Has identical usage to `PetscDeviceMalloc()` except that the memory is zeroed before it is
170   returned. See `PetscDeviceMalloc()` for further discussion.
171 
172   This routine falls back to using `PetscCalloc1()` if PETSc was not configured with device
173   support. The user should note that `mtype` is ignored in this case, as `PetscCalloc1()`
174   allocates only host memory.
175 
176   Level: beginner
177 
178 .N ASYNC_API
179 
180 .seealso: `PetscDeviceFree()`, `PetscDeviceMalloc()`, `PetscDeviceArrayCopy()`,
181 `PetscDeviceArrayZero()`, `PetscDeviceAllocate()`, `PetscDeviceDeallocate()`
182 M*/
183 #define PetscDeviceCalloc(dctx, mtype, n, ptr) (PetscDefined(HAVE_DEVICE) ? PetscDeviceAllocate((dctx), PETSC_TRUE, (mtype), (size_t)(n) * sizeof(**(ptr)), (void **)(ptr)) : PetscCalloc1((n), (ptr)))
184 
185 /*MC
186   PetscDeviceFree - Free device-aware memory
187 
188   Synopsis:
189   #include <petscdevice.h>
190   PetscErrorCode PetscDeviceFree(PetscDeviceContext dctx, void *ptr)
191 
192   Not Collective, Asynchronous, Auto-dependency aware
193 
194   Input Parameters:
195 + dctx - The `PetscDeviceContext` used to free the memory
196 - ptr  - The pointer to free
197 
198   Notes:
199   `ptr` must have been allocated using `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, or
200   `PetscDeviceAllocate()`, or registered with the system using `PetscRegisterMemory()`.
201 
202   Automatically sets `ptr` to `PETSC_NULLPTR` on successful deallocation.
203 
204   This routine falls back to using `PetscFree()` if PETSc was not configured with device
205   support. The user should note that `PetscFree()` frees only host memory.
206 
207   See `PetscDeviceDeallocate()` for more further discussion.
208 
209   Level: beginner
210 
211 .N ASYNC_API
212 
213 .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceDeallocate()`
214 M*/
215 #define PetscDeviceFree(dctx, ptr) ((ptr) ? (PetscDefined(HAVE_DEVICE) ? (PetscDeviceDeallocate((dctx), (ptr)) || ((ptr) = PETSC_NULLPTR, 0)) : PetscFree(ptr)) : 0)
216 
217 /*MC
218   PetscDeviceArrayCopy - Copy memory in a device-aware manner
219 
220   Synopsis:
221   #include <petscdevice.h>
222   PetscErrorCode PetscDeviceArrayCopy(PetscDeviceContext dctx, void *PETSC_RESTRICT dest, const void *PETSC_RESTRICT src, size_t n, PetscDeviceCopyMode mode)
223 
224   Not Collective, Asynchronous, Auto-dependency aware
225 
226   Input Parameters:
227 + dctx - The `PetscDeviceContext` used to copy the memory
228 . dest - The pointer to copy to
229 . src  - The pointer to copy from
230 - n    - The amount (in elements) to copy
231 
232   Notes:
233   Both `dest` and `src` must have been allocated using any of `PetscDeviceMalloc()`,
234   `PetscDeviceCalloc()` or `PetscDeviceAllocate()`, or registered with the system via
235   `PetscDeviceRegisterMemory()`.
236 
237   This uses the `sizeof()` of the `src` memory type requested to determine the total memory to
238   be copied, therefore you should not multiply the number of elements by the `sizeof()` the
239   type\:
240 
241 .vb
242   PetscInt *to,*from;
243 
244   // correct
245   PetscDeviceArrayCopy(dctx,to,from,n,PETSC_DEVICE_COPY_AUTO);
246 
247   // incorrect
248   PetscDeviceArrayCopy(dctx,to,from,n*sizeof(*from),PETSC_DEVICE_COPY_AUTO);
249 .ve
250 
251   See `PetscDeviceMemcpy()` for further discussion.
252 
253   Level: beginner
254 
255 .N ASYNC_API
256 
257 .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceRegisterMemory()`,
258 `PetscDeviceFree()`, `PetscDeviceArrayZero()`, `PetscDeviceMemcpy()`
259 M*/
260 #define PetscDeviceArrayCopy(dctx, dest, src, n) ((n) ? (PetscDefined(HAVE_DEVICE) ? PetscDeviceMemcpy((dctx), (dest), (src), (size_t)(n) * sizeof(*(src))) : PetscArraycpy((dest), (src), (n))) : 0)
261 
262 /*MC
263   PetscDeviceArrayZero - Zero memory in a device-aware manner
264 
265   Synopsis:
266   #include <petscdevice.h>
267   PetscErrorCode PetscDeviceArrayZero(PetscDeviceContext dctx, PetscMemType mtype, void *ptr, size_t n)
268 
269   Not Collective, Asynchronous, Auto-dependency aware
270 
271   Input Parameters:
272 + dctx  - The `PetscDeviceContext` used to zero the memory
273 . ptr   - The pointer to the memory
274 - n     - The amount (in elements) to zero
275 
276   Notes:
277   `ptr` must have been allocated using any of `PetscDeviceMalloc()`, `PetscDeviceCalloc()` or
278   `PetscDeviceAllocate()`, or registered with the system via `PetscDeviceRegisterMemory()`.
279 
280   This uses the `sizeof()` of the memory type requested to determine the total memory to be
281   zeroed, therefore you should not multiply the number of elements by the `sizeof()` the type\:
282 
283 .vb
284   PetscInt *ptr;
285 
286   // correct
287   PetscDeviceArrayZero(dctx,PETSC_MEMTYPE_DEVICE,ptr,n);
288 
289   // incorrect
290   PetscDeviceArrayZero(dctx,PETSC_MEMTYPE_DEVICE,ptr,n*sizeof(*ptr));
291 .ve
292 
293   See `PetscDeviceMemset()` for futher discussion.
294 
295   Level: beginner
296 
297 .N ASYNC_API
298 
299 .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceRegisterMemory()`,
300 `PetscDeviceFree()`, `PetscDeviceArrayCopy()`, `PetscDeviceMemset()`
301 M*/
302 #define PetscDeviceArrayZero(dctx, ptr, n) ((n) ? (PetscDefined(HAVE_DEVICE) ? PetscDeviceMemset((dctx), (ptr), 0, (size_t)(n) * sizeof(*(ptr))) : PetscArrayzero((ptr), (n))) : 0)
303 
304 #endif /* PETSCDEVICE_H */
305