10e6b6b59SJacob Faibussowitsch #include <petsc/private/deviceimpl.h> /*I <petscdevice.h> I*/
20e6b6b59SJacob Faibussowitsch
30e6b6b59SJacob Faibussowitsch PetscLogEvent CUBLAS_HANDLE_CREATE;
40e6b6b59SJacob Faibussowitsch PetscLogEvent CUSOLVER_HANDLE_CREATE;
50e6b6b59SJacob Faibussowitsch PetscLogEvent HIPSOLVER_HANDLE_CREATE;
60e6b6b59SJacob Faibussowitsch PetscLogEvent HIPBLAS_HANDLE_CREATE;
70e6b6b59SJacob Faibussowitsch
80e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Create;
90e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Destroy;
100e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_ChangeStream;
110e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_SetDevice;
120e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_SetUp;
130e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Duplicate;
140e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_QueryIdle;
150e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_WaitForCtx;
160e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Fork;
170e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Join;
180e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Sync;
190e6b6b59SJacob Faibussowitsch PetscLogEvent DCONTEXT_Mark;
200e6b6b59SJacob Faibussowitsch
210e6b6b59SJacob Faibussowitsch // DO NOT MOVE THESE (literally, they must be exactly here)!
220e6b6b59SJacob Faibussowitsch //
230e6b6b59SJacob Faibussowitsch // pgcc has a _very_ strange bug, where if both of these are defined at the top of this file,
240e6b6b59SJacob Faibussowitsch // then building src/sys/objects/device/test/ex2.c results in "undefined reference to
250e6b6b59SJacob Faibussowitsch // PETSC_DEVICE_CONTEXT_CLASSID". If you initialize PETSC_DEVICE_CONTEXT_CLASSID it goes
260e6b6b59SJacob Faibussowitsch // away. If you move the definition down, it goes away.
270e6b6b59SJacob Faibussowitsch PetscClassId PETSC_DEVICE_CLASSID;
280e6b6b59SJacob Faibussowitsch PetscClassId PETSC_DEVICE_CONTEXT_CLASSID;
290e6b6b59SJacob Faibussowitsch
300e6b6b59SJacob Faibussowitsch // clang-format off
310e6b6b59SJacob Faibussowitsch const char *const PetscStreamTypes[] = {
32*d9acb416SHong Zhang "default",
33*d9acb416SHong Zhang "nonblocking",
34*d9acb416SHong Zhang "default_with_barrier",
35*d9acb416SHong Zhang "nonblocking_with_barrier",
360e6b6b59SJacob Faibussowitsch "max",
370e6b6b59SJacob Faibussowitsch "PetscStreamType",
380e6b6b59SJacob Faibussowitsch "PETSC_STREAM_",
390e6b6b59SJacob Faibussowitsch PETSC_NULLPTR
400e6b6b59SJacob Faibussowitsch };
410e6b6b59SJacob Faibussowitsch
420e6b6b59SJacob Faibussowitsch const char *const PetscDeviceContextJoinModes[] = {
430e6b6b59SJacob Faibussowitsch "destroy",
440e6b6b59SJacob Faibussowitsch "sync",
450e6b6b59SJacob Faibussowitsch "no_sync",
460e6b6b59SJacob Faibussowitsch "PetscDeviceContextJoinMode",
470e6b6b59SJacob Faibussowitsch "PETSC_DEVICE_CONTEXT_JOIN_",
480e6b6b59SJacob Faibussowitsch PETSC_NULLPTR
490e6b6b59SJacob Faibussowitsch };
500e6b6b59SJacob Faibussowitsch
510e6b6b59SJacob Faibussowitsch const char *const PetscDeviceTypes[] = {
520e6b6b59SJacob Faibussowitsch "host",
530e6b6b59SJacob Faibussowitsch "cuda",
540e6b6b59SJacob Faibussowitsch "hip",
550e6b6b59SJacob Faibussowitsch "sycl",
560e6b6b59SJacob Faibussowitsch "max",
570e6b6b59SJacob Faibussowitsch "PetscDeviceType",
580e6b6b59SJacob Faibussowitsch "PETSC_DEVICE_",
590e6b6b59SJacob Faibussowitsch PETSC_NULLPTR
600e6b6b59SJacob Faibussowitsch };
610e6b6b59SJacob Faibussowitsch
620e6b6b59SJacob Faibussowitsch const char *const PetscDeviceInitTypes[] = {
630e6b6b59SJacob Faibussowitsch "none",
640e6b6b59SJacob Faibussowitsch "lazy",
650e6b6b59SJacob Faibussowitsch "eager",
660e6b6b59SJacob Faibussowitsch "PetscDeviceInitType",
670e6b6b59SJacob Faibussowitsch "PETSC_DEVICE_INIT_",
680e6b6b59SJacob Faibussowitsch PETSC_NULLPTR
690e6b6b59SJacob Faibussowitsch };
700e6b6b59SJacob Faibussowitsch
710e6b6b59SJacob Faibussowitsch #ifdef __cplusplus
720e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/type_traits.hpp>
730e6b6b59SJacob Faibussowitsch
74bd2fcf0cSJacob Faibussowitsch static_assert(Petsc::util::to_underlying(PETSC_DEVICE_INIT_NONE) == 0, "");
75bd2fcf0cSJacob Faibussowitsch static_assert(Petsc::util::to_underlying(PETSC_DEVICE_INIT_LAZY) == 1, "");
76bd2fcf0cSJacob Faibussowitsch static_assert(Petsc::util::to_underlying(PETSC_DEVICE_INIT_EAGER) == 2, "");
770e6b6b59SJacob Faibussowitsch
780e6b6b59SJacob Faibussowitsch static_assert(
790e6b6b59SJacob Faibussowitsch PETSC_STATIC_ARRAY_LENGTH(PetscDeviceInitTypes) == 6,
800e6b6b59SJacob Faibussowitsch "Must change CUPMDevice<T>::initialize number of enum values in -device_enable_cupm to match!"
810e6b6b59SJacob Faibussowitsch );
820e6b6b59SJacob Faibussowitsch #endif
830e6b6b59SJacob Faibussowitsch
840e6b6b59SJacob Faibussowitsch const char *const PetscDeviceAttributes[] = {
850e6b6b59SJacob Faibussowitsch "shared_mem_per_block",
860e6b6b59SJacob Faibussowitsch "max",
870e6b6b59SJacob Faibussowitsch "PetscDeviceAttribute",
880e6b6b59SJacob Faibussowitsch "PETSC_DEVICE_ATTR_",
890e6b6b59SJacob Faibussowitsch PETSC_NULLPTR
900e6b6b59SJacob Faibussowitsch };
910e6b6b59SJacob Faibussowitsch // clang-format on
920e6b6b59SJacob Faibussowitsch
930e6b6b59SJacob Faibussowitsch static PetscBool registered = PETSC_FALSE;
940e6b6b59SJacob Faibussowitsch
PetscDeviceRegisterEvent_Private(const char name[],PetscClassId id,PetscLogEvent * event)95d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDeviceRegisterEvent_Private(const char name[], PetscClassId id, PetscLogEvent *event)
96d71ae5a4SJacob Faibussowitsch {
970e6b6b59SJacob Faibussowitsch PetscFunctionBegin;
980e6b6b59SJacob Faibussowitsch PetscCall(PetscLogEventRegister(name, id, event));
990e6b6b59SJacob Faibussowitsch PetscCall(PetscLogEventSetCollective(*event, PETSC_FALSE));
1003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1010e6b6b59SJacob Faibussowitsch }
1020e6b6b59SJacob Faibussowitsch
1030e6b6b59SJacob Faibussowitsch /*@C
1040e6b6b59SJacob Faibussowitsch PetscDeviceFinalizePackage - This function cleans up all components of the `PetscDevice`
1050e6b6b59SJacob Faibussowitsch package. It is called from `PetscFinalize()`.
1060e6b6b59SJacob Faibussowitsch
107aec76313SJacob Faibussowitsch Developer Notes:
1080e6b6b59SJacob Faibussowitsch This function is automatically registered to be called during `PetscFinalize()` by
1090e6b6b59SJacob Faibussowitsch `PetscDeviceInitializePackage()` so there should be no need to call it yourself.
1100e6b6b59SJacob Faibussowitsch
1110e6b6b59SJacob Faibussowitsch Level: developer
1120e6b6b59SJacob Faibussowitsch
1130e6b6b59SJacob Faibussowitsch .seealso: `PetscFinalize()`, `PetscDeviceInitializePackage()`
1140e6b6b59SJacob Faibussowitsch @*/
PetscDeviceFinalizePackage(void)115d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDeviceFinalizePackage(void)
116d71ae5a4SJacob Faibussowitsch {
1170e6b6b59SJacob Faibussowitsch PetscFunctionBegin;
1180e6b6b59SJacob Faibussowitsch registered = PETSC_FALSE;
1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1200e6b6b59SJacob Faibussowitsch }
1210e6b6b59SJacob Faibussowitsch
1220e6b6b59SJacob Faibussowitsch /*@C
1230e6b6b59SJacob Faibussowitsch PetscDeviceInitializePackage - This function initializes everything in the `PetscDevice`
1240e6b6b59SJacob Faibussowitsch package. It is called on the first call to `PetscDeviceContextCreate()` or
1250e6b6b59SJacob Faibussowitsch `PetscDeviceCreate()` when using shared or static libraries.
1260e6b6b59SJacob Faibussowitsch
1270e6b6b59SJacob Faibussowitsch Level: developer
1280e6b6b59SJacob Faibussowitsch
1290e6b6b59SJacob Faibussowitsch .seealso: `PetscInitialize()`, `PetscDeviceFinalizePackage()`, `PetscDeviceContextCreate()`,
1300e6b6b59SJacob Faibussowitsch `PetscDeviceCreate()`
1310e6b6b59SJacob Faibussowitsch @*/
PetscDeviceInitializePackage(void)132d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDeviceInitializePackage(void)
133d71ae5a4SJacob Faibussowitsch {
1340e6b6b59SJacob Faibussowitsch PetscFunctionBegin;
1350e6b6b59SJacob Faibussowitsch PetscCheck(PetscDeviceConfiguredFor_Internal(PETSC_DEVICE_DEFAULT()), PETSC_COMM_SELF, PETSC_ERR_SUP, "PETSc is not configured with device support (PETSC_DEVICE_DEFAULT = '%s')", PetscDeviceTypes[PETSC_DEVICE_DEFAULT()]);
1363ba16761SJacob Faibussowitsch if (PetscLikely(registered)) PetscFunctionReturn(PETSC_SUCCESS);
1370e6b6b59SJacob Faibussowitsch registered = PETSC_TRUE;
1380e6b6b59SJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscDeviceFinalizePackage));
1390e6b6b59SJacob Faibussowitsch // class registration
1400e6b6b59SJacob Faibussowitsch PetscCall(PetscClassIdRegister("PetscDevice", &PETSC_DEVICE_CLASSID));
1410e6b6b59SJacob Faibussowitsch PetscCall(PetscClassIdRegister("PetscDeviceContext", &PETSC_DEVICE_CONTEXT_CLASSID));
1420e6b6b59SJacob Faibussowitsch // events
1430e6b6b59SJacob Faibussowitsch if (PetscDefined(HAVE_CUDA)) {
1440e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("cuBLAS Init", PETSC_DEVICE_CONTEXT_CLASSID, &CUBLAS_HANDLE_CREATE));
1450e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("cuSolver Init", PETSC_DEVICE_CONTEXT_CLASSID, &CUSOLVER_HANDLE_CREATE));
1460e6b6b59SJacob Faibussowitsch }
1470e6b6b59SJacob Faibussowitsch if (PetscDefined(HAVE_HIP)) {
1480e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("hipBLAS Init", PETSC_DEVICE_CONTEXT_CLASSID, &HIPBLAS_HANDLE_CREATE));
1490e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("hipSolver Init", PETSC_DEVICE_CONTEXT_CLASSID, &HIPSOLVER_HANDLE_CREATE));
1500e6b6b59SJacob Faibussowitsch }
1510e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxCreate", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Create));
1520e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxDestroy", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Destroy));
1530e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxChangeStream", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_ChangeStream));
1540e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxSetUp", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_SetUp));
1550e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxSetDevice", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_SetDevice));
1560e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxDuplicate", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Duplicate));
1570e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxQueryIdle", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_QueryIdle));
1580e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxWaitForCtx", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_WaitForCtx));
1590e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxFork", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Fork));
1600e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxJoin", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Join));
1610e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxSync", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Sync));
1620e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceRegisterEvent_Private("DCtxMark", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Mark));
1630e6b6b59SJacob Faibussowitsch {
1640e6b6b59SJacob Faibussowitsch const PetscClassId classids[] = {PETSC_DEVICE_CONTEXT_CLASSID, PETSC_DEVICE_CLASSID};
1650e6b6b59SJacob Faibussowitsch
1660e6b6b59SJacob Faibussowitsch PetscCall(PetscInfoProcessClass("device", PETSC_STATIC_ARRAY_LENGTH(classids), classids));
1670e6b6b59SJacob Faibussowitsch }
1683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1690e6b6b59SJacob Faibussowitsch }
170