Actual source code: deviceimpl.h
1: #pragma once
3: #include <petscdevice.h>
4: #include <petsc/private/petscimpl.h>
6: #if defined(PETSC_HAVE_CUPM)
7: PETSC_INTERN int PetscDeviceCUPMRuntimeArch; // The real CUDA/HIP arch the code is run with. For log view and error diagnosis
8: #endif
10: /* logging support */
11: PETSC_INTERN PetscLogEvent CUBLAS_HANDLE_CREATE;
12: PETSC_INTERN PetscLogEvent CUSOLVER_HANDLE_CREATE;
13: PETSC_INTERN PetscLogEvent HIPSOLVER_HANDLE_CREATE;
14: PETSC_INTERN PetscLogEvent HIPBLAS_HANDLE_CREATE;
16: PETSC_INTERN PetscLogEvent DCONTEXT_Create;
17: PETSC_INTERN PetscLogEvent DCONTEXT_Destroy;
18: PETSC_INTERN PetscLogEvent DCONTEXT_ChangeStream;
19: PETSC_INTERN PetscLogEvent DCONTEXT_SetDevice;
20: PETSC_INTERN PetscLogEvent DCONTEXT_SetUp;
21: PETSC_INTERN PetscLogEvent DCONTEXT_Duplicate;
22: PETSC_INTERN PetscLogEvent DCONTEXT_QueryIdle;
23: PETSC_INTERN PetscLogEvent DCONTEXT_WaitForCtx;
24: PETSC_INTERN PetscLogEvent DCONTEXT_Fork;
25: PETSC_INTERN PetscLogEvent DCONTEXT_Join;
26: PETSC_INTERN PetscLogEvent DCONTEXT_Sync;
27: PETSC_INTERN PetscLogEvent DCONTEXT_Mark;
29: /* type cast macros for some additional type-safety in C++ land */
30: #if defined(__cplusplus)
31: #define PetscStreamTypeCast(...) static_cast<PetscStreamType>(__VA_ARGS__)
32: #define PetscDeviceTypeCast(...) static_cast<PetscDeviceType>(__VA_ARGS__)
33: #define PetscDeviceInitTypeCast(...) static_cast<PetscDeviceInitType>(__VA_ARGS__)
34: #else
35: #define PetscStreamTypeCast(...) ((PetscStreamType)(__VA_ARGS__))
36: #define PetscDeviceTypeCast(...) ((PetscDeviceType)(__VA_ARGS__))
37: #define PetscDeviceInitTypeCast(...) ((PetscDeviceInitType)(__VA_ARGS__))
38: #endif
40: #if defined(PETSC_CLANG_STATIC_ANALYZER)
41: template <typename T>
43: template <typename T, typename U>
44: extern void PetscCheckCompatibleDeviceTypes(T, int, U, int);
45: template <typename T>
47: template <typename T>
49: template <typename T, typename U>
50: extern void PetscCheckCompatibleDevices(T, int, U, int);
51: template <typename T>
53: template <typename T>
55: template <typename T, typename U>
56: extern void PetscCheckCompatibleDeviceContexts(T, int, U, int);
57: #elif PetscDefined(HAVE_CXX) && (PetscDefined(USE_DEBUG) || PetscDefined(DEVICE_KEEP_ERROR_CHECKING_MACROS))
59: do { \
60: PetscDeviceType pvdt_dtype_ = PetscDeviceTypeCast(dtype); \
61: int pvdt_argno_ = (int)(argno); \
62: PetscCheck(((int)pvdt_dtype_ >= (int)PETSC_DEVICE_HOST) && ((int)pvdt_dtype_ <= (int)PETSC_DEVICE_MAX), PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDeviceType '%d': Argument #%d", pvdt_dtype_, pvdt_argno_); \
63: if (PetscUnlikely(!PetscDeviceConfiguredFor_Internal(pvdt_dtype_))) { \
64: PetscCheck((int)pvdt_dtype_ != (int)PETSC_DEVICE_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Invalid PetscDeviceType '%s': Argument #%d", PetscDeviceTypes[pvdt_dtype_], pvdt_argno_); \
65: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, \
66: "Not configured for PetscDeviceType '%s': Argument #%d;" \
67: " run configure --help %s for available options", \
68: PetscDeviceTypes[pvdt_dtype_], pvdt_argno_, PetscDeviceTypes[pvdt_dtype_]); \
69: } \
70: } while (0)
72: #define PetscCheckCompatibleDeviceTypes(dtype1, argno1, dtype2, argno2) \
73: do { \
74: PetscDeviceType pccdt_dtype1_ = PetscDeviceTypeCast(dtype1); \
75: PetscDeviceType pccdt_dtype2_ = PetscDeviceTypeCast(dtype2); \
78: PetscCheck(pccdt_dtype1_ == pccdt_dtype2_, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMETYPE, "PetscDeviceTypes are incompatible: Arguments #%d and #%d. Expected PetscDeviceType '%s' but have '%s' instead", argno1, argno2, PetscDeviceTypes[pccdt_dtype1_], PetscDeviceTypes[pccdt_dtype2_]); \
79: } while (0)
82: do { \
83: PetscDevice pvd_dev_ = dev; \
84: int pvd_argno_ = (int)(argno); \
85: PetscAssertPointer(pvd_dev_, pvd_argno_); \
87: PetscCheck(pvd_dev_->id >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid PetscDevice: Argument #%d; id %" PetscInt_FMT " < 0", pvd_argno_, pvd_dev_->id); \
88: PetscCheck(pvd_dev_->refcnt >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid PetscDevice: Argument #%d; negative reference count %" PetscInt_FMT, pvd_argno_, pvd_dev_->refcnt); \
89: } while (0)
92: do { \
93: PetscDeviceAttribute pvda_attr_ = (dattr); \
94: int pvda_argno_ = (int)(argno); \
95: PetscCheck((((int)pvda_attr_) >= 0) && (pvda_attr_ <= PETSC_DEVICE_ATTR_MAX), PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDeviceAttribute '%d': Argument #%d", (int)pvda_attr_, pvda_argno_); \
96: PetscCheck(pvda_attr_ != PETSC_DEVICE_ATTR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Invalid PetscDeviceAttribute '%s': Argument #%d", PetscDeviceAttributes[pvda_attr_], pvda_argno_); \
97: } while (0)
99: /*
100: for now just checks strict equality, but this can be changed as some devices (i.e. kokkos and
101: any cupm should be compatible once implemented)
102: */
103: #define PetscCheckCompatibleDevices(dev1, argno1, dev2, argno2) \
104: do { \
105: PetscDevice pccd_dev1_ = (dev1), pccd_dev2_ = (dev2); \
106: int pccd_argno1_ = (int)(argno1), pccd_argno2_ = (int)(argno2); \
109: PetscCheckCompatibleDeviceTypes(pccd_dev1_->type, pccd_argno1_, pccd_dev2_->type, pccd_argno2_); \
110: } while (0)
113: do { \
114: PetscStreamType pvst_stype_ = PetscStreamTypeCast(stype); \
115: int pvst_argno_ = (int)(argno); \
116: PetscCheck(((int)pvst_stype_ >= 0) && ((int)pvst_stype_ <= (int)PETSC_STREAM_MAX), PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscStreamType '%d': Argument #%d", pvst_stype_, pvst_argno_); \
117: PetscCheck((int)pvst_stype_ != (int)PETSC_STREAM_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Invalid PetscStreamType '%s': Argument #%d", PetscStreamTypes[pvst_stype_], pvst_argno_); \
118: } while (0)
121: do { \
122: PetscDeviceContext pvdc_dctx_ = dctx; \
123: int pvdc_argno_ = (int)(argno); \
126: if (pvdc_dctx_->device) { \
128: } else { \
129: PetscCheck(!pvdc_dctx_->setup, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, \
130: "Invalid PetscDeviceContext: Argument #%d; " \
131: "PetscDeviceContext is setup but has no PetscDevice", \
132: pvdc_argno_); \
133: } \
134: PetscCheck(((PetscObject)pvdc_dctx_)->id >= 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid PetscDeviceContext: Argument #%d; id %" PetscInt64_FMT " < 1", pvdc_argno_, ((PetscObject)pvdc_dctx_)->id); \
135: PetscCheck(pvdc_dctx_->numChildren <= pvdc_dctx_->maxNumChildren, PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "Invalid PetscDeviceContext: Argument #%d; number of children %" PetscInt_FMT " > max number of children %" PetscInt_FMT, pvdc_argno_, \
136: pvdc_dctx_->numChildren, pvdc_dctx_->maxNumChildren); \
137: } while (0)
139: #define PetscCheckCompatibleDeviceContexts(dctx1, argno1, dctx2, argno2) \
140: do { \
141: PetscDeviceContext pccdc_dctx1_ = (dctx1), pccdc_dctx2_ = (dctx2); \
142: int pccdc_argno1_ = (int)(argno1), pccdc_argno2_ = (int)(argno2); \
145: if (pccdc_dctx1_->device && pccdc_dctx2_->device) PetscCheckCompatibleDevices(pccdc_dctx1_->device, pccdc_argno1_, pccdc_dctx2_->device, pccdc_argno2_); \
146: } while (0)
147: #else /* PetscDefined(USE_DEBUG) */
149: #define PetscCheckCompatibleDeviceTypes(dtype1, argno1, dtype2, argno2)
152: #define PetscCheckCompatibleDevices(dev1, argno1, dev2, argno2)
155: #define PetscCheckCompatibleDeviceContexts(dctx1, argno1, dctx2, argno2)
156: #endif /* PetscDefined(USE_DEBUG) */
158: /* if someone is ready to rock with more than 128 GPUs on hand then we're in real trouble */
159: #define PETSC_DEVICE_MAX_DEVICES 128
161: /*
162: the configure-time default device type, used as the initial the value of
163: PETSC_DEVICE_DEFAULT() as well as what it is restored to during PetscFinalize()
164: */
165: #if PetscDefined(HAVE_HIP)
166: #define PETSC_DEVICE_HARDWARE_DEFAULT_TYPE PETSC_DEVICE_HIP
167: #elif PetscDefined(HAVE_CUDA)
168: #define PETSC_DEVICE_HARDWARE_DEFAULT_TYPE PETSC_DEVICE_CUDA
169: #elif PetscDefined(HAVE_SYCL)
170: #define PETSC_DEVICE_HARDWARE_DEFAULT_TYPE PETSC_DEVICE_SYCL
171: #else
172: #define PETSC_DEVICE_HARDWARE_DEFAULT_TYPE PETSC_DEVICE_HOST
173: #endif
175: #define PETSC_DEVICE_CONTEXT_DEFAULT_DEVICE_TYPE PETSC_DEVICE_HARDWARE_DEFAULT_TYPE
176: // REMOVE ME (change)
177: #define PETSC_DEVICE_CONTEXT_DEFAULT_STREAM_TYPE PETSC_STREAM_DEFAULT
179: typedef struct _DeviceOps *DeviceOps;
180: struct _DeviceOps {
181: /* the creation routine for the corresponding PetscDeviceContext, this is NOT intended
182: * to be called by the PetscDevice itself */
183: PetscErrorCode (*createcontext)(PetscDeviceContext);
184: PetscErrorCode (*configure)(PetscDevice);
185: PetscErrorCode (*view)(PetscDevice, PetscViewer);
186: PetscErrorCode (*getattribute)(PetscDevice, PetscDeviceAttribute, void *);
187: };
189: struct _n_PetscDevice {
190: struct _DeviceOps ops[1];
191: void *data; /* placeholder */
192: PetscInt refcnt; /* reference count for the device */
193: PetscInt id; /* unique id per created PetscDevice */
194: PetscInt deviceId; /* the id of the underlying device, i.e. the return of
195: * cudaGetDevice() for example */
196: PetscDeviceType type; /* type of device */
197: };
199: typedef struct _n_PetscEvent *PetscEvent;
200: struct _n_PetscEvent {
201: PetscDeviceType dtype; // this cannot change for the lifetime of the event
202: PetscObjectId dctx_id; // id of last dctx to record this event
203: PetscObjectState dctx_state; // state of last dctx to record this event
204: void *data; // event handle
205: PetscErrorCode (*destroy)(PetscEvent);
206: };
208: typedef struct _DeviceContextOps *DeviceContextOps;
209: struct _DeviceContextOps {
210: PetscErrorCode (*destroy)(PetscDeviceContext);
211: PetscErrorCode (*changestreamtype)(PetscDeviceContext, PetscStreamType);
212: PetscErrorCode (*setup)(PetscDeviceContext);
213: PetscErrorCode (*query)(PetscDeviceContext, PetscBool *);
214: PetscErrorCode (*waitforcontext)(PetscDeviceContext, PetscDeviceContext);
215: PetscErrorCode (*synchronize)(PetscDeviceContext);
216: PetscErrorCode (*getblashandle)(PetscDeviceContext, void *);
217: PetscErrorCode (*getsolverhandle)(PetscDeviceContext, void *);
218: PetscErrorCode (*getstreamhandle)(PetscDeviceContext, void **);
219: PetscErrorCode (*begintimer)(PetscDeviceContext);
220: PetscErrorCode (*endtimer)(PetscDeviceContext, PetscLogDouble *);
221: PetscErrorCode (*memalloc)(PetscDeviceContext, PetscBool, PetscMemType, size_t, size_t, void **); // optional
222: PetscErrorCode (*memfree)(PetscDeviceContext, PetscMemType, void **); // optional
223: PetscErrorCode (*memcopy)(PetscDeviceContext, void *PETSC_RESTRICT, const void *PETSC_RESTRICT, size_t, PetscDeviceCopyMode); // optional
224: PetscErrorCode (*memset)(PetscDeviceContext, PetscMemType, void *, PetscInt, size_t); // optional
225: PetscErrorCode (*createevent)(PetscDeviceContext, PetscEvent); // optional
226: PetscErrorCode (*recordevent)(PetscDeviceContext, PetscEvent); // optional
227: PetscErrorCode (*waitforevent)(PetscDeviceContext, PetscEvent); // optional
228: };
230: struct _p_PetscDeviceContext {
231: PETSCHEADER(struct _DeviceContextOps);
232: PetscDevice device; /* the device this context stems from */
233: void *data; /* solver contexts, event, stream */
234: PetscObjectId *childIDs; /* array containing ids of contexts currently forked from this one */
235: PetscInt numChildren; /* how many children does this context expect to destroy */
236: PetscInt maxNumChildren; /* how many children can this context have room for without realloc'ing */
237: PetscStreamType streamType; /* how should this contexts stream behave around other streams? */
238: PetscBool setup;
239: PetscBool usersetdevice;
240: };
242: // ===================================================================================
243: // PetscDevice Internal Functions
244: // ===================================================================================
245: #if PetscDefined(HAVE_CXX)
246: PETSC_INTERN PetscErrorCode PetscDeviceInitializeFromOptions_Internal(MPI_Comm);
247: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscDeviceGetDefaultForType_Internal(PetscDeviceType, PetscDevice *);
249: static inline PetscErrorCode PetscDeviceReference_Internal(PetscDevice device)
250: {
251: PetscFunctionBegin;
252: ++(device->refcnt);
253: PetscFunctionReturn(PETSC_SUCCESS);
254: }
256: static inline PetscErrorCode PetscDeviceDereference_Internal(PetscDevice device)
257: {
258: PetscFunctionBegin;
259: --(device->refcnt);
260: PetscAssert(device->refcnt >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "PetscDevice has negative reference count %" PetscInt_FMT, device->refcnt);
261: PetscFunctionReturn(PETSC_SUCCESS);
262: }
263: #else /* PETSC_HAVE_CXX for PetscDevice Internal Functions */
264: #define PetscDeviceInitializeFromOptions_Internal(comm) PETSC_SUCCESS
265: #define PetscDeviceGetDefaultForType_Internal(Type, device) (*(device) = PETSC_NULLPTR, PETSC_SUCCESS)
266: #define PetscDeviceReference_Internal(device) PETSC_SUCCESS
267: #define PetscDeviceDereference_Internal(device) PETSC_SUCCESS
268: #endif /* PETSC_HAVE_CXX for PetscDevice Internal Functions */
270: static inline PetscErrorCode PetscDeviceCheckDeviceCount_Internal(PetscInt count)
271: {
272: PetscFunctionBegin;
273: PetscAssert(count < PETSC_DEVICE_MAX_DEVICES, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Detected %" PetscInt_FMT " devices, which is larger than maximum supported number of devices %d", count, PETSC_DEVICE_MAX_DEVICES);
274: PetscFunctionReturn(PETSC_SUCCESS);
275: }
277: /* More general form of PetscDeviceDefaultType_Internal(), as it calls the former using
278: * the automatically selected default PetscDeviceType */
279: #define PetscDeviceGetDefault_Internal(device) PetscDeviceGetDefaultForType_Internal(PETSC_DEVICE_DEFAULT(), device)
281: static inline PETSC_CONSTEXPR_14 PetscBool PetscDeviceConfiguredFor_Internal(PetscDeviceType type)
282: {
283: switch (type) {
284: case PETSC_DEVICE_HOST:
285: return PETSC_TRUE;
286: /* casts are needed in C++ */
287: case PETSC_DEVICE_CUDA:
288: return (PetscBool)PetscDefined(HAVE_CUDA);
289: case PETSC_DEVICE_HIP:
290: return (PetscBool)PetscDefined(HAVE_HIP);
291: case PETSC_DEVICE_SYCL:
292: return (PetscBool)PetscDefined(HAVE_SYCL);
293: case PETSC_DEVICE_MAX:
294: return PETSC_FALSE;
295: /* Do not add default case! Will make compiler warn on new additions to PetscDeviceType! */
296: }
297: PetscUnreachable();
298: return PETSC_FALSE;
299: }
301: // ===================================================================================
302: // PetscDeviceContext Internal Functions
303: // ===================================================================================
304: #if PetscDefined(HAVE_CXX)
305: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscDeviceContextGetNullContext_Internal(PetscDeviceContext *);
307: static inline PetscErrorCode PetscDeviceContextGetBLASHandle_Internal(PetscDeviceContext dctx, void *handle)
308: {
309: PetscFunctionBegin;
310: /* we do error checking here as this routine is an entry-point */
312: PetscUseTypeMethod(dctx, getblashandle, handle);
313: PetscFunctionReturn(PETSC_SUCCESS);
314: }
316: static inline PetscErrorCode PetscDeviceContextGetSOLVERHandle_Internal(PetscDeviceContext dctx, void *handle)
317: {
318: PetscFunctionBegin;
319: /* we do error checking here as this routine is an entry-point */
321: PetscUseTypeMethod(dctx, getsolverhandle, handle);
322: PetscFunctionReturn(PETSC_SUCCESS);
323: }
325: static inline PetscErrorCode PetscDeviceContextGetStreamHandle_Internal(PetscDeviceContext dctx, void **handle)
326: {
327: PetscFunctionBegin;
328: /* we do error checking here as this routine is an entry-point */
330: PetscAssertPointer(handle, 2);
331: PetscUseTypeMethod(dctx, getstreamhandle, handle);
332: PetscFunctionReturn(PETSC_SUCCESS);
333: }
335: static inline PetscErrorCode PetscDeviceContextBeginTimer_Internal(PetscDeviceContext dctx)
336: {
337: PetscFunctionBegin;
338: /* we do error checking here as this routine is an entry-point */
340: PetscUseTypeMethod(dctx, begintimer);
341: PetscFunctionReturn(PETSC_SUCCESS);
342: }
344: static inline PetscErrorCode PetscDeviceContextEndTimer_Internal(PetscDeviceContext dctx, PetscLogDouble *elapsed)
345: {
346: PetscFunctionBegin;
347: /* we do error checking here as this routine is an entry-point */
349: PetscAssertPointer(elapsed, 2);
350: PetscUseTypeMethod(dctx, endtimer, elapsed);
351: PetscFunctionReturn(PETSC_SUCCESS);
352: }
353: #else /* PETSC_HAVE_CXX for PetscDeviceContext Internal Functions */
354: #define PetscDeviceContextGetNullContext_Internal(dctx) (*(dctx) = PETSC_NULLPTR, PETSC_SUCCESS)
355: #define PetscDeviceContextGetBLASHandle_Internal(dctx, handle) (*(handle) = PETSC_NULLPTR, PETSC_SUCCESS)
356: #define PetscDeviceContextGetSOLVERHandle_Internal(dctx, handle) (*(handle) = PETSC_NULLPTR, PETSC_SUCCESS)
357: #define PetscDeviceContextGetStreamHandle_Internal(dctx, handle) (*(handle) = PETSC_NULLPTR, PETSC_SUCCESS)
358: #define PetscDeviceContextBeginTimer_Internal(dctx) PETSC_SUCCESS
359: #define PetscDeviceContextEndTimer_Internal(dctx, elapsed) PETSC_SUCCESS
360: #endif /* PETSC_HAVE_CXX for PetscDeviceContext Internal Functions */
362: /* note, only does assertion checking in debug mode */
363: static inline PetscErrorCode PetscDeviceContextGetCurrentContextAssertType_Internal(PetscDeviceContext *dctx, PetscDeviceType type)
364: {
365: PetscFunctionBegin;
366: PetscCall(PetscDeviceContextGetCurrentContext(dctx));
367: if (PetscDefined(USE_DEBUG)) {
368: PetscDeviceType dtype;
371: PetscCall(PetscDeviceContextGetDeviceType(*dctx, &dtype));
372: PetscCheckCompatibleDeviceTypes(dtype, 1, type, 2);
373: } else (void)type;
374: PetscFunctionReturn(PETSC_SUCCESS);
375: }
377: static inline PetscErrorCode PetscDeviceContextGetOptionalNullContext_Internal(PetscDeviceContext *dctx)
378: {
379: PetscFunctionBegin;
380: PetscAssertPointer(dctx, 1);
381: if (!*dctx) PetscCall(PetscDeviceContextGetNullContext_Internal(dctx));
383: PetscFunctionReturn(PETSC_SUCCESS);
384: }
386: /* Experimental API -- it will eventually become public */
387: #if PetscDefined(HAVE_CXX)
388: PETSC_EXTERN PetscErrorCode PetscDeviceRegisterMemory(const void *PETSC_RESTRICT, PetscMemType, size_t);
389: PETSC_EXTERN PetscErrorCode PetscDeviceGetAttribute(PetscDevice, PetscDeviceAttribute, void *);
390: PETSC_EXTERN PetscErrorCode PetscDeviceContextMarkIntentFromID(PetscDeviceContext, PetscObjectId, PetscMemoryAccessMode, const char name[]);
391: #if defined(__cplusplus)
392: namespace
393: {
395: inline PetscErrorCode PetscDeviceContextMarkIntentFromID(PetscDeviceContext dctx, PetscObject obj, PetscMemoryAccessMode mode, const char name[])
396: {
397: PetscFunctionBegin;
398: PetscCall(PetscDeviceContextMarkIntentFromID(dctx, obj->id, mode, name));
399: PetscFunctionReturn(PETSC_SUCCESS);
400: }
402: } // anonymous namespace
403: #endif // __cplusplus
404: #else
405: #define PetscDeviceRegisterMemory(void_ptr, PetscMemType, size) PETSC_SUCCESS
406: #define PetscDeviceGetAttribute(PetscDevice, PetscDeviceAttribute, void_star) ((*((int *)(void_star)) = 0), PETSC_SUCCESS)
407: #define PetscDeviceContextMarkIntentFromID(PetscDeviceContext, PetscObjectId, PetscMemoryAccessMode, ptr) PETSC_SUCCESS
408: #endif
410: PETSC_INTERN PetscErrorCode PetscDeviceContextCreate_HOST(PetscDeviceContext);
411: #if PetscDefined(HAVE_CUDA)
412: PETSC_INTERN PetscErrorCode PetscDeviceContextCreate_CUDA(PetscDeviceContext);
413: #endif
414: #if PetscDefined(HAVE_HIP)
415: PETSC_INTERN PetscErrorCode PetscDeviceContextCreate_HIP(PetscDeviceContext);
416: #endif
417: #if PetscDefined(HAVE_SYCL)
418: PETSC_INTERN PetscErrorCode PetscDeviceContextCreate_SYCL(PetscDeviceContext);
419: #endif
421: // Used for testing purposes, internal use ONLY
422: PETSC_EXTERN PetscErrorCode PetscGetMarkedObjectMap_Internal(size_t *, PetscObjectId **, PetscMemoryAccessMode **, size_t **, PetscEvent ***);
423: PETSC_EXTERN PetscErrorCode PetscRestoreMarkedObjectMap_Internal(size_t, PetscObjectId **, PetscMemoryAccessMode **, size_t **, PetscEvent ***);
425: static inline PetscErrorCode PetscDeviceContextSynchronizeIfWithBarrier_Internal(PetscDeviceContext dctx)
426: {
427: PetscStreamType stream_type;
429: PetscFunctionBegin;
430: PetscCall(PetscDeviceContextGetStreamType(dctx, &stream_type));
431: if (stream_type == PETSC_STREAM_DEFAULT_WITH_BARRIER || stream_type == PETSC_STREAM_NONBLOCKING_WITH_BARRIER) PetscCall(PetscDeviceContextSynchronize(dctx));
432: PetscFunctionReturn(PETSC_SUCCESS);
433: }