1: #ifndef PETSCCUPMDEVICE_HPP
2: #define PETSCCUPMDEVICE_HPP
4: #include <petsc/private/deviceimpl.h>
5: #include <petsc/private/cupminterface.hpp>
6: #include <petsc/private/viewerimpl.h>
7: #include <array>
8: #include <memory>
9: #include <limits>
11: namespace Petsc
12: {
14: namespace Device
15: {
17: namespace CUPM
18: {
20: #if defined(PETSC_CUPM_DEVICE_NONE)
21: # error redefinition of PETSC_CUPM_DEVICE_NONE
22: #endif
24: #define PETSC_CUPM_DEVICE_NONE -3
26: template <DeviceType T>
27: class Device : Impl::Interface<T>
28: {
29: public:
30: using createContextFunction_t = PetscErrorCode (*)(PetscDeviceContext);
31: PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(cupmInterface_t,T);
33: // default constructor
34: explicit Device(createContextFunction_t func) noexcept : create_(func) { }
36: PETSC_NODISCARD static PetscErrorCode initialize(MPI_Comm,PetscInt*,PetscDeviceInitType*) noexcept;
38: PETSC_NODISCARD PetscErrorCode getDevice(PetscDevice,PetscInt) const noexcept;
40: PETSC_NODISCARD static PetscErrorCode configureDevice(PetscDevice) noexcept;
42: PETSC_NODISCARD static PetscErrorCode viewDevice(PetscDevice,PetscViewer) noexcept;
44: private:
45: // opaque class representing a single device
46: class DeviceInternal;
48: // all known devices
49: static std::array<std::unique_ptr<DeviceInternal>,PETSC_DEVICE_MAX_DEVICES> devices_;
51: // this ranks default device, if < 0 then devices are specifically disabled
52: static int defaultDevice_;
54: // function to create a PetscDeviceContext (the (*create) function pointer usually set
55: // via XXXSetType() for other PETSc objects)
56: const createContextFunction_t create_;
58: // have we tried looking for devices
59: static bool initialized_;
61: // clean-up
62: PETSC_NODISCARD static PetscErrorCode finalize_() noexcept;
63: };
65: // define static variables
66: template <DeviceType T> bool Device<T>::initialized_ = false;
68: template <DeviceType T>
69: std::array<std::unique_ptr<typename Device<T>::DeviceInternal>,PETSC_DEVICE_MAX_DEVICES>
70: Device<T>::devices_ = { };
72: template <DeviceType T> int Device<T>::defaultDevice_ = PETSC_CUPM_DEVICE_NONE;
74: } // namespace CUPM
76: } // namespace Device
78: } // namespace Petsc
80: #endif /* PETSCCUPMDEVICE_HPP */