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: }