xref: /petsc/src/sys/objects/kokkos/kinit.kokkos.cxx (revision bcee047adeeb73090d7e36cc71e39fc287cdbb97)
1 #include <petsc/private/deviceimpl.h>
2 #include <petscpkg_version.h>
3 #include <petsc_kokkos.hpp>
4 
5 PetscBool PetscKokkosInitialized = PETSC_FALSE;
6 
7 Kokkos::DefaultExecutionSpace *PetscKokkosExecutionSpacePtr = nullptr;
8 
9 PetscErrorCode PetscKokkosFinalize_Private(void)
10 {
11   PetscFunctionBegin;
12   PetscCallCXX(delete PetscKokkosExecutionSpacePtr);
13   Kokkos::finalize();
14   PetscFunctionReturn(PETSC_SUCCESS);
15 }
16 
17 PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool *isInitialized)
18 {
19   PetscFunctionBegin;
20   *isInitialized = Kokkos::is_initialized() ? PETSC_TRUE : PETSC_FALSE;
21   PetscFunctionReturn(PETSC_SUCCESS);
22 }
23 
24 /* Initialize Kokkos if not yet */
25 PetscErrorCode PetscKokkosInitializeCheck(void)
26 {
27   PetscFunctionBegin;
28   if (!Kokkos::is_initialized()) {
29 #if PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
30     auto args = Kokkos::InitializationSettings();
31 #else
32     auto args             = Kokkos::InitArguments{}; /* use default constructor */
33 #endif
34 
35 #if (defined(KOKKOS_ENABLE_CUDA) && PetscDefined(HAVE_CUDA)) || (defined(KOKKOS_ENABLE_HIP) && PetscDefined(HAVE_HIP)) || (defined(KOKKOS_ENABLE_SYCL) && PetscDefined(HAVE_SYCL))
36     /* Kokkos does not support CUDA and HIP at the same time (but we do :)) */
37     PetscDevice device;
38     PetscInt    deviceId;
39     PetscCall(PetscDeviceCreate(PETSC_DEVICE_DEFAULT(), PETSC_DECIDE, &device));
40     PetscCall(PetscDeviceGetDeviceId(device, &deviceId));
41     PetscCall(PetscDeviceDestroy(&device));
42   #if PETSC_PKG_KOKKOS_VERSION_GE(4, 0, 0)
43     // if device_id is not set, and no gpus have been found, kokkos will use CPU
44     if (deviceId >= 0) args.set_device_id(static_cast<int>(deviceId));
45   #elif PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
46     args.set_device_id(static_cast<int>(deviceId));
47   #else
48     PetscCall(PetscMPIIntCast(deviceId, &args.device_id));
49   #endif
50 #endif
51 
52 #if PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
53     args.set_disable_warnings(!PetscDefined(HAVE_KOKKOS_INIT_WARNINGS));
54 #else
55     args.disable_warnings = !PetscDefined(HAVE_KOKKOS_INIT_WARNINGS);
56 #endif
57 
58     /* To use PetscNumOMPThreads, one has to configure petsc --with-openmp.
59        Otherwise, let's keep the default value (-1) of args.num_threads.
60     */
61 #if defined(KOKKOS_ENABLE_OPENMP) && PetscDefined(HAVE_OPENMP)
62   #if PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
63     args.set_num_threads(PetscNumOMPThreads);
64   #else
65     args.num_threads = PetscNumOMPThreads;
66   #endif
67 #endif
68     PetscCallCXX(Kokkos::initialize(args));
69     PetscBeganKokkos = PETSC_TRUE;
70   }
71   if (!PetscKokkosExecutionSpacePtr) { // No matter Kokkos is init'ed by petsc or by user, we need to init PetscKokkosExecutionSpacePtr
72 #if defined(PETSC_HAVE_CUDA)
73     extern cudaStream_t PetscDefaultCudaStream;
74     PetscCallCXX(PetscKokkosExecutionSpacePtr = new Kokkos::DefaultExecutionSpace(PetscDefaultCudaStream));
75 #elif defined(PETS_HAVE_HIP)
76     extern hipStream_t PetscDefaultHipStream;
77     PetscCallCXX(PetscKokkosExecutionSpacePtr = new Kokkos::DefaultExecutionSpace(PetscDefaultHipStream));
78 #else
79     PetscCallCXX(PetscKokkosExecutionSpacePtr = new Kokkos::DefaultExecutionSpace());
80 #endif
81   }
82   PetscKokkosInitialized = PETSC_TRUE;
83   PetscFunctionReturn(PETSC_SUCCESS);
84 }
85