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 */