Actual source code: devicereg.c

  1: #include <petsc/private/deviceimpl.h>

  3: PetscLogEvent CUBLAS_HANDLE_CREATE;
  4: PetscLogEvent CUSOLVER_HANDLE_CREATE;
  5: PetscLogEvent HIPSOLVER_HANDLE_CREATE;
  6: PetscLogEvent HIPBLAS_HANDLE_CREATE;

  8: PetscLogEvent DCONTEXT_Create;
  9: PetscLogEvent DCONTEXT_Destroy;
 10: PetscLogEvent DCONTEXT_ChangeStream;
 11: PetscLogEvent DCONTEXT_SetDevice;
 12: PetscLogEvent DCONTEXT_SetUp;
 13: PetscLogEvent DCONTEXT_Duplicate;
 14: PetscLogEvent DCONTEXT_QueryIdle;
 15: PetscLogEvent DCONTEXT_WaitForCtx;
 16: PetscLogEvent DCONTEXT_Fork;
 17: PetscLogEvent DCONTEXT_Join;
 18: PetscLogEvent DCONTEXT_Sync;
 19: PetscLogEvent DCONTEXT_Mark;

 21: // DO NOT MOVE THESE (literally, they must be exactly here)!
 22: //
 23: // pgcc has a _very_ strange bug, where if both of these are defined at the top of this file,
 24: // then building src/sys/objects/device/test/ex2.c results in "undefined reference to
 25: // PETSC_DEVICE_CONTEXT_CLASSID". If you initialize PETSC_DEVICE_CONTEXT_CLASSID it goes
 26: // away. If you move the definition down, it goes away.
 27: PetscClassId PETSC_DEVICE_CLASSID;
 28: PetscClassId PETSC_DEVICE_CONTEXT_CLASSID;

 30: // clang-format off
 31: const char *const PetscStreamTypes[] = {
 32:   "default",
 33:   "nonblocking",
 34:   "default_with_barrier",
 35:   "nonblocking_with_barrier",
 36:   "max",
 37:   "PetscStreamType",
 38:   "PETSC_STREAM_",
 39:   PETSC_NULLPTR
 40: };

 42: const char *const PetscDeviceContextJoinModes[] = {
 43:   "destroy",
 44:   "sync",
 45:   "no_sync",
 46:   "PetscDeviceContextJoinMode",
 47:   "PETSC_DEVICE_CONTEXT_JOIN_",
 48:   PETSC_NULLPTR
 49: };

 51: const char *const PetscDeviceTypes[] = {
 52:   "host",
 53:   "cuda",
 54:   "hip",
 55:   "sycl",
 56:   "max",
 57:   "PetscDeviceType",
 58:   "PETSC_DEVICE_",
 59:   PETSC_NULLPTR
 60: };

 62: const char *const PetscDeviceInitTypes[] = {
 63:   "none",
 64:   "lazy",
 65:   "eager",
 66:   "PetscDeviceInitType",
 67:   "PETSC_DEVICE_INIT_",
 68:   PETSC_NULLPTR
 69: };

 71: #ifdef __cplusplus
 72: #include <petsc/private/cpp/type_traits.hpp>

 74: static_assert(Petsc::util::to_underlying(PETSC_DEVICE_INIT_NONE) == 0, "");
 75: static_assert(Petsc::util::to_underlying(PETSC_DEVICE_INIT_LAZY) == 1, "");
 76: static_assert(Petsc::util::to_underlying(PETSC_DEVICE_INIT_EAGER) == 2, "");

 78: static_assert(
 79:   PETSC_STATIC_ARRAY_LENGTH(PetscDeviceInitTypes) == 6,
 80:   "Must change CUPMDevice<T>::initialize number of enum values in -device_enable_cupm to match!"
 81: );
 82: #endif

 84: const char *const PetscDeviceAttributes[] = {
 85:   "shared_mem_per_block",
 86:   "max",
 87:   "PetscDeviceAttribute",
 88:   "PETSC_DEVICE_ATTR_",
 89:   PETSC_NULLPTR
 90: };
 91: // clang-format on

 93: static PetscBool registered = PETSC_FALSE;

 95: static PetscErrorCode PetscDeviceRegisterEvent_Private(const char name[], PetscClassId id, PetscLogEvent *event)
 96: {
 97:   PetscFunctionBegin;
 98:   PetscCall(PetscLogEventRegister(name, id, event));
 99:   PetscCall(PetscLogEventSetCollective(*event, PETSC_FALSE));
100:   PetscFunctionReturn(PETSC_SUCCESS);
101: }

