xref: /petsc/src/sys/objects/kokkos/kinit.kokkos.cxx (revision 9c9deb76dd0719e9932a40601ba89146ea490760)
1a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h>
20e6b6b59SJacob Faibussowitsch #include <petscpkg_version.h>
3524fe776SJunchao Zhang #include <petsc_kokkos.hpp>
4c2b86a48SJunchao Zhang 
545639126SStefano Zampini PetscBool PetscKokkosInitialized = PETSC_FALSE;
645639126SStefano Zampini 
7524fe776SJunchao Zhang Kokkos::DefaultExecutionSpace *PetscKokkosExecutionSpacePtr = nullptr;
8524fe776SJunchao Zhang 
9d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscKokkosFinalize_Private(void)
10d71ae5a4SJacob Faibussowitsch {
11c2b86a48SJunchao Zhang   PetscFunctionBegin;
12524fe776SJunchao Zhang   PetscCallCXX(delete PetscKokkosExecutionSpacePtr);
13c2b86a48SJunchao Zhang   Kokkos::finalize();
143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15c2b86a48SJunchao Zhang }
16c2b86a48SJunchao Zhang 
17d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool *isInitialized)
18d71ae5a4SJacob Faibussowitsch {
19c2b86a48SJunchao Zhang   PetscFunctionBegin;
20c2b86a48SJunchao Zhang   *isInitialized = Kokkos::is_initialized() ? PETSC_TRUE : PETSC_FALSE;
213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22c2b86a48SJunchao Zhang }
23375e5adfSJunchao Zhang 
2434766dafSJunchao Zhang /* Initialize Kokkos if not yet */
25d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscKokkosInitializeCheck(void)
26d71ae5a4SJacob Faibussowitsch {
27375e5adfSJunchao Zhang   PetscFunctionBegin;
2834766dafSJunchao Zhang   if (!Kokkos::is_initialized()) {
29471471fdSJunchao Zhang #if PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
30c66e0907SJunchao Zhang     auto args = Kokkos::InitializationSettings();
31c66e0907SJunchao Zhang #else
3262825ce1SJacob Faibussowitsch     auto args             = Kokkos::InitArguments{}; /* use default constructor */
33c66e0907SJunchao Zhang #endif
34b84ac304SJunchao Zhang 
3562825ce1SJacob Faibussowitsch #if (defined(KOKKOS_ENABLE_CUDA) && PetscDefined(HAVE_CUDA)) || (defined(KOKKOS_ENABLE_HIP) && PetscDefined(HAVE_HIP)) || (defined(KOKKOS_ENABLE_SYCL) && PetscDefined(HAVE_SYCL))
3662825ce1SJacob Faibussowitsch     /* Kokkos does not support CUDA and HIP at the same time (but we do :)) */
37ab4ee011SJunchao Zhang     PetscDevice device;
38ab4ee011SJunchao Zhang     PetscInt    deviceId;
39ab4ee011SJunchao Zhang     PetscCall(PetscDeviceCreate(PETSC_DEVICE_DEFAULT(), PETSC_DECIDE, &device));
40ab4ee011SJunchao Zhang     PetscCall(PetscDeviceGetDeviceId(device, &deviceId));
41ab4ee011SJunchao Zhang     PetscCall(PetscDeviceDestroy(&device));
42ab4ee011SJunchao Zhang   #if PETSC_PKG_KOKKOS_VERSION_GE(4, 0, 0)
43ab4ee011SJunchao Zhang     // if device_id is not set, and no gpus have been found, kokkos will use CPU
44ab4ee011SJunchao Zhang     if (deviceId >= 0) args.set_device_id(static_cast<int>(deviceId));
45ab4ee011SJunchao Zhang   #elif PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
46ab4ee011SJunchao Zhang     args.set_device_id(static_cast<int>(deviceId));
47c66e0907SJunchao Zhang   #else
48ab4ee011SJunchao Zhang     PetscCall(PetscMPIIntCast(deviceId, &args.device_id));
49375e5adfSJunchao Zhang   #endif
50c66e0907SJunchao Zhang #endif
5111f0be55SJunchao Zhang 
52471471fdSJunchao Zhang #if PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
53c66e0907SJunchao Zhang     args.set_disable_warnings(!PetscDefined(HAVE_KOKKOS_INIT_WARNINGS));
54c66e0907SJunchao Zhang #else
5562825ce1SJacob Faibussowitsch     args.disable_warnings = !PetscDefined(HAVE_KOKKOS_INIT_WARNINGS);
56c66e0907SJunchao Zhang #endif
5762825ce1SJacob Faibussowitsch 
5811f0be55SJunchao Zhang     /* To use PetscNumOMPThreads, one has to configure petsc --with-openmp.
5911f0be55SJunchao Zhang        Otherwise, let's keep the default value (-1) of args.num_threads.
6011f0be55SJunchao Zhang     */
6162825ce1SJacob Faibussowitsch #if defined(KOKKOS_ENABLE_OPENMP) && PetscDefined(HAVE_OPENMP)
62471471fdSJunchao Zhang   #if PETSC_PKG_KOKKOS_VERSION_GE(3, 7, 0)
63c66e0907SJunchao Zhang     args.set_num_threads(PetscNumOMPThreads);
64c66e0907SJunchao Zhang   #else
6511f0be55SJunchao Zhang     args.num_threads = PetscNumOMPThreads;
6611f0be55SJunchao Zhang   #endif
67c66e0907SJunchao Zhang #endif
68ab4ee011SJunchao Zhang     PetscCallCXX(Kokkos::initialize(args));
69*9c9deb76SJunchao Zhang     PetscBeganKokkos = PETSC_TRUE;
70*9c9deb76SJunchao Zhang   }
71*9c9deb76SJunchao Zhang   if (!PetscKokkosExecutionSpacePtr) { // No matter Kokkos is init'ed by petsc or by user, we need to init PetscKokkosExecutionSpacePtr
72524fe776SJunchao Zhang #if defined(PETSC_HAVE_CUDA)
73524fe776SJunchao Zhang     extern cudaStream_t PetscDefaultCudaStream;
74524fe776SJunchao Zhang     PetscCallCXX(PetscKokkosExecutionSpacePtr = new Kokkos::DefaultExecutionSpace(PetscDefaultCudaStream));
75524fe776SJunchao Zhang #elif defined(PETS_HAVE_HIP)
76524fe776SJunchao Zhang     extern hipStream_t PetscDefaultHipStream;
77524fe776SJunchao Zhang     PetscCallCXX(PetscKokkosExecutionSpacePtr = new Kokkos::DefaultExecutionSpace(PetscDefaultHipStream));
78524fe776SJunchao Zhang #else
79524fe776SJunchao Zhang     PetscCallCXX(PetscKokkosExecutionSpacePtr = new Kokkos::DefaultExecutionSpace());
80524fe776SJunchao Zhang #endif
8159e55d94SJunchao Zhang   }
8245639126SStefano Zampini   PetscKokkosInitialized = PETSC_TRUE;
833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
84375e5adfSJunchao Zhang }
85