10e6b6b59SJacob Faibussowitsch #ifndef PETSC_CUPM_THRUST_UTILITY_HPP 20e6b6b59SJacob Faibussowitsch #define PETSC_CUPM_THRUST_UTILITY_HPP 30e6b6b59SJacob Faibussowitsch 40e6b6b59SJacob Faibussowitsch #if defined(__cplusplus) 5*f3146f24SJacob Faibussowitsch #include <petsclog.h> // PetscLogGpuTimeBegin()/End() 6*f3146f24SJacob Faibussowitsch #include <petscerror.h> // SETERRQ() 7*f3146f24SJacob Faibussowitsch #include <petscdevice_cupm.h> // PETSC_USING_NVCC 8*f3146f24SJacob Faibussowitsch 9*f3146f24SJacob Faibussowitsch #include <thrust/system_error.h> // thrust::system_error 10*f3146f24SJacob Faibussowitsch #include <thrust/execution_policy.h> // thrust::cuda/hip::par 110e6b6b59SJacob Faibussowitsch 12d71ae5a4SJacob Faibussowitsch namespace Petsc 13d71ae5a4SJacob Faibussowitsch { 140e6b6b59SJacob Faibussowitsch 15d71ae5a4SJacob Faibussowitsch namespace device 16d71ae5a4SJacob Faibussowitsch { 170e6b6b59SJacob Faibussowitsch 18d71ae5a4SJacob Faibussowitsch namespace cupm 19d71ae5a4SJacob Faibussowitsch { 200e6b6b59SJacob Faibussowitsch 210e6b6b59SJacob Faibussowitsch #if PetscDefined(USING_NVCC) 220e6b6b59SJacob Faibussowitsch #if !defined(THRUST_VERSION) 230e6b6b59SJacob Faibussowitsch #error "THRUST_VERSION not defined!" 240e6b6b59SJacob Faibussowitsch #endif 250e6b6b59SJacob Faibussowitsch #if !PetscDefined(USE_DEBUG) && (THRUST_VERSION >= 101600) 26*f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::cuda::par_nosync.on(s), __VA_ARGS__) 270e6b6b59SJacob Faibussowitsch #else 28*f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::cuda::par.on(s), __VA_ARGS__) 290e6b6b59SJacob Faibussowitsch #endif 300e6b6b59SJacob Faibussowitsch #elif PetscDefined(USING_HCC) // rocThrust has no par_nosync 31*f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::hip::par.on(s), __VA_ARGS__) 320e6b6b59SJacob Faibussowitsch #else 33*f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(__VA_ARGS__) 340e6b6b59SJacob Faibussowitsch #endif 350e6b6b59SJacob Faibussowitsch 36d71ae5a4SJacob Faibussowitsch namespace detail 37d71ae5a4SJacob Faibussowitsch { 380e6b6b59SJacob Faibussowitsch 390e6b6b59SJacob Faibussowitsch struct PetscLogGpuTimer { 400e6b6b59SJacob Faibussowitsch PetscLogGpuTimer() noexcept { PetscCallAbort(PETSC_COMM_SELF, PetscLogGpuTimeBegin()); } 410e6b6b59SJacob Faibussowitsch ~PetscLogGpuTimer() noexcept { PetscCallAbort(PETSC_COMM_SELF, PetscLogGpuTimeEnd()); } 420e6b6b59SJacob Faibussowitsch }; 430e6b6b59SJacob Faibussowitsch 440e6b6b59SJacob Faibussowitsch } // namespace detail 450e6b6b59SJacob Faibussowitsch 460e6b6b59SJacob Faibussowitsch #define THRUST_CALL(...) \ 470e6b6b59SJacob Faibussowitsch [&] { \ 48*f3146f24SJacob Faibussowitsch const auto timer = ::Petsc::device::cupm::detail::PetscLogGpuTimer{}; \ 49*f3146f24SJacob Faibussowitsch return PETSC_THRUST_CALL_PAR_ON(__VA_ARGS__); \ 500e6b6b59SJacob Faibussowitsch }() 510e6b6b59SJacob Faibussowitsch 520e6b6b59SJacob Faibussowitsch #define PetscCallThrust(...) \ 530e6b6b59SJacob Faibussowitsch do { \ 540e6b6b59SJacob Faibussowitsch try { \ 55*f3146f24SJacob Faibussowitsch { \ 560e6b6b59SJacob Faibussowitsch __VA_ARGS__; \ 57*f3146f24SJacob Faibussowitsch } \ 58d71ae5a4SJacob Faibussowitsch } catch (const thrust::system_error &ex) { \ 59d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Thrust error: %s", ex.what()); \ 60d71ae5a4SJacob Faibussowitsch } \ 610e6b6b59SJacob Faibussowitsch } while (0) 620e6b6b59SJacob Faibussowitsch 630e6b6b59SJacob Faibussowitsch } // namespace cupm 640e6b6b59SJacob Faibussowitsch 650e6b6b59SJacob Faibussowitsch } // namespace device 660e6b6b59SJacob Faibussowitsch 670e6b6b59SJacob Faibussowitsch } // namespace Petsc 680e6b6b59SJacob Faibussowitsch 690e6b6b59SJacob Faibussowitsch #endif // __cplusplus 700e6b6b59SJacob Faibussowitsch 710e6b6b59SJacob Faibussowitsch #endif // PETSC_CUPM_THRUST_UTILITY_HPP 72