103: /*@C
104:   PetscDeviceFinalizePackage - This function cleans up all components of the `PetscDevice`
105:   package. It is called from `PetscFinalize()`.

107:   Developer Notes:
108:   This function is automatically registered to be called during `PetscFinalize()` by
109:   `PetscDeviceInitializePackage()` so there should be no need to call it yourself.

111:   Level: developer

113: .seealso: `PetscFinalize()`, `PetscDeviceInitializePackage()`
114: @*/
115: PetscErrorCode PetscDeviceFinalizePackage(void)
116: {
117:   PetscFunctionBegin;
118:   registered = PETSC_FALSE;
119:   PetscFunctionReturn(PETSC_SUCCESS);
120: }

122: /*@C
123:   PetscDeviceInitializePackage - This function initializes everything in the `PetscDevice`
124:   package. It is called on the first call to `PetscDeviceContextCreate()` or
125:   `PetscDeviceCreate()` when using shared or static libraries.

127:   Level: developer

129: .seealso: `PetscInitialize()`, `PetscDeviceFinalizePackage()`, `PetscDeviceContextCreate()`,
130: `PetscDeviceCreate()`
131: @*/
132: PetscErrorCode PetscDeviceInitializePackage(void)
133: {
134:   PetscFunctionBegin;
135:   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()]);
136:   if (PetscLikely(registered)) PetscFunctionReturn(PETSC_SUCCESS);
137:   registered = PETSC_TRUE;
138:   PetscCall(PetscRegisterFinalize(PetscDeviceFinalizePackage));
139:   // class registration
140:   PetscCall(PetscClassIdRegister("PetscDevice", &PETSC_DEVICE_CLASSID));
141:   PetscCall(PetscClassIdRegister("PetscDeviceContext", &PETSC_DEVICE_CONTEXT_CLASSID));
142:   // events
143:   if (PetscDefined(HAVE_CUDA)) {
144:     PetscCall(PetscDeviceRegisterEvent_Private("cuBLAS Init", PETSC_DEVICE_CONTEXT_CLASSID, &CUBLAS_HANDLE_CREATE));
145:     PetscCall(PetscDeviceRegisterEvent_Private("cuSolver Init", PETSC_DEVICE_CONTEXT_CLASSID, &CUSOLVER_HANDLE_CREATE));
146:   }
147:   if (PetscDefined(HAVE_HIP)) {
148:     PetscCall(PetscDeviceRegisterEvent_Private("hipBLAS Init", PETSC_DEVICE_CONTEXT_CLASSID, &HIPBLAS_HANDLE_CREATE));
149:     PetscCall(PetscDeviceRegisterEvent_Private("hipSolver Init", PETSC_DEVICE_CONTEXT_CLASSID, &HIPSOLVER_HANDLE_CREATE));
150:   }
151:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxCreate", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Create));
152:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxDestroy", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Destroy));
153:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxChangeStream", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_ChangeStream));
154:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxSetUp", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_SetUp));
155:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxSetDevice", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_SetDevice));
156:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxDuplicate", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Duplicate));
157:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxQueryIdle", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_QueryIdle));
158:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxWaitForCtx", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_WaitForCtx));
159:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxFork", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Fork));
160:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxJoin", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Join));
161:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxSync", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Sync));
162:   PetscCall(PetscDeviceRegisterEvent_Private("DCtxMark", PETSC_DEVICE_CONTEXT_CLASSID, &DCONTEXT_Mark));
163:   {
164:     const PetscClassId classids[] = {PETSC_DEVICE_CONTEXT_CLASSID, PETSC_DEVICE_CLASSID};

166:     PetscCall(PetscInfoProcessClass("device", PETSC_STATIC_ARRAY_LENGTH(classids), classids));
167:   }
168:   PetscFunctionReturn(PETSC_SUCCESS);
169: }