1: #ifndef PETSCSYCLDEVICE_HPP
2: #define PETSCSYCLDEVICE_HPP
4: #include <petsc/private/deviceimpl.h>
5: #include <petscviewer.h>
6: #include <array>
7: #include <limits>
9: namespace Petsc
10: {
12: namespace Device
13: {
15: namespace SYCL
16: {
18: #define PETSC_SYCL_DEVICE_HOST -1 // Note -1 is also used by PETSC_DECIDE, so user needs to pass -2 to explicitly select the host
19: #define PETSC_SYCL_DEVICE_NONE -3
21: class Device
22: {
23: public:
24: using createContextFunction_t = PetscErrorCode (*)(PetscDeviceContext);
26: explicit Device(createContextFunction_t func) noexcept : create_(func) { }
27: ~Device() {static_cast<void>(finalize_());}
29: PETSC_NODISCARD static PetscErrorCode initialize(MPI_Comm,PetscInt*,PetscDeviceInitType*) noexcept;
30: PETSC_NODISCARD PetscErrorCode getDevice(PetscDevice,PetscInt) const noexcept;
31: PETSC_NODISCARD static PetscErrorCode configureDevice(PetscDevice) noexcept;
32: PETSC_NODISCARD static PetscErrorCode viewDevice(PetscDevice,PetscViewer) noexcept;
34: private:
35: // opaque class representing a single device instance
36: class DeviceInternal;
38: const createContextFunction_t create_;
40: // currently stores sycl host and gpu devices
41: static std::array<DeviceInternal*,PETSC_DEVICE_MAX_DEVICES> devices_array_;
42: static DeviceInternal **devices_; // alias to devices_array_, but shifted to support devices_[-1] for sycl host device
44: // this rank's default device. If equals to PETSC_SYCL_DEVICE_NONE, then all sycl devices are disabled
45: static int defaultDevice_;
47: // have we tried looking for devices
48: static bool initialized_;
50: // clean-up
51: PETSC_NODISCARD static PetscErrorCode finalize_() noexcept;
52: };
54: } // namespace SYCL
56: } // namespace Device
58: } // namespace Petsc
60: #endif /* PETSCSYCLDEVICE_HPP */