xref: /petsc/src/sys/objects/device/impls/cupm/cupmthrustutility.hpp (revision 9d47de495d3c23378050c1b4a410c12a375cb6c6)
1a4963045SJacob Faibussowitsch #pragma once
20e6b6b59SJacob Faibussowitsch 
3f3146f24SJacob Faibussowitsch #include <petsclog.h>         // PetscLogGpuTimeBegin()/End()
47233ce55SJed Brown #include <petscsys.h>         // SETERRQ()
5f3146f24SJacob Faibussowitsch #include <petscdevice_cupm.h> // PETSC_USING_NVCC
6f3146f24SJacob Faibussowitsch 
7ebc16b7dSJacob Faibussowitsch #include <thrust/version.h>          // THRUST_VERSION
8f3146f24SJacob Faibussowitsch #include <thrust/system_error.h>     // thrust::system_error
9f3146f24SJacob Faibussowitsch #include <thrust/execution_policy.h> // thrust::cuda/hip::par
100e6b6b59SJacob Faibussowitsch 
11d71ae5a4SJacob Faibussowitsch namespace Petsc
12d71ae5a4SJacob Faibussowitsch {
130e6b6b59SJacob Faibussowitsch 
14d71ae5a4SJacob Faibussowitsch namespace device
15d71ae5a4SJacob Faibussowitsch {
160e6b6b59SJacob Faibussowitsch 
17d71ae5a4SJacob Faibussowitsch namespace cupm
18d71ae5a4SJacob Faibussowitsch {
190e6b6b59SJacob Faibussowitsch 
200e6b6b59SJacob Faibussowitsch #if PetscDefined(USING_NVCC)
210e6b6b59SJacob Faibussowitsch   #if !defined(THRUST_VERSION)
220e6b6b59SJacob Faibussowitsch     #error "THRUST_VERSION not defined!"
230e6b6b59SJacob Faibussowitsch   #endif
24ebc16b7dSJacob Faibussowitsch   #if THRUST_VERSION >= 101600
25ebc16b7dSJacob Faibussowitsch     #define PETSC_THRUST_HAS_ASYNC                 1
26f3146f24SJacob Faibussowitsch     #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::cuda::par_nosync.on(s), __VA_ARGS__)
270e6b6b59SJacob Faibussowitsch   #else
28f3146f24SJacob Faibussowitsch     #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::cuda::par.on(s), __VA_ARGS__)
290e6b6b59SJacob Faibussowitsch   #endif
303853def2SToby Isaac #elif PetscDefined(USING_HCC)
313853def2SToby Isaac   #if !defined(THRUST_VERSION)
323853def2SToby Isaac     #error "THRUST_VERSION not defined!"
333853def2SToby Isaac   #endif
343853def2SToby Isaac   #if THRUST_VERSION >= 101600
353853def2SToby Isaac     #define PETSC_THRUST_HAS_ASYNC                 1
363853def2SToby Isaac     #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::hip::par_nosync.on(s), __VA_ARGS__)
373853def2SToby Isaac   #else
38f3146f24SJacob Faibussowitsch     #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(thrust::hip::par.on(s), __VA_ARGS__)
393853def2SToby Isaac   #endif
400e6b6b59SJacob Faibussowitsch #else
41f3146f24SJacob Faibussowitsch   #define PETSC_THRUST_CALL_PAR_ON(func, s, ...) func(__VA_ARGS__)
420e6b6b59SJacob Faibussowitsch #endif
430e6b6b59SJacob Faibussowitsch 
44*beceaeb6SBarry Smith #if !defined(PETSC_THRUST_HAS_ASYNC)
45ebc16b7dSJacob Faibussowitsch   #define PETSC_THRUST_HAS_ASYNC 0
46ebc16b7dSJacob Faibussowitsch #endif
47ebc16b7dSJacob Faibussowitsch 
48d71ae5a4SJacob Faibussowitsch namespace detail
49d71ae5a4SJacob Faibussowitsch {
500e6b6b59SJacob Faibussowitsch 
510e6b6b59SJacob Faibussowitsch struct PetscLogGpuTimer {
PetscLogGpuTimerPetsc::device::cupm::detail::PetscLogGpuTimer52ebc16b7dSJacob Faibussowitsch   PetscLogGpuTimer() noexcept
53ebc16b7dSJacob Faibussowitsch   {
54ebc16b7dSJacob Faibussowitsch     PetscFunctionBegin;
55ebc16b7dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscLogGpuTimeBegin());
56ebc16b7dSJacob Faibussowitsch     PetscFunctionReturnVoid();
57ebc16b7dSJacob Faibussowitsch   }
58ebc16b7dSJacob Faibussowitsch 
~PetscLogGpuTimerPetsc::device::cupm::detail::PetscLogGpuTimer59ebc16b7dSJacob Faibussowitsch   ~PetscLogGpuTimer() noexcept
60ebc16b7dSJacob Faibussowitsch   {
61ebc16b7dSJacob Faibussowitsch     PetscFunctionBegin;
62ebc16b7dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscLogGpuTimeEnd());
63ebc16b7dSJacob Faibussowitsch     PetscFunctionReturnVoid();
64ebc16b7dSJacob Faibussowitsch   }
650e6b6b59SJacob Faibussowitsch };
660e6b6b59SJacob Faibussowitsch 
670e6b6b59SJacob Faibussowitsch } // namespace detail
680e6b6b59SJacob Faibussowitsch 
690e6b6b59SJacob Faibussowitsch #define THRUST_CALL(...) \
700e6b6b59SJacob Faibussowitsch   [&] { \
71f3146f24SJacob Faibussowitsch     const auto timer = ::Petsc::device::cupm::detail::PetscLogGpuTimer{}; \
72f3146f24SJacob Faibussowitsch     return PETSC_THRUST_CALL_PAR_ON(__VA_ARGS__); \
730e6b6b59SJacob Faibussowitsch   }()
740e6b6b59SJacob Faibussowitsch 
750e6b6b59SJacob Faibussowitsch #define PetscCallThrust(...) \
760e6b6b59SJacob Faibussowitsch   do { \
770e6b6b59SJacob Faibussowitsch     try { \
78f3146f24SJacob Faibussowitsch       { \
790e6b6b59SJacob Faibussowitsch         __VA_ARGS__; \
80f3146f24SJacob Faibussowitsch       } \
81d71ae5a4SJacob Faibussowitsch     } catch (const thrust::system_error &ex) { \
82d71ae5a4SJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Thrust error: %s", ex.what()); \
83d71ae5a4SJacob Faibussowitsch     } \
840e6b6b59SJacob Faibussowitsch   } while (0)
850e6b6b59SJacob Faibussowitsch 
860e6b6b59SJacob Faibussowitsch } // namespace cupm
870e6b6b59SJacob Faibussowitsch 
880e6b6b59SJacob Faibussowitsch } // namespace device
890e6b6b59SJacob Faibussowitsch 
900e6b6b59SJacob Faibussowitsch } // namespace Petsc
91