xref: /petsc/include/petscdevicetypes.h (revision edd03b47ed9fa9b7ef9dd67df42d5194593a501d)
107e4ef11SJacob Faibussowitsch #ifndef PETSCDEVICETYPES_H
2030f984aSJacob Faibussowitsch #define PETSCDEVICETYPES_H
3030f984aSJacob Faibussowitsch 
40e6b6b59SJacob Faibussowitsch #include <petscsys.h> /*I <petscdevicetypes.h> I*/
50e6b6b59SJacob Faibussowitsch 
60e6b6b59SJacob Faibussowitsch // Some overzealous older gcc versions warn that the comparisons below are always true. Neat
70e6b6b59SJacob Faibussowitsch // that it can detect this, but the tautology *is* the point of the static_assert()!
80e6b6b59SJacob Faibussowitsch #if defined(__GNUC__) && __GNUC__ >= 6 && !PetscDefined(HAVE_WINDOWS_COMPILERS)
90e6b6b59SJacob Faibussowitsch   #define PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING 1
100e6b6b59SJacob Faibussowitsch #else
110e6b6b59SJacob Faibussowitsch   #define PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING 0
120e6b6b59SJacob Faibussowitsch #endif
13030f984aSJacob Faibussowitsch 
14ac09b921SBarry Smith /* SUBMANSEC = Sys */
15ac09b921SBarry Smith 
16030f984aSJacob Faibussowitsch /*E
17030f984aSJacob Faibussowitsch   PetscMemType - Memory type of a pointer
18030f984aSJacob Faibussowitsch 
1916a05f60SBarry Smith   Level: intermediate
20fe0d65a2SJacob Faibussowitsch 
213214990dSStefano Zampini   Notes:
2287497f52SBarry Smith   `PETSC_MEMTYPE_KOKKOS` depends on the Kokkos backend configuration
233214990dSStefano Zampini 
240e6b6b59SJacob Faibussowitsch   Developer Notes:
250e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemTypeToString()`) to convert to string representation so
260e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
270e6b6b59SJacob Faibussowitsch 
2816a05f60SBarry Smith   Developer Note:
2916a05f60SBarry Smith   Encoding of the bitmask in binary: xxxxyyyz
3016a05f60SBarry Smith .vb
3116a05f60SBarry Smith  z = 0                - Host memory
3216a05f60SBarry Smith  z = 1                - Device memory
3316a05f60SBarry Smith  yyy = 000            - CUDA-related memory
3416a05f60SBarry Smith  yyy = 001            - HIP-related memory
3516a05f60SBarry Smith  yyy = 010            - SYCL-related memory
3616a05f60SBarry Smith  xxxxyyy1 = 0000,0001 - CUDA memory
3716a05f60SBarry Smith  xxxxyyy1 = 0001,0001 - CUDA NVSHMEM memory
3816a05f60SBarry Smith  xxxxyyy1 = 0000,0011 - HIP memory
3916a05f60SBarry Smith  xxxxyyy1 = 0000,0101 - SYCL memory
4016a05f60SBarry Smith .ve
4116a05f60SBarry Smith 
4216a05f60SBarry Smith   Other types of memory, e.g., CUDA managed memory, can be added when needed.
4316a05f60SBarry Smith 
440e6b6b59SJacob Faibussowitsch .seealso: `PetscMemTypeToString()`, `VecGetArrayAndMemType()`,
450e6b6b59SJacob Faibussowitsch `PetscSFBcastWithMemTypeBegin()`, `PetscSFReduceWithMemTypeBegin()`
46030f984aSJacob Faibussowitsch E*/
47fe0d65a2SJacob Faibussowitsch typedef enum {
48fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_HOST    = 0,
49fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_DEVICE  = 0x01,
50fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_CUDA    = 0x01,
51fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_NVSHMEM = 0x11,
52a2158755SJunchao Zhang   PETSC_MEMTYPE_HIP     = 0x03,
533214990dSStefano Zampini   PETSC_MEMTYPE_SYCL    = 0x05,
54fe0d65a2SJacob Faibussowitsch } PetscMemType;
55c0288c05SSatish Balay #if PetscDefined(HAVE_CUDA)
56c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_CUDA
57c0288c05SSatish Balay #elif PetscDefined(HAVE_HIP)
58c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_HIP
59c0288c05SSatish Balay #elif PetscDefined(HAVE_SYCL)
60c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_SYCL
61c0288c05SSatish Balay #else
62c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_HOST
63c0288c05SSatish Balay #endif
64030f984aSJacob Faibussowitsch 
65030f984aSJacob Faibussowitsch #define PetscMemTypeHost(m)    (((m)&0x1) == PETSC_MEMTYPE_HOST)
66030f984aSJacob Faibussowitsch #define PetscMemTypeDevice(m)  (((m)&0x1) == PETSC_MEMTYPE_DEVICE)
67030f984aSJacob Faibussowitsch #define PetscMemTypeCUDA(m)    (((m)&0xF) == PETSC_MEMTYPE_CUDA)
68030f984aSJacob Faibussowitsch #define PetscMemTypeHIP(m)     (((m)&0xF) == PETSC_MEMTYPE_HIP)
69a2158755SJunchao Zhang #define PetscMemTypeSYCL(m)    (((m)&0xF) == PETSC_MEMTYPE_SYCL)
70030f984aSJacob Faibussowitsch #define PetscMemTypeNVSHMEM(m) ((m) == PETSC_MEMTYPE_NVSHMEM)
71030f984aSJacob Faibussowitsch 
720e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
730e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
740e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
750e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
760e6b6b59SJacob Faibussowitsch   #endif
770e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeHost(PETSC_MEMTYPE_HOST), "");
780e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_DEVICE), "");
790e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_CUDA), "");
800e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_HIP), "");
810e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_SYCL), "");
820e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_NVSHMEM), "");
830e6b6b59SJacob Faibussowitsch 
840e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeDevice(PETSC_MEMTYPE_HOST), "");
850e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_DEVICE), "");
860e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_CUDA), "");
870e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_HIP), "");
880e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_SYCL), "");
890e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_NVSHMEM), "");
900e6b6b59SJacob Faibussowitsch 
910e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_CUDA), "");
920e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_NVSHMEM), "");
930e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
940e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
950e6b6b59SJacob Faibussowitsch   #endif
960e6b6b59SJacob Faibussowitsch #endif // __cplusplus
970e6b6b59SJacob Faibussowitsch 
98d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemTypeToString(PetscMemType mtype)
99d71ae5a4SJacob Faibussowitsch {
1000e6b6b59SJacob Faibussowitsch #ifdef __cplusplus
1010e6b6b59SJacob Faibussowitsch   static_assert(PETSC_MEMTYPE_CUDA == PETSC_MEMTYPE_DEVICE, "");
1020e6b6b59SJacob Faibussowitsch #endif
1030e6b6b59SJacob Faibussowitsch #define PETSC_CASE_NAME(v) \
104d71ae5a4SJacob Faibussowitsch case v: \
105d71ae5a4SJacob Faibussowitsch   return PetscStringize(v)
1060e6b6b59SJacob Faibussowitsch 
1070e6b6b59SJacob Faibussowitsch   switch (mtype) {
1080e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HOST);
1090e6b6b59SJacob Faibussowitsch     /* PETSC_CASE_NAME(PETSC_MEMTYPE_DEVICE); same as PETSC_MEMTYPE_CUDA */
1100e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_CUDA);
1110e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_NVSHMEM);
1120e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HIP);
1130e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_SYCL);
1140e6b6b59SJacob Faibussowitsch   }
1150e6b6b59SJacob Faibussowitsch   PetscUnreachable();
1160e6b6b59SJacob Faibussowitsch   return "invalid";
1170e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_NAME
1180e6b6b59SJacob Faibussowitsch }
1190e6b6b59SJacob Faibussowitsch 
120*edd03b47SJacob Faibussowitsch #define PETSC_OFFLOAD_VECKOKKOS_DEPRECATED PETSC_OFFLOAD_VECKOKKOS PETSC_DEPRECATED_ENUM(3, 17, 0, "PETSC_OFFLOAD_KOKKOS", )
1210e6b6b59SJacob Faibussowitsch 
122030f984aSJacob Faibussowitsch /*E
123030f984aSJacob Faibussowitsch   PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data
124030f984aSJacob Faibussowitsch 
12516a05f60SBarry Smith   Values:
12616a05f60SBarry Smith + `PETSC_OFFLOAD_UNALLOCATED` - no memory contains valid matrix entries; NEVER used for vectors
12716a05f60SBarry Smith . `PETSC_OFFLOAD_GPU`         - GPU has valid vector/matrix entries
12816a05f60SBarry Smith . `PETSC_OFFLOAD_CPU`         - CPU has valid vector/matrix entries
12916a05f60SBarry Smith . `PETSC_OFFLOAD_BOTH`        - Both GPU and CPU have valid vector/matrix entries and they match
13016a05f60SBarry Smith - `PETSC_OFFLOAD_KOKKOS`      - Reserved for Kokkos matrix and vector. It means the offload is managed by Kokkos, thus this flag itself cannot tell you where the valid data is.
13116a05f60SBarry Smith 
13216a05f60SBarry Smith   Level: developer
133030f984aSJacob Faibussowitsch 
1340e6b6b59SJacob Faibussowitsch   Developer Notes:
1350e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscOffloadMaskToString()`) to convert to string representation so
1360e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
1370e6b6b59SJacob Faibussowitsch 
1380e6b6b59SJacob Faibussowitsch .seealso: `PetscOffloadMaskToString()`, `PetscOffloadMaskToMemType()`, `PetscOffloadMaskToDeviceCopyMode()`
139030f984aSJacob Faibussowitsch E*/
140fe0d65a2SJacob Faibussowitsch typedef enum {
141fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_UNALLOCATED          = 0x0,
142fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_CPU                  = 0x1,
143fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_GPU                  = 0x2,
144fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_BOTH                 = 0x3,
145d795ed5eSJunchao Zhang   PETSC_OFFLOAD_VECKOKKOS_DEPRECATED = 0x100,
146ae76731bSJunchao Zhang   PETSC_OFFLOAD_KOKKOS               = 0x100
147fe0d65a2SJacob Faibussowitsch } PetscOffloadMask;
148030f984aSJacob Faibussowitsch 
1490e6b6b59SJacob Faibussowitsch #define PetscOffloadUnallocated(m) ((m) == PETSC_OFFLOAD_UNALLOCATED)
1500e6b6b59SJacob Faibussowitsch #define PetscOffloadHost(m)        (((m)&PETSC_OFFLOAD_CPU) == PETSC_OFFLOAD_CPU)
1510e6b6b59SJacob Faibussowitsch #define PetscOffloadDevice(m)      (((m)&PETSC_OFFLOAD_GPU) == PETSC_OFFLOAD_GPU)
152a8e904f6SJacob Faibussowitsch #define PetscOffloadBoth(m)        ((m) == PETSC_OFFLOAD_BOTH)
1530e6b6b59SJacob Faibussowitsch 
1540e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
1550e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
1560e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
1570e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
1580e6b6b59SJacob Faibussowitsch   #endif
1590e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_UNALLOCATED), "");
1600e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadHost(PETSC_OFFLOAD_BOTH), "");
1610e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_GPU), "");
1620e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadHost(PETSC_OFFLOAD_BOTH), "");
1630e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_KOKKOS), "");
1640e6b6b59SJacob Faibussowitsch 
1650e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_UNALLOCATED), "");
1660e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_CPU), "");
1670e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadDevice(PETSC_OFFLOAD_GPU), "");
1680e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadDevice(PETSC_OFFLOAD_BOTH), "");
1690e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_KOKKOS), "");
170a8e904f6SJacob Faibussowitsch 
171a8e904f6SJacob Faibussowitsch static_assert(PetscOffloadBoth(PETSC_OFFLOAD_BOTH), "");
172a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_CPU), "");
173a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_GPU), "");
174a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_GPU), "");
175a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_KOKKOS), "");
1760e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
1770e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
1780e6b6b59SJacob Faibussowitsch   #endif
1790e6b6b59SJacob Faibussowitsch #endif // __cplusplus
1800e6b6b59SJacob Faibussowitsch 
181d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscOffloadMaskToString(PetscOffloadMask mask)
182d71ae5a4SJacob Faibussowitsch {
1830e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
184d71ae5a4SJacob Faibussowitsch case v: \
185d71ae5a4SJacob Faibussowitsch   return PetscStringize(v)
1860e6b6b59SJacob Faibussowitsch 
1870e6b6b59SJacob Faibussowitsch   switch (mask) {
1880e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_UNALLOCATED);
1890e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_CPU);
1900e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_GPU);
1910e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_BOTH);
1920e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_KOKKOS);
1930e6b6b59SJacob Faibussowitsch   }
1940e6b6b59SJacob Faibussowitsch   PetscUnreachable();
1950e6b6b59SJacob Faibussowitsch   return "invalid";
1960e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
1970e6b6b59SJacob Faibussowitsch }
1980e6b6b59SJacob Faibussowitsch 
199d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscMemType PetscOffloadMaskToMemType(PetscOffloadMask mask)
200d71ae5a4SJacob Faibussowitsch {
2010e6b6b59SJacob Faibussowitsch   switch (mask) {
2020e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_UNALLOCATED:
203d71ae5a4SJacob Faibussowitsch   case PETSC_OFFLOAD_CPU:
204d71ae5a4SJacob Faibussowitsch     return PETSC_MEMTYPE_HOST;
2050e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_GPU:
206d71ae5a4SJacob Faibussowitsch   case PETSC_OFFLOAD_BOTH:
207d71ae5a4SJacob Faibussowitsch     return PETSC_MEMTYPE_DEVICE;
208d71ae5a4SJacob Faibussowitsch   case PETSC_OFFLOAD_KOKKOS:
209d71ae5a4SJacob Faibussowitsch     return PETSC_MEMTYPE_KOKKOS;
2100e6b6b59SJacob Faibussowitsch   }
2110e6b6b59SJacob Faibussowitsch   PetscUnreachable();
2120e6b6b59SJacob Faibussowitsch   return PETSC_MEMTYPE_HOST;
2130e6b6b59SJacob Faibussowitsch }
2140e6b6b59SJacob Faibussowitsch 
215030f984aSJacob Faibussowitsch /*E
21687497f52SBarry Smith   PetscDeviceInitType - Initialization strategy for `PetscDevice`
217a4af0ceeSJacob Faibussowitsch 
21816a05f60SBarry Smith   Values:
21916a05f60SBarry Smith + `PETSC_DEVICE_INIT_NONE`  - PetscDevice is never initialized
22016a05f60SBarry Smith . `PETSC_DEVICE_INIT_LAZY`  - PetscDevice is initialized on demand
22116a05f60SBarry Smith - `PETSC_DEVICE_INIT_EAGER` - PetscDevice is initialized as soon as possible
22216a05f60SBarry Smith 
22316a05f60SBarry Smith   Level: beginner
224a4af0ceeSJacob Faibussowitsch 
225a4af0ceeSJacob Faibussowitsch   Notes:
2260e6b6b59SJacob Faibussowitsch   `PETSC_DEVICE_INIT_NONE` implies that any initialization of `PetscDevice` is disallowed and
227a4af0ceeSJacob Faibussowitsch   doing so results in an error. Useful to ensure that no accelerator is used in a program.
228a4af0ceeSJacob Faibussowitsch 
2290e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceType`, `PetscDeviceInitialize()`,
2300e6b6b59SJacob Faibussowitsch `PetscDeviceInitialized()`, `PetscDeviceCreate()`
231a4af0ceeSJacob Faibussowitsch E*/
232a4af0ceeSJacob Faibussowitsch typedef enum {
233a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_NONE,
234a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_LAZY,
235a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_EAGER
236a4af0ceeSJacob Faibussowitsch } PetscDeviceInitType;
237a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceInitTypes[];
238a4af0ceeSJacob Faibussowitsch 
239a4af0ceeSJacob Faibussowitsch /*E
240a4af0ceeSJacob Faibussowitsch   PetscDeviceType - Kind of accelerator device backend
241030f984aSJacob Faibussowitsch 
24216a05f60SBarry Smith   Values:
24316a05f60SBarry Smith + `PETSC_DEVICE_HOST` - Host, no accelerator backend found
24416a05f60SBarry Smith . `PETSC_DEVICE_CUDA` - CUDA enabled GPU
24516a05f60SBarry Smith . `PETSC_DEVICE_HIP`  - ROCM/HIP enabled GPU
24616a05f60SBarry Smith . `PETSC_DEVICE_SYCL` - SYCL enabled device
24716a05f60SBarry Smith - `PETSC_DEVICE_MAX`  - Always 1 greater than the largest valid `PetscDeviceType`, invalid type, do not use
24816a05f60SBarry Smith 
24916a05f60SBarry Smith   Level: beginner
250030f984aSJacob Faibussowitsch 
251030f984aSJacob Faibussowitsch   Notes:
2520e6b6b59SJacob Faibussowitsch   One can also use the `PETSC_DEVICE_DEFAULT()` routine to get the current default `PetscDeviceType`.
253030f984aSJacob Faibussowitsch 
2540e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceInitType`, `PetscDeviceCreate()`, `PETSC_DEVICE_DEFAULT()`
255030f984aSJacob Faibussowitsch E*/
256030f984aSJacob Faibussowitsch typedef enum {
2570e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_HOST,
258a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_CUDA,
259a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_HIP,
260a2158755SJunchao Zhang   PETSC_DEVICE_SYCL,
261a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_MAX
262a4af0ceeSJacob Faibussowitsch } PetscDeviceType;
263a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceTypes[];
264030f984aSJacob Faibussowitsch 
265a16fd2c9SJacob Faibussowitsch /*E
266a16fd2c9SJacob Faibussowitsch   PetscDeviceAttribute - Attribute detailing a property or feature of a `PetscDevice`
267a16fd2c9SJacob Faibussowitsch 
26816a05f60SBarry Smith   Values:
26916a05f60SBarry Smith + `PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK` - The maximum amount of shared memory per block in a device kernel
27016a05f60SBarry Smith - `PETSC_DEVICE_ATTR_MAX`                         - Invalid attribute, do not use
271a16fd2c9SJacob Faibussowitsch 
272a16fd2c9SJacob Faibussowitsch   Level: beginner
273a16fd2c9SJacob Faibussowitsch 
274a16fd2c9SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceGetAttribute()`
275a16fd2c9SJacob Faibussowitsch E*/
276a16fd2c9SJacob Faibussowitsch typedef enum {
277a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK,
278a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_MAX
279a16fd2c9SJacob Faibussowitsch } PetscDeviceAttribute;
280a16fd2c9SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceAttributes[];
281a16fd2c9SJacob Faibussowitsch 
282030f984aSJacob Faibussowitsch /*S
28387497f52SBarry Smith   PetscDevice - Object to manage an accelerator "device" (usually a GPU)
284030f984aSJacob Faibussowitsch 
28516a05f60SBarry Smith   Level: beginner
28616a05f60SBarry Smith 
2870e6b6b59SJacob Faibussowitsch   Notes:
2880e6b6b59SJacob Faibussowitsch   This object is used to house configuration and state of a device, but does not offer any
2890e6b6b59SJacob Faibussowitsch   ability to interact with or drive device computation. This functionality is facilitated
2900e6b6b59SJacob Faibussowitsch   instead by the `PetscDeviceContext` object.
291030f984aSJacob Faibussowitsch 
2920e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceType`, `PetscDeviceInitType`, `PetscDeviceCreate()`,
2930e6b6b59SJacob Faibussowitsch `PetscDeviceConfigure()`, `PetscDeviceDestroy()`, `PetscDeviceContext`,
2940e6b6b59SJacob Faibussowitsch `PetscDeviceContextSetDevice()`, `PetscDeviceContextGetDevice()`, `PetscDeviceGetAttribute()`
295030f984aSJacob Faibussowitsch S*/
296030f984aSJacob Faibussowitsch typedef struct _n_PetscDevice *PetscDevice;
297030f984aSJacob Faibussowitsch 
298030f984aSJacob Faibussowitsch /*E
2990e6b6b59SJacob Faibussowitsch   PetscStreamType - Stream blocking mode, indicates how a stream implementation will interact
30016a05f60SBarry Smith   with the default `NULL` stream, which is usually blocking.
301030f984aSJacob Faibussowitsch 
30216a05f60SBarry Smith   Values:
30316a05f60SBarry Smith + `PETSC_STREAM_GLOBAL_BLOCKING`    - Alias for `NULL` stream. Any stream of this type will block the host for all other streams to finish work before starting its operations.
30416a05f60SBarry Smith . `PETSC_STREAM_DEFAULT_BLOCKING`   - Stream will act independent of other streams, but will still be blocked by actions on the `NULL` stream.
30516a05f60SBarry Smith . `PETSC_STREAM_GLOBAL_NONBLOCKING` - Stream is truly asynchronous, and is blocked by nothing, not even the `NULL` stream.
30616a05f60SBarry Smith - `PETSC_STREAM_MAX`                - Always 1 greater than the largest `PetscStreamType`, do not use
307030f984aSJacob Faibussowitsch 
308030f984aSJacob Faibussowitsch   Level: intermediate
309030f984aSJacob Faibussowitsch 
310db781477SPatrick Sanan .seealso: `PetscDeviceContextSetStreamType()`, `PetscDeviceContextGetStreamType()`
311030f984aSJacob Faibussowitsch E*/
312030f984aSJacob Faibussowitsch typedef enum {
313a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_GLOBAL_BLOCKING,
314a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_DEFAULT_BLOCKING,
315a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_GLOBAL_NONBLOCKING,
316a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_MAX
317030f984aSJacob Faibussowitsch } PetscStreamType;
318030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscStreamTypes[];
319030f984aSJacob Faibussowitsch 
320030f984aSJacob Faibussowitsch /*E
3210e6b6b59SJacob Faibussowitsch   PetscDeviceContextJoinMode - Describes the type of join operation to perform in
3220e6b6b59SJacob Faibussowitsch   `PetscDeviceContextJoin()`
323030f984aSJacob Faibussowitsch 
32416a05f60SBarry Smith   Values:
32516a05f60SBarry Smith + `PETSC_DEVICE_CONTEXT_JOIN_DESTROY` - Destroy all incoming sub-contexts after join.
32616a05f60SBarry Smith . `PETSC_DEVICE_CONTEXT_JOIN_SYNC`    - Synchronize incoming sub-contexts after join.
32716a05f60SBarry Smith - `PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC` - Do not synchronize incoming sub-contexts after join.
328030f984aSJacob Faibussowitsch 
329030f984aSJacob Faibussowitsch   Level: beginner
330030f984aSJacob Faibussowitsch 
331db781477SPatrick Sanan .seealso: `PetscDeviceContext`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
332030f984aSJacob Faibussowitsch E*/
333030f984aSJacob Faibussowitsch typedef enum {
334030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_DESTROY,
335030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_SYNC,
336030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC
337030f984aSJacob Faibussowitsch } PetscDeviceContextJoinMode;
338030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceContextJoinModes[];
339030f984aSJacob Faibussowitsch 
340030f984aSJacob Faibussowitsch /*S
3410e6b6b59SJacob Faibussowitsch   PetscDeviceContext - Container to manage stream dependencies and the various solver handles
3420e6b6b59SJacob Faibussowitsch   for asynchronous device compute.
343030f984aSJacob Faibussowitsch 
344030f984aSJacob Faibussowitsch   Level: beginner
345030f984aSJacob Faibussowitsch 
3460e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceContextCreate()`, `PetscDeviceContextSetDevice()`,
3470e6b6b59SJacob Faibussowitsch `PetscDeviceContextDestroy()`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
348030f984aSJacob Faibussowitsch S*/
3490e6b6b59SJacob Faibussowitsch typedef struct _p_PetscDeviceContext *PetscDeviceContext;
3500e6b6b59SJacob Faibussowitsch 
3510e6b6b59SJacob Faibussowitsch /*E
35216a05f60SBarry Smith   PetscDeviceCopyMode - Describes the copy direction of a device-aware `memcpy`
3530e6b6b59SJacob Faibussowitsch 
35416a05f60SBarry Smith   Values:
35516a05f60SBarry Smith + `PETSC_DEVICE_COPY_HTOH` - Copy from host memory to host memory
35616a05f60SBarry Smith . `PETSC_DEVICE_COPY_DTOH` - Copy from device memory to host memory
35716a05f60SBarry Smith . `PETSC_DEVICE_COPY_HTOD` - Copy from host memory to device memory
35816a05f60SBarry Smith . `PETSC_DEVICE_COPY_DTOD` - Copy from device memory to device memory
35916a05f60SBarry Smith - `PETSC_DEVICE_COPY_AUTO` - Infer the copy direction from the pointers
3600e6b6b59SJacob Faibussowitsch 
3610e6b6b59SJacob Faibussowitsch   Level: beginner
3620e6b6b59SJacob Faibussowitsch 
3630e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceArrayCopy()`, `PetscDeviceMemcpy()`
3640e6b6b59SJacob Faibussowitsch E*/
3650e6b6b59SJacob Faibussowitsch typedef enum {
3660e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOH,
3670e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOH,
3680e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOD,
3690e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOD,
3700e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_AUTO,
3710e6b6b59SJacob Faibussowitsch } PetscDeviceCopyMode;
3720e6b6b59SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceCopyModes[];
3730e6b6b59SJacob Faibussowitsch 
374d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PetscDeviceCopyMode PetscOffloadMaskToDeviceCopyMode(PetscOffloadMask dest, PetscOffloadMask src)
375d71ae5a4SJacob Faibussowitsch {
3760e6b6b59SJacob Faibussowitsch   PetscDeviceCopyMode mode;
3770e6b6b59SJacob Faibussowitsch 
3780e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
3790e6b6b59SJacob Faibussowitsch   PetscAssertAbort(dest != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy to unallocated");
3800e6b6b59SJacob Faibussowitsch   PetscAssertAbort(src != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy from unallocated");
3810e6b6b59SJacob Faibussowitsch 
3820e6b6b59SJacob Faibussowitsch   if (PetscOffloadDevice(dest)) {
3830e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOD : PETSC_DEVICE_COPY_DTOD;
3840e6b6b59SJacob Faibussowitsch   } else {
3850e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
3860e6b6b59SJacob Faibussowitsch   }
3870e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(mode);
3880e6b6b59SJacob Faibussowitsch }
3890e6b6b59SJacob Faibussowitsch 
390d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscDeviceCopyMode PetscMemTypeToDeviceCopyMode(PetscMemType dest, PetscMemType src)
391d71ae5a4SJacob Faibussowitsch {
3920e6b6b59SJacob Faibussowitsch   if (PetscMemTypeHost(dest)) {
3930e6b6b59SJacob Faibussowitsch     return PetscMemTypeHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
3940e6b6b59SJacob Faibussowitsch   } else {
3950e6b6b59SJacob Faibussowitsch     return PetscMemTypeDevice(src) ? PETSC_DEVICE_COPY_DTOD : PETSC_DEVICE_COPY_HTOD;
3960e6b6b59SJacob Faibussowitsch   }
3970e6b6b59SJacob Faibussowitsch }
3980e6b6b59SJacob Faibussowitsch 
3990e6b6b59SJacob Faibussowitsch /*E
4000e6b6b59SJacob Faibussowitsch   PetscMemoryAccessMode - Describes the intended usage of a memory region
4010e6b6b59SJacob Faibussowitsch 
40216a05f60SBarry Smith   Values:
40316a05f60SBarry Smith + `PETSC_MEMORY_ACCESS_READ`       - Read only
40416a05f60SBarry Smith . `PETSC_MEMORY_ACCESS_WRITE`      - Write only
40516a05f60SBarry Smith - `PETSC_MEMORY_ACCESS_READ_WRITE` - Read and write
40616a05f60SBarry Smith 
40716a05f60SBarry Smith   Level: beginner
4080e6b6b59SJacob Faibussowitsch 
4090e6b6b59SJacob Faibussowitsch   Notes:
4100e6b6b59SJacob Faibussowitsch   This `enum` is a bitmask with the following encoding (assuming 2 bit)\:
4110e6b6b59SJacob Faibussowitsch 
4120e6b6b59SJacob Faibussowitsch .vb
4130e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0b01
4140e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0b10
4150e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0b11
4160e6b6b59SJacob Faibussowitsch 
4170e6b6b59SJacob Faibussowitsch   // consequently
4180e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE = PETSC_MEMORY_ACCESS_READ_WRITE
4190e6b6b59SJacob Faibussowitsch .ve
4200e6b6b59SJacob Faibussowitsch 
421aaa8cc7dSPierre Jolivet   The following convenience macros are also provided\:
4220e6b6b59SJacob Faibussowitsch 
42316a05f60SBarry Smith + `PetscMemoryAccessRead(mode)` - `true` if `mode` is any kind of read, `false` otherwise
42416a05f60SBarry Smith - `PetscMemoryAccessWrite(mode)` - `true` if `mode` is any kind of write, `false` otherwise
4250e6b6b59SJacob Faibussowitsch 
4260e6b6b59SJacob Faibussowitsch   Developer Notes:
4270e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemoryAccessModeToString()`) to convert values to string
4280e6b6b59SJacob Faibussowitsch   representation, so cannot be used in `PetscOptionsEnum()`.
4290e6b6b59SJacob Faibussowitsch 
4300e6b6b59SJacob Faibussowitsch .seealso: `PetscMemoryAccessModeToString()`, `PetscDevice`, `PetscDeviceContext`
4310e6b6b59SJacob Faibussowitsch E*/
4320e6b6b59SJacob Faibussowitsch typedef enum {
4330e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0x1, // 01
4340e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0x2, // 10
4350e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0x3, // 11
4360e6b6b59SJacob Faibussowitsch } PetscMemoryAccessMode;
4370e6b6b59SJacob Faibussowitsch 
4380e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessRead(m)  (((m)&PETSC_MEMORY_ACCESS_READ) == PETSC_MEMORY_ACCESS_READ)
4390e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessWrite(m) (((m)&PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_WRITE)
4400e6b6b59SJacob Faibussowitsch 
4410e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
4420e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4430e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
4440e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
4450e6b6b59SJacob Faibussowitsch   #endif
4460e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ), "");
4470e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ_WRITE), "");
4480e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_WRITE), "");
4490e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_WRITE), "");
4500e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ_WRITE), "");
4510e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ), "");
4520e6b6b59SJacob Faibussowitsch static_assert((PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_READ_WRITE, "");
4530e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4540e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
4550e6b6b59SJacob Faibussowitsch   #endif
4560e6b6b59SJacob Faibussowitsch #endif
4570e6b6b59SJacob Faibussowitsch 
458d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemoryAccessModeToString(PetscMemoryAccessMode mode)
459d71ae5a4SJacob Faibussowitsch {
4600e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
461d71ae5a4SJacob Faibussowitsch case v: \
462d71ae5a4SJacob Faibussowitsch   return PetscStringize(v)
4630e6b6b59SJacob Faibussowitsch 
4640e6b6b59SJacob Faibussowitsch   switch (mode) {
4650e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ);
4660e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_WRITE);
4670e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ_WRITE);
4680e6b6b59SJacob Faibussowitsch   }
4690e6b6b59SJacob Faibussowitsch   PetscUnreachable();
4700e6b6b59SJacob Faibussowitsch   return "invalid";
4710e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
4720e6b6b59SJacob Faibussowitsch }
4730e6b6b59SJacob Faibussowitsch 
4740e6b6b59SJacob Faibussowitsch #undef PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4750e6b6b59SJacob Faibussowitsch 
476030f984aSJacob Faibussowitsch #endif /* PETSCDEVICETYPES_H */
477