xref: /petsc/include/petscdevicetypes.h (revision aaa8cc7d2a5c3913edcbb923e20f154fe9c4aa65)
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 
19030f984aSJacob Faibussowitsch   Developer Note:
20030f984aSJacob Faibussowitsch   Encoding of the bitmask in binary: xxxxyyyz
21fe0d65a2SJacob Faibussowitsch 
22fe0d65a2SJacob Faibussowitsch $ z = 0                - Host memory
23fe0d65a2SJacob Faibussowitsch $ z = 1                - Device memory
24fe0d65a2SJacob Faibussowitsch $ yyy = 000            - CUDA-related memory
25fe0d65a2SJacob Faibussowitsch $ yyy = 001            - HIP-related memory
26a2158755SJunchao Zhang $ yyy = 010            - SYCL-related memory
27fe0d65a2SJacob Faibussowitsch $ xxxxyyy1 = 0000,0001 - CUDA memory
28fe0d65a2SJacob Faibussowitsch $ xxxxyyy1 = 0001,0001 - CUDA NVSHMEM memory
29fe0d65a2SJacob Faibussowitsch $ xxxxyyy1 = 0000,0011 - HIP memory
30a2158755SJunchao Zhang $ xxxxyyy1 = 0000,0101 - SYCL memory
31030f984aSJacob Faibussowitsch 
32030f984aSJacob Faibussowitsch   Other types of memory, e.g., CUDA managed memory, can be added when needed.
33030f984aSJacob Faibussowitsch 
34fe0d65a2SJacob Faibussowitsch   Level: beginner
35fe0d65a2SJacob Faibussowitsch 
363214990dSStefano Zampini   Notes:
3787497f52SBarry Smith   `PETSC_MEMTYPE_KOKKOS` depends on the Kokkos backend configuration
383214990dSStefano Zampini 
390e6b6b59SJacob Faibussowitsch   Developer Notes:
400e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemTypeToString()`) to convert to string representation so
410e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
420e6b6b59SJacob Faibussowitsch 
430e6b6b59SJacob Faibussowitsch .seealso: `PetscMemTypeToString()`, `VecGetArrayAndMemType()`,
440e6b6b59SJacob Faibussowitsch `PetscSFBcastWithMemTypeBegin()`, `PetscSFReduceWithMemTypeBegin()`
45030f984aSJacob Faibussowitsch E*/
46fe0d65a2SJacob Faibussowitsch typedef enum {
47fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_HOST    = 0,
48fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_DEVICE  = 0x01,
49fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_CUDA    = 0x01,
50fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_NVSHMEM = 0x11,
51a2158755SJunchao Zhang   PETSC_MEMTYPE_HIP     = 0x03,
523214990dSStefano Zampini   PETSC_MEMTYPE_SYCL    = 0x05,
53fe0d65a2SJacob Faibussowitsch } PetscMemType;
54c0288c05SSatish Balay #if PetscDefined(HAVE_CUDA)
55c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_CUDA
56c0288c05SSatish Balay #elif PetscDefined(HAVE_HIP)
57c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_HIP
58c0288c05SSatish Balay #elif PetscDefined(HAVE_SYCL)
59c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_SYCL
60c0288c05SSatish Balay #else
61c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_HOST
62c0288c05SSatish Balay #endif
63030f984aSJacob Faibussowitsch 
64030f984aSJacob Faibussowitsch #define PetscMemTypeHost(m)    (((m)&0x1) == PETSC_MEMTYPE_HOST)
65030f984aSJacob Faibussowitsch #define PetscMemTypeDevice(m)  (((m)&0x1) == PETSC_MEMTYPE_DEVICE)
66030f984aSJacob Faibussowitsch #define PetscMemTypeCUDA(m)    (((m)&0xF) == PETSC_MEMTYPE_CUDA)
67030f984aSJacob Faibussowitsch #define PetscMemTypeHIP(m)     (((m)&0xF) == PETSC_MEMTYPE_HIP)
68a2158755SJunchao Zhang #define PetscMemTypeSYCL(m)    (((m)&0xF) == PETSC_MEMTYPE_SYCL)
69030f984aSJacob Faibussowitsch #define PetscMemTypeNVSHMEM(m) ((m) == PETSC_MEMTYPE_NVSHMEM)
70030f984aSJacob Faibussowitsch 
710e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
720e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
730e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
740e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
750e6b6b59SJacob Faibussowitsch   #endif
760e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeHost(PETSC_MEMTYPE_HOST), "");
770e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_DEVICE), "");
780e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_CUDA), "");
790e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_HIP), "");
800e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_SYCL), "");
810e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_NVSHMEM), "");
820e6b6b59SJacob Faibussowitsch 
830e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeDevice(PETSC_MEMTYPE_HOST), "");
840e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_DEVICE), "");
850e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_CUDA), "");
860e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_HIP), "");
870e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_SYCL), "");
880e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_NVSHMEM), "");
890e6b6b59SJacob Faibussowitsch 
900e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_CUDA), "");
910e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_NVSHMEM), "");
920e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
930e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
940e6b6b59SJacob Faibussowitsch   #endif
950e6b6b59SJacob Faibussowitsch #endif // __cplusplus
960e6b6b59SJacob Faibussowitsch 
97d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemTypeToString(PetscMemType mtype)
98d71ae5a4SJacob Faibussowitsch {
990e6b6b59SJacob Faibussowitsch #ifdef __cplusplus
1000e6b6b59SJacob Faibussowitsch   static_assert(PETSC_MEMTYPE_CUDA == PETSC_MEMTYPE_DEVICE, "");
1010e6b6b59SJacob Faibussowitsch #endif
1020e6b6b59SJacob Faibussowitsch #define PETSC_CASE_NAME(v) \
103d71ae5a4SJacob Faibussowitsch case v: \
104d71ae5a4SJacob Faibussowitsch   return PetscStringize(v)
1050e6b6b59SJacob Faibussowitsch 
1060e6b6b59SJacob Faibussowitsch   switch (mtype) {
1070e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HOST);
1080e6b6b59SJacob Faibussowitsch     /* PETSC_CASE_NAME(PETSC_MEMTYPE_DEVICE); same as PETSC_MEMTYPE_CUDA */
1090e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_CUDA);
1100e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_NVSHMEM);
1110e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HIP);
1120e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_SYCL);
1130e6b6b59SJacob Faibussowitsch   }
1140e6b6b59SJacob Faibussowitsch   PetscUnreachable();
1150e6b6b59SJacob Faibussowitsch   return "invalid";
1160e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_NAME
1170e6b6b59SJacob Faibussowitsch }
1180e6b6b59SJacob Faibussowitsch 
1195b5f62f7SJacob Faibussowitsch #define PETSC_OFFLOAD_VECKOKKOS_DEPRECATED PETSC_OFFLOAD_VECKOKKOS PETSC_DEPRECATED_ENUM("Use PETSC_OFFLOAD_KOKKOS (since version 3.17.0)")
1200e6b6b59SJacob Faibussowitsch 
121030f984aSJacob Faibussowitsch /*E
122030f984aSJacob Faibussowitsch   PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data
123030f984aSJacob Faibussowitsch 
124fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
125fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_GPU         - GPU has valid vector/matrix entries
126fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_CPU         - CPU has valid vector/matrix entries
127fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_BOTH        - Both GPU and CPU have valid vector/matrix entries and they match
128ae76731bSJunchao Zhang $ 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.
129030f984aSJacob Faibussowitsch 
1300e6b6b59SJacob Faibussowitsch   Developer Notes:
1310e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscOffloadMaskToString()`) to convert to string representation so
1320e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
1330e6b6b59SJacob Faibussowitsch 
134030f984aSJacob Faibussowitsch   Level: developer
1350e6b6b59SJacob Faibussowitsch 
1360e6b6b59SJacob Faibussowitsch .seealso: `PetscOffloadMaskToString()`, `PetscOffloadMaskToMemType()`, `PetscOffloadMaskToDeviceCopyMode()`
137030f984aSJacob Faibussowitsch E*/
138fe0d65a2SJacob Faibussowitsch typedef enum {
139fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_UNALLOCATED          = 0x0,
140fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_CPU                  = 0x1,
141fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_GPU                  = 0x2,
142fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_BOTH                 = 0x3,
143d795ed5eSJunchao Zhang   PETSC_OFFLOAD_VECKOKKOS_DEPRECATED = 0x100,
144ae76731bSJunchao Zhang   PETSC_OFFLOAD_KOKKOS               = 0x100
145fe0d65a2SJacob Faibussowitsch } PetscOffloadMask;
146030f984aSJacob Faibussowitsch 
1470e6b6b59SJacob Faibussowitsch #define PetscOffloadUnallocated(m) ((m) == PETSC_OFFLOAD_UNALLOCATED)
1480e6b6b59SJacob Faibussowitsch #define PetscOffloadHost(m)        (((m)&PETSC_OFFLOAD_CPU) == PETSC_OFFLOAD_CPU)
1490e6b6b59SJacob Faibussowitsch #define PetscOffloadDevice(m)      (((m)&PETSC_OFFLOAD_GPU) == PETSC_OFFLOAD_GPU)
150a8e904f6SJacob Faibussowitsch #define PetscOffloadBoth(m)        ((m) == PETSC_OFFLOAD_BOTH)
1510e6b6b59SJacob Faibussowitsch 
1520e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
1530e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
1540e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
1550e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
1560e6b6b59SJacob Faibussowitsch   #endif
1570e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_UNALLOCATED), "");
1580e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadHost(PETSC_OFFLOAD_BOTH), "");
1590e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_GPU), "");
1600e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadHost(PETSC_OFFLOAD_BOTH), "");
1610e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_KOKKOS), "");
1620e6b6b59SJacob Faibussowitsch 
1630e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_UNALLOCATED), "");
1640e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_CPU), "");
1650e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadDevice(PETSC_OFFLOAD_GPU), "");
1660e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadDevice(PETSC_OFFLOAD_BOTH), "");
1670e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_KOKKOS), "");
168a8e904f6SJacob Faibussowitsch 
169a8e904f6SJacob Faibussowitsch static_assert(PetscOffloadBoth(PETSC_OFFLOAD_BOTH), "");
170a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_CPU), "");
171a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_GPU), "");
172a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_GPU), "");
173a8e904f6SJacob Faibussowitsch static_assert(!PetscOffloadBoth(PETSC_OFFLOAD_KOKKOS), "");
1740e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
1750e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
1760e6b6b59SJacob Faibussowitsch   #endif
1770e6b6b59SJacob Faibussowitsch #endif // __cplusplus
1780e6b6b59SJacob Faibussowitsch 
179d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscOffloadMaskToString(PetscOffloadMask mask)
180d71ae5a4SJacob Faibussowitsch {
1810e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
182d71ae5a4SJacob Faibussowitsch case v: \
183d71ae5a4SJacob Faibussowitsch   return PetscStringize(v)
1840e6b6b59SJacob Faibussowitsch 
1850e6b6b59SJacob Faibussowitsch   switch (mask) {
1860e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_UNALLOCATED);
1870e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_CPU);
1880e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_GPU);
1890e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_BOTH);
1900e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_KOKKOS);
1910e6b6b59SJacob Faibussowitsch   }
1920e6b6b59SJacob Faibussowitsch   PetscUnreachable();
1930e6b6b59SJacob Faibussowitsch   return "invalid";
1940e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
1950e6b6b59SJacob Faibussowitsch }
1960e6b6b59SJacob Faibussowitsch 
197d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscMemType PetscOffloadMaskToMemType(PetscOffloadMask mask)
198d71ae5a4SJacob Faibussowitsch {
1990e6b6b59SJacob Faibussowitsch   switch (mask) {
2000e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_UNALLOCATED:
201d71ae5a4SJacob Faibussowitsch   case PETSC_OFFLOAD_CPU:
202d71ae5a4SJacob Faibussowitsch     return PETSC_MEMTYPE_HOST;
2030e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_GPU:
204d71ae5a4SJacob Faibussowitsch   case PETSC_OFFLOAD_BOTH:
205d71ae5a4SJacob Faibussowitsch     return PETSC_MEMTYPE_DEVICE;
206d71ae5a4SJacob Faibussowitsch   case PETSC_OFFLOAD_KOKKOS:
207d71ae5a4SJacob Faibussowitsch     return PETSC_MEMTYPE_KOKKOS;
2080e6b6b59SJacob Faibussowitsch   }
2090e6b6b59SJacob Faibussowitsch   PetscUnreachable();
2100e6b6b59SJacob Faibussowitsch   return PETSC_MEMTYPE_HOST;
2110e6b6b59SJacob Faibussowitsch }
2120e6b6b59SJacob Faibussowitsch 
213030f984aSJacob Faibussowitsch /*E
21487497f52SBarry Smith   PetscDeviceInitType - Initialization strategy for `PetscDevice`
215a4af0ceeSJacob Faibussowitsch 
216a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_INIT_NONE  - PetscDevice is never initialized
217a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_INIT_LAZY  - PetscDevice is initialized on demand
218a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_INIT_EAGER - PetscDevice is initialized as soon as possible
219a4af0ceeSJacob Faibussowitsch 
220a4af0ceeSJacob Faibussowitsch   Notes:
2210e6b6b59SJacob Faibussowitsch   `PETSC_DEVICE_INIT_NONE` implies that any initialization of `PetscDevice` is disallowed and
222a4af0ceeSJacob Faibussowitsch   doing so results in an error. Useful to ensure that no accelerator is used in a program.
223a4af0ceeSJacob Faibussowitsch 
224a4af0ceeSJacob Faibussowitsch   Level: beginner
225a4af0ceeSJacob Faibussowitsch 
2260e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceType`, `PetscDeviceInitialize()`,
2270e6b6b59SJacob Faibussowitsch `PetscDeviceInitialized()`, `PetscDeviceCreate()`
228a4af0ceeSJacob Faibussowitsch E*/
229a4af0ceeSJacob Faibussowitsch typedef enum {
230a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_NONE,
231a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_LAZY,
232a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_EAGER
233a4af0ceeSJacob Faibussowitsch } PetscDeviceInitType;
234a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceInitTypes[];
235a4af0ceeSJacob Faibussowitsch 
236a4af0ceeSJacob Faibussowitsch /*E
237a4af0ceeSJacob Faibussowitsch   PetscDeviceType - Kind of accelerator device backend
238030f984aSJacob Faibussowitsch 
2390e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_HOST - Host, no accelerator backend found
240030f984aSJacob Faibussowitsch $ PETSC_DEVICE_CUDA - CUDA enabled GPU
241030f984aSJacob Faibussowitsch $ PETSC_DEVICE_HIP  - ROCM/HIP enabled GPU
242a2158755SJunchao Zhang $ PETSC_DEVICE_SYCL - SYCL enabled device
243a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_MAX  - Always 1 greater than the largest valid PetscDeviceType, invalid type, do not use
244030f984aSJacob Faibussowitsch 
245030f984aSJacob Faibussowitsch   Notes:
2460e6b6b59SJacob Faibussowitsch   One can also use the `PETSC_DEVICE_DEFAULT()` routine to get the current default `PetscDeviceType`.
247030f984aSJacob Faibussowitsch 
248030f984aSJacob Faibussowitsch   Level: beginner
249030f984aSJacob Faibussowitsch 
2500e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceInitType`, `PetscDeviceCreate()`, `PETSC_DEVICE_DEFAULT()`
251030f984aSJacob Faibussowitsch E*/
252030f984aSJacob Faibussowitsch typedef enum {
2530e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_HOST,
254a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_CUDA,
255a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_HIP,
256a2158755SJunchao Zhang   PETSC_DEVICE_SYCL,
257a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_MAX
258a4af0ceeSJacob Faibussowitsch } PetscDeviceType;
259a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceTypes[];
260030f984aSJacob Faibussowitsch 
261a16fd2c9SJacob Faibussowitsch /*E
262a16fd2c9SJacob Faibussowitsch   PetscDeviceAttribute - Attribute detailing a property or feature of a `PetscDevice`
263a16fd2c9SJacob Faibussowitsch 
264a16fd2c9SJacob Faibussowitsch $ PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK - The maximum amount of shared memory per block in a
265a16fd2c9SJacob Faibussowitsch device kernel
266a16fd2c9SJacob Faibussowitsch $ PETSC_DEVICE_ATTR_MAX                         - Invalid attribute, do not use
267a16fd2c9SJacob Faibussowitsch 
268a16fd2c9SJacob Faibussowitsch   Level: beginner
269a16fd2c9SJacob Faibussowitsch 
270a16fd2c9SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceGetAttribute()`
271a16fd2c9SJacob Faibussowitsch E*/
272a16fd2c9SJacob Faibussowitsch typedef enum {
273a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK,
274a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_MAX
275a16fd2c9SJacob Faibussowitsch } PetscDeviceAttribute;
276a16fd2c9SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceAttributes[];
277a16fd2c9SJacob Faibussowitsch 
278030f984aSJacob Faibussowitsch /*S
27987497f52SBarry Smith   PetscDevice - Object to manage an accelerator "device" (usually a GPU)
280030f984aSJacob Faibussowitsch 
2810e6b6b59SJacob Faibussowitsch   Notes:
2820e6b6b59SJacob Faibussowitsch   This object is used to house configuration and state of a device, but does not offer any
2830e6b6b59SJacob Faibussowitsch   ability to interact with or drive device computation. This functionality is facilitated
2840e6b6b59SJacob Faibussowitsch   instead by the `PetscDeviceContext` object.
285030f984aSJacob Faibussowitsch 
286030f984aSJacob Faibussowitsch   Level: beginner
287030f984aSJacob Faibussowitsch 
2880e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceType`, `PetscDeviceInitType`, `PetscDeviceCreate()`,
2890e6b6b59SJacob Faibussowitsch `PetscDeviceConfigure()`, `PetscDeviceDestroy()`, `PetscDeviceContext`,
2900e6b6b59SJacob Faibussowitsch `PetscDeviceContextSetDevice()`, `PetscDeviceContextGetDevice()`, `PetscDeviceGetAttribute()`
291030f984aSJacob Faibussowitsch S*/
292030f984aSJacob Faibussowitsch typedef struct _n_PetscDevice *PetscDevice;
293030f984aSJacob Faibussowitsch 
294030f984aSJacob Faibussowitsch /*E
2950e6b6b59SJacob Faibussowitsch   PetscStreamType - Stream blocking mode, indicates how a stream implementation will interact
2960e6b6b59SJacob Faibussowitsch   with the default "NULL" stream, which is usually blocking.
297030f984aSJacob Faibussowitsch 
298030f984aSJacob Faibussowitsch $ 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.
299030f984aSJacob Faibussowitsch $ PETSC_STREAM_DEFAULT_BLOCKING   - Stream will act independent of other streams, but will still be blocked by actions on the NULL stream.
300030f984aSJacob Faibussowitsch $ PETSC_STREAM_GLOBAL_NONBLOCKING - Stream is truly asynchronous, and is blocked by nothing, not even the NULL stream.
301030f984aSJacob Faibussowitsch $ PETSC_STREAM_MAX                - Always 1 greater than the largest PetscStreamType, do not use
302030f984aSJacob Faibussowitsch 
303030f984aSJacob Faibussowitsch   Level: intermediate
304030f984aSJacob Faibussowitsch 
305db781477SPatrick Sanan .seealso: `PetscDeviceContextSetStreamType()`, `PetscDeviceContextGetStreamType()`
306030f984aSJacob Faibussowitsch E*/
307030f984aSJacob Faibussowitsch typedef enum {
308a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_GLOBAL_BLOCKING,
309a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_DEFAULT_BLOCKING,
310a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_GLOBAL_NONBLOCKING,
311a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_MAX
312030f984aSJacob Faibussowitsch } PetscStreamType;
313030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscStreamTypes[];
314030f984aSJacob Faibussowitsch 
315030f984aSJacob Faibussowitsch /*E
3160e6b6b59SJacob Faibussowitsch   PetscDeviceContextJoinMode - Describes the type of join operation to perform in
3170e6b6b59SJacob Faibussowitsch   `PetscDeviceContextJoin()`
318030f984aSJacob Faibussowitsch 
3195d84059aSJacob Faibussowitsch $ PETSC_DEVICE_CONTEXT_JOIN_DESTROY - Destroy all incoming sub-contexts after join.
3205d84059aSJacob Faibussowitsch $ PETSC_DEVICE_CONTEXT_JOIN_SYNC    - Synchronize incoming sub-contexts after join.
3215d84059aSJacob Faibussowitsch $ PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC - Do not synchronize incoming sub-contexts after join.
322030f984aSJacob Faibussowitsch 
323030f984aSJacob Faibussowitsch   Level: beginner
324030f984aSJacob Faibussowitsch 
325db781477SPatrick Sanan .seealso: `PetscDeviceContext`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
326030f984aSJacob Faibussowitsch E*/
327030f984aSJacob Faibussowitsch typedef enum {
328030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_DESTROY,
329030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_SYNC,
330030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC
331030f984aSJacob Faibussowitsch } PetscDeviceContextJoinMode;
332030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceContextJoinModes[];
333030f984aSJacob Faibussowitsch 
334030f984aSJacob Faibussowitsch /*S
3350e6b6b59SJacob Faibussowitsch   PetscDeviceContext - Container to manage stream dependencies and the various solver handles
3360e6b6b59SJacob Faibussowitsch   for asynchronous device compute.
337030f984aSJacob Faibussowitsch 
338030f984aSJacob Faibussowitsch   Level: beginner
339030f984aSJacob Faibussowitsch 
3400e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceContextCreate()`, `PetscDeviceContextSetDevice()`,
3410e6b6b59SJacob Faibussowitsch `PetscDeviceContextDestroy()`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
342030f984aSJacob Faibussowitsch S*/
3430e6b6b59SJacob Faibussowitsch typedef struct _p_PetscDeviceContext *PetscDeviceContext;
3440e6b6b59SJacob Faibussowitsch 
3450e6b6b59SJacob Faibussowitsch /*E
3460e6b6b59SJacob Faibussowitsch   PetscDeviceCopyMode - Describes the copy direction of a device-aware memcpy
3470e6b6b59SJacob Faibussowitsch 
3480e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_HTOH - Copy from host memory to host memory
3490e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_DTOH - Copy from device memory to host memory
3500e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_HTOD - Copy from host memory to device memory
3510e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_DTOD - Copy from device memory to device memory
3520e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_AUTO - Infer the copy direction from the pointers
3530e6b6b59SJacob Faibussowitsch 
3540e6b6b59SJacob Faibussowitsch   Level: beginner
3550e6b6b59SJacob Faibussowitsch 
3560e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceArrayCopy()`, `PetscDeviceMemcpy()`
3570e6b6b59SJacob Faibussowitsch E*/
3580e6b6b59SJacob Faibussowitsch typedef enum {
3590e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOH,
3600e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOH,
3610e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOD,
3620e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOD,
3630e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_AUTO,
3640e6b6b59SJacob Faibussowitsch } PetscDeviceCopyMode;
3650e6b6b59SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceCopyModes[];
3660e6b6b59SJacob Faibussowitsch 
367d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PetscDeviceCopyMode PetscOffloadMaskToDeviceCopyMode(PetscOffloadMask dest, PetscOffloadMask src)
368d71ae5a4SJacob Faibussowitsch {
3690e6b6b59SJacob Faibussowitsch   PetscDeviceCopyMode mode;
3700e6b6b59SJacob Faibussowitsch 
3710e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
3720e6b6b59SJacob Faibussowitsch   PetscAssertAbort(dest != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy to unallocated");
3730e6b6b59SJacob Faibussowitsch   PetscAssertAbort(src != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy from unallocated");
3740e6b6b59SJacob Faibussowitsch 
3750e6b6b59SJacob Faibussowitsch   if (PetscOffloadDevice(dest)) {
3760e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOD : PETSC_DEVICE_COPY_DTOD;
3770e6b6b59SJacob Faibussowitsch   } else {
3780e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
3790e6b6b59SJacob Faibussowitsch   }
3800e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(mode);
3810e6b6b59SJacob Faibussowitsch }
3820e6b6b59SJacob Faibussowitsch 
383d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscDeviceCopyMode PetscMemTypeToDeviceCopyMode(PetscMemType dest, PetscMemType src)
384d71ae5a4SJacob Faibussowitsch {
3850e6b6b59SJacob Faibussowitsch   if (PetscMemTypeHost(dest)) {
3860e6b6b59SJacob Faibussowitsch     return PetscMemTypeHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
3870e6b6b59SJacob Faibussowitsch   } else {
3880e6b6b59SJacob Faibussowitsch     return PetscMemTypeDevice(src) ? PETSC_DEVICE_COPY_DTOD : PETSC_DEVICE_COPY_HTOD;
3890e6b6b59SJacob Faibussowitsch   }
3900e6b6b59SJacob Faibussowitsch }
3910e6b6b59SJacob Faibussowitsch 
3920e6b6b59SJacob Faibussowitsch /*E
3930e6b6b59SJacob Faibussowitsch   PetscMemoryAccessMode - Describes the intended usage of a memory region
3940e6b6b59SJacob Faibussowitsch 
3950e6b6b59SJacob Faibussowitsch + PETSC_MEMORY_ACCESS_READ       - Read only
3960e6b6b59SJacob Faibussowitsch . PETSC_MEMORY_ACCESS_WRITE      - Write only
3970e6b6b59SJacob Faibussowitsch - PETSC_MEMORY_ACCESS_READ_WRITE - Read and write
3980e6b6b59SJacob Faibussowitsch 
3990e6b6b59SJacob Faibussowitsch   Notes:
4000e6b6b59SJacob Faibussowitsch   This `enum` is a bitmask with the following encoding (assuming 2 bit)\:
4010e6b6b59SJacob Faibussowitsch 
4020e6b6b59SJacob Faibussowitsch .vb
4030e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0b01
4040e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0b10
4050e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0b11
4060e6b6b59SJacob Faibussowitsch 
4070e6b6b59SJacob Faibussowitsch   // consequently
4080e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE = PETSC_MEMORY_ACCESS_READ_WRITE
4090e6b6b59SJacob Faibussowitsch .ve
4100e6b6b59SJacob Faibussowitsch 
411*aaa8cc7dSPierre Jolivet   The following convenience macros are also provided\:
4120e6b6b59SJacob Faibussowitsch 
4130e6b6b59SJacob Faibussowitsch   - `PetscMemoryAccessRead(mode)`\: `true` if `mode` is any kind of read, `false` otherwise
4140e6b6b59SJacob Faibussowitsch   - `PetscMemoryAccessWrite(mode)`\: `true` if `mode` is any kind of write, `false` otherwise
4150e6b6b59SJacob Faibussowitsch 
4160e6b6b59SJacob Faibussowitsch   Developer Notes:
4170e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemoryAccessModeToString()`) to convert values to string
4180e6b6b59SJacob Faibussowitsch   representation, so cannot be used in `PetscOptionsEnum()`.
4190e6b6b59SJacob Faibussowitsch 
4200e6b6b59SJacob Faibussowitsch   Level: beginner
4210e6b6b59SJacob Faibussowitsch 
4220e6b6b59SJacob Faibussowitsch .seealso: `PetscMemoryAccessModeToString()`, `PetscDevice`, `PetscDeviceContext`
4230e6b6b59SJacob Faibussowitsch E*/
4240e6b6b59SJacob Faibussowitsch typedef enum {
4250e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0x1, // 01
4260e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0x2, // 10
4270e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0x3, // 11
4280e6b6b59SJacob Faibussowitsch } PetscMemoryAccessMode;
4290e6b6b59SJacob Faibussowitsch 
4300e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessRead(m)  (((m)&PETSC_MEMORY_ACCESS_READ) == PETSC_MEMORY_ACCESS_READ)
4310e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessWrite(m) (((m)&PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_WRITE)
4320e6b6b59SJacob Faibussowitsch 
4330e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
4340e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4350e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
4360e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
4370e6b6b59SJacob Faibussowitsch   #endif
4380e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ), "");
4390e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ_WRITE), "");
4400e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_WRITE), "");
4410e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_WRITE), "");
4420e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ_WRITE), "");
4430e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ), "");
4440e6b6b59SJacob Faibussowitsch static_assert((PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_READ_WRITE, "");
4450e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4460e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
4470e6b6b59SJacob Faibussowitsch   #endif
4480e6b6b59SJacob Faibussowitsch #endif
4490e6b6b59SJacob Faibussowitsch 
450d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemoryAccessModeToString(PetscMemoryAccessMode mode)
451d71ae5a4SJacob Faibussowitsch {
4520e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
453d71ae5a4SJacob Faibussowitsch case v: \
454d71ae5a4SJacob Faibussowitsch   return PetscStringize(v)
4550e6b6b59SJacob Faibussowitsch 
4560e6b6b59SJacob Faibussowitsch   switch (mode) {
4570e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ);
4580e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_WRITE);
4590e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ_WRITE);
4600e6b6b59SJacob Faibussowitsch   }
4610e6b6b59SJacob Faibussowitsch   PetscUnreachable();
4620e6b6b59SJacob Faibussowitsch   return "invalid";
4630e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
4640e6b6b59SJacob Faibussowitsch }
4650e6b6b59SJacob Faibussowitsch 
4660e6b6b59SJacob Faibussowitsch #undef PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4670e6b6b59SJacob Faibussowitsch 
468030f984aSJacob Faibussowitsch #endif /* PETSCDEVICETYPES_H */
469