10e6b6b59SJacob Faibussowitsch #ifndef PETSC_CUPM_THRUST_UTILITY_HPP 20e6b6b59SJacob Faibussowitsch #define PETSC_CUPM_THRUST_UTILITY_HPP 30e6b6b59SJacob Faibussowitsch 40e6b6b59SJacob Faibussowitsch #if defined(__cplusplus) 5f3146f24SJacob Faibussowitsch #include <petsclog.h> // PetscLogGpuTimeBegin()/End() 6f3146f24SJacob Faibussowitsch #include <petscerror.h> // SETERRQ() 7f3146f24SJacob Faibussowitsch #include <petscdevice_cupm.h> // PETSC_USING_NVCC 8f3146f24SJacob Faibussowitsch 9*ebc16b7dSJacob Faibussowitsch #include <thrust/version.h> // THRUST_VERSION 10f3146f24SJacob Faibussowitsch #include <thrust/system_error.h> // thrust::system_error 11f3146f24SJacob Faibussowitsch #include <thrust/execution_policy.h> // thrust::cuda/hip::par 120e6b6b59SJacob Faibussowitsch 13d71ae5a4SJacob Faibussowitsch namespace Petsc 14d71ae5a4SJacob Faibussowitsch { 150e6b6b59SJacob Faibussowitsch 16d71ae5a4SJacob Faibussowitsch namespace device 17d71ae5a4SJacob Faibussowitsch { 180e6b6b59SJacob Faibussowitsch 19d71ae5a4SJacob Faibussowitsch namespace cupm 20d71ae5a4SJacob Faibussowitsch { 210e6b6b59SJacob Faibussowitsch 220e6b6b59SJacob Faibussowitsch #if PetscDefined(USING_NVCC) 230e6b6b59SJacob Faibussowitsch #if !defined(THRUST_VERSION) 240e6b6b59SJacob Faibussowitsch #error "THRUST_VERSION not defined!" 250e6b6b59SJacob Faibussowitsch #endif 26*ebc16b7dSJacob Faibussowitsch #if THRUST_VERSION >= 101600 27*ebc16b7dSJacob Faibussowitsch #define PETSC_THRUST_HAS_ASYNC 1 28f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::cuda::par_nosync.on(s), __VA_ARGS__) 290e6b6b59SJacob Faibussowitsch #else 30f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::cuda::par.on(s), __VA_ARGS__) 310e6b6b59SJacob Faibussowitsch #endif 320e6b6b59SJacob Faibussowitsch #elif PetscDefined(USING_HCC) // rocThrust has no par_nosync 33f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::hip::par.on(s), __VA_ARGS__) 340e6b6b59SJacob Faibussowitsch #else 35f3146f24SJacob Faibussowitsch #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(__VA_ARGS__) 360e6b6b59SJacob Faibussowitsch #endif 370e6b6b59SJacob Faibussowitsch 38*ebc16b7dSJacob Faibussowitsch #ifndef PETSC_THRUST_HAS_ASYNC 39*ebc16b7dSJacob Faibussowitsch #define PETSC_THRUST_HAS_ASYNC 0 40*ebc16b7dSJacob Faibussowitsch #endif 41*ebc16b7dSJacob Faibussowitsch 42d71ae5a4SJacob Faibussowitsch namespace detail 43d71ae5a4SJacob Faibussowitsch { 440e6b6b59SJacob Faibussowitsch 450e6b6b59SJacob Faibussowitsch struct PetscLogGpuTimer { 46*ebc16b7dSJacob Faibussowitsch PetscLogGpuTimer() noexcept 47*ebc16b7dSJacob Faibussowitsch { 48*ebc16b7dSJacob Faibussowitsch PetscFunctionBegin; 49*ebc16b7dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, PetscLogGpuTimeBegin()); 50*ebc16b7dSJacob Faibussowitsch PetscFunctionReturnVoid(); 51*ebc16b7dSJacob Faibussowitsch } 52*ebc16b7dSJacob Faibussowitsch 53*ebc16b7dSJacob Faibussowitsch ~PetscLogGpuTimer() noexcept 54*ebc16b7dSJacob Faibussowitsch { 55*ebc16b7dSJacob Faibussowitsch PetscFunctionBegin; 56*ebc16b7dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF, PetscLogGpuTimeEnd()); 57*ebc16b7dSJacob Faibussowitsch PetscFunctionReturnVoid(); 58*ebc16b7dSJacob Faibussowitsch } 590e6b6b59SJacob Faibussowitsch }; 600e6b6b59SJacob Faibussowitsch 610e6b6b59SJacob Faibussowitsch } // namespace detail 620e6b6b59SJacob Faibussowitsch 630e6b6b59SJacob Faibussowitsch #define THRUST_CALL(...) \ 640e6b6b59SJacob Faibussowitsch [&] { \ 65f3146f24SJacob Faibussowitsch const auto timer = ::Petsc::device::cupm::detail::PetscLogGpuTimer{}; \ 66f3146f24SJacob Faibussowitsch return PETSC_THRUST_CALL_PAR_ON(__VA_ARGS__); \ 670e6b6b59SJacob Faibussowitsch }() 680e6b6b59SJacob Faibussowitsch 690e6b6b59SJacob Faibussowitsch #define PetscCallThrust(...) \ 700e6b6b59SJacob Faibussowitsch do { \ 710e6b6b59SJacob Faibussowitsch try { \ 72f3146f24SJacob Faibussowitsch { \ 730e6b6b59SJacob Faibussowitsch __VA_ARGS__; \ 74f3146f24SJacob Faibussowitsch } \ 75d71ae5a4SJacob Faibussowitsch } catch (const thrust::system_error &ex) { \ 76d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Thrust error: %s", ex.what()); \ 77d71ae5a4SJacob Faibussowitsch } \ 780e6b6b59SJacob Faibussowitsch } while (0) 790e6b6b59SJacob Faibussowitsch 800e6b6b59SJacob Faibussowitsch } // namespace cupm 810e6b6b59SJacob Faibussowitsch 820e6b6b59SJacob Faibussowitsch } // namespace device 830e6b6b59SJacob Faibussowitsch 840e6b6b59SJacob Faibussowitsch } // namespace Petsc 850e6b6b59SJacob Faibussowitsch 860e6b6b59SJacob Faibussowitsch #endif // __cplusplus 870e6b6b59SJacob Faibussowitsch 880e6b6b59SJacob Faibussowitsch #endif // PETSC_CUPM_THRUST_UTILITY_HPP 89