xref: /petsc/src/sys/objects/device/util/devicereg.c (revision 98d129c30f3ee9fdddc40fdbc5a989b7be64f888)
1 #include <petsc/private/deviceimpl.h> /*I <petscdevice.h> I*/
2 
3 PetscLogEvent CUBLAS_HANDLE_CREATE;
4 PetscLogEvent CUSOLVER_HANDLE_CREATE;
5 PetscLogEvent HIPSOLVER_HANDLE_CREATE;
6 PetscLogEvent HIPBLAS_HANDLE_CREATE;
7 
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;
20 
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;
29 
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 };
41 
42 const char *const PetscDeviceContextJoinModes[] = {
43   "destroy",
44   "sync",
45   "no_sync",
46   "PetscDeviceContextJoinMode",
47   "PETSC_DEVICE_CONTEXT_JOIN_",
48   PETSC_NULLPTR
49 };
50 
51 const char *const PetscDeviceTypes[] = {
52   "host",
53   "cuda",
54   "hip",
55   "sycl",
56   "max",
57   "PetscDeviceType",
58   "PETSC_DEVICE_",
59   PETSC_NULLPTR
60 };
61 
62 const char *const PetscDeviceInitTypes[] = {
63   "none",
64   "lazy",
65   "eager",
66   "PetscDeviceInitType",
67   "PETSC_DEVICE_INIT_",
68   PETSC_NULLPTR
69 };
70 
71 #ifdef __cplusplus
72 #include <petsc/private/cpp/type_traits.hpp>
73 
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, "");
77 
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
83 
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
92 
93 static PetscBool registered = PETSC_FALSE;
94 
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 }
102 
103 /*@C
104   PetscDeviceFinalizePackage - This function cleans up all components of the `PetscDevice`
105   package. It is called from `PetscFinalize()`.
106 
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.
110 
111   Level: developer
112 
113 .seealso: `PetscFinalize()`, `PetscDeviceInitializePackage()`
114 @*/
115 PetscErrorCode PetscDeviceFinalizePackage(void)
116 {
117   PetscFunctionBegin;
118   registered = PETSC_FALSE;
119   PetscFunctionReturn(PETSC_SUCCESS);
120 }
121 
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.
126 
127   Level: developer
128 
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};
165 
166     PetscCall(PetscInfoProcessClass("device", PETSC_STATIC_ARRAY_LENGTH(classids), classids));
167   }
168   PetscFunctionReturn(PETSC_SUCCESS);
169 }
170