xref: /petsc/src/sys/objects/device/impls/cupm/cupmthrustutility.hpp (revision ebc16b7d23408ea44c9a341eaacd7cbb3f4cdbc1)
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