xref: /petsc/include/petscdevicetypes.h (revision 0e6b6b5985dd9b1172860d21fb88bd3966bf7c54)
107e4ef11SJacob Faibussowitsch #ifndef PETSCDEVICETYPES_H
2030f984aSJacob Faibussowitsch #define PETSCDEVICETYPES_H
3030f984aSJacob Faibussowitsch 
4*0e6b6b59SJacob Faibussowitsch #include <petscsys.h> /*I <petscdevicetypes.h> I*/
5*0e6b6b59SJacob Faibussowitsch 
6*0e6b6b59SJacob Faibussowitsch // Some overzealous older gcc versions warn that the comparisons below are always true. Neat
7*0e6b6b59SJacob Faibussowitsch // that it can detect this, but the tautology *is* the point of the static_assert()!
8*0e6b6b59SJacob Faibussowitsch #if defined(__GNUC__) && __GNUC__ >= 6 && !PetscDefined(HAVE_WINDOWS_COMPILERS)
9*0e6b6b59SJacob Faibussowitsch #define PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING 1
10*0e6b6b59SJacob Faibussowitsch #else
11*0e6b6b59SJacob Faibussowitsch #define PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING 0
12*0e6b6b59SJacob 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 
39*0e6b6b59SJacob Faibussowitsch   Developer Notes:
40*0e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemTypeToString()`) to convert to string representation so
41*0e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
42*0e6b6b59SJacob Faibussowitsch 
43*0e6b6b59SJacob Faibussowitsch .seealso: `PetscMemTypeToString()`, `VecGetArrayAndMemType()`,
44*0e6b6b59SJacob 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 
71*0e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
72*0e6b6b59SJacob Faibussowitsch #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
73*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic push
74*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic ignored "-Wtautological-compare"
75*0e6b6b59SJacob Faibussowitsch #endif
76*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeHost(PETSC_MEMTYPE_HOST), "");
77*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_DEVICE), "");
78*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_CUDA), "");
79*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_HIP), "");
80*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_SYCL), "");
81*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_NVSHMEM), "");
82*0e6b6b59SJacob Faibussowitsch 
83*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeDevice(PETSC_MEMTYPE_HOST), "");
84*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_DEVICE), "");
85*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_CUDA), "");
86*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_HIP), "");
87*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_SYCL), "");
88*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_NVSHMEM), "");
89*0e6b6b59SJacob Faibussowitsch 
90*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_CUDA), "");
91*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_NVSHMEM), "");
92*0e6b6b59SJacob Faibussowitsch #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
93*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic pop
94*0e6b6b59SJacob Faibussowitsch #endif
95*0e6b6b59SJacob Faibussowitsch #endif // __cplusplus
96*0e6b6b59SJacob Faibussowitsch 
97*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemTypeToString(PetscMemType mtype) {
98*0e6b6b59SJacob Faibussowitsch #ifdef __cplusplus
99*0e6b6b59SJacob Faibussowitsch   static_assert(PETSC_MEMTYPE_CUDA == PETSC_MEMTYPE_DEVICE, "");
100*0e6b6b59SJacob Faibussowitsch #endif
101*0e6b6b59SJacob Faibussowitsch #define PETSC_CASE_NAME(v) \
102*0e6b6b59SJacob Faibussowitsch   case v: return PetscStringize(v)
103*0e6b6b59SJacob Faibussowitsch 
104*0e6b6b59SJacob Faibussowitsch   switch (mtype) {
105*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HOST);
106*0e6b6b59SJacob Faibussowitsch     /* PETSC_CASE_NAME(PETSC_MEMTYPE_DEVICE); same as PETSC_MEMTYPE_CUDA */
107*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_CUDA);
108*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_NVSHMEM);
109*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HIP);
110*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_SYCL);
111*0e6b6b59SJacob Faibussowitsch   }
112*0e6b6b59SJacob Faibussowitsch   PetscUnreachable();
113*0e6b6b59SJacob Faibussowitsch   return "invalid";
114*0e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_NAME
115*0e6b6b59SJacob Faibussowitsch }
116*0e6b6b59SJacob Faibussowitsch 
1175b5f62f7SJacob Faibussowitsch #define PETSC_OFFLOAD_VECKOKKOS_DEPRECATED PETSC_OFFLOAD_VECKOKKOS PETSC_DEPRECATED_ENUM("Use PETSC_OFFLOAD_KOKKOS (since version 3.17.0)")
118*0e6b6b59SJacob Faibussowitsch 
119030f984aSJacob Faibussowitsch /*E
120030f984aSJacob Faibussowitsch   PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data
121030f984aSJacob Faibussowitsch 
122fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
123fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_GPU         - GPU has valid vector/matrix entries
124fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_CPU         - CPU has valid vector/matrix entries
125fe0d65a2SJacob Faibussowitsch $ PETSC_OFFLOAD_BOTH        - Both GPU and CPU have valid vector/matrix entries and they match
126ae76731bSJunchao 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.
127030f984aSJacob Faibussowitsch 
128*0e6b6b59SJacob Faibussowitsch   Developer Notes:
129*0e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscOffloadMaskToString()`) to convert to string representation so
130*0e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
131*0e6b6b59SJacob Faibussowitsch 
132030f984aSJacob Faibussowitsch   Level: developer
133*0e6b6b59SJacob Faibussowitsch 
134*0e6b6b59SJacob Faibussowitsch .seealso: `PetscOffloadMaskToString()`, `PetscOffloadMaskToMemType()`, `PetscOffloadMaskToDeviceCopyMode()`
135030f984aSJacob Faibussowitsch E*/
136fe0d65a2SJacob Faibussowitsch typedef enum {
137fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_UNALLOCATED          = 0x0,
138fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_CPU                  = 0x1,
139fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_GPU                  = 0x2,
140fe0d65a2SJacob Faibussowitsch   PETSC_OFFLOAD_BOTH                 = 0x3,
141d795ed5eSJunchao Zhang   PETSC_OFFLOAD_VECKOKKOS_DEPRECATED = 0x100,
142ae76731bSJunchao Zhang   PETSC_OFFLOAD_KOKKOS               = 0x100
143fe0d65a2SJacob Faibussowitsch } PetscOffloadMask;
144030f984aSJacob Faibussowitsch 
145*0e6b6b59SJacob Faibussowitsch #define PetscOffloadUnallocated(m) ((m) == PETSC_OFFLOAD_UNALLOCATED)
146*0e6b6b59SJacob Faibussowitsch #define PetscOffloadHost(m)        (((m)&PETSC_OFFLOAD_CPU) == PETSC_OFFLOAD_CPU)
147*0e6b6b59SJacob Faibussowitsch #define PetscOffloadDevice(m)      (((m)&PETSC_OFFLOAD_GPU) == PETSC_OFFLOAD_GPU)
148*0e6b6b59SJacob Faibussowitsch #define PetscOffloadBoth(m)        ((m) != PETSC_OFFLOAD_UNALLOCATED)
149*0e6b6b59SJacob Faibussowitsch 
150*0e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
151*0e6b6b59SJacob Faibussowitsch #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
152*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic push
153*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic ignored "-Wtautological-compare"
154*0e6b6b59SJacob Faibussowitsch #endif
155*0e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_UNALLOCATED), "");
156*0e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadHost(PETSC_OFFLOAD_BOTH), "");
157*0e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_GPU), "");
158*0e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadHost(PETSC_OFFLOAD_BOTH), "");
159*0e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadHost(PETSC_OFFLOAD_KOKKOS), "");
160*0e6b6b59SJacob Faibussowitsch 
161*0e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_UNALLOCATED), "");
162*0e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_CPU), "");
163*0e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadDevice(PETSC_OFFLOAD_GPU), "");
164*0e6b6b59SJacob Faibussowitsch static_assert(PetscOffloadDevice(PETSC_OFFLOAD_BOTH), "");
165*0e6b6b59SJacob Faibussowitsch static_assert(!PetscOffloadDevice(PETSC_OFFLOAD_KOKKOS), "");
166*0e6b6b59SJacob Faibussowitsch #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
167*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic pop
168*0e6b6b59SJacob Faibussowitsch #endif
169*0e6b6b59SJacob Faibussowitsch #endif // __cplusplus
170*0e6b6b59SJacob Faibussowitsch 
171*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscOffloadMaskToString(PetscOffloadMask mask) {
172*0e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
173*0e6b6b59SJacob Faibussowitsch   case v: return PetscStringize(v)
174*0e6b6b59SJacob Faibussowitsch 
175*0e6b6b59SJacob Faibussowitsch   switch (mask) {
176*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_UNALLOCATED);
177*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_CPU);
178*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_GPU);
179*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_BOTH);
180*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_OFFLOAD_KOKKOS);
181*0e6b6b59SJacob Faibussowitsch   }
182*0e6b6b59SJacob Faibussowitsch   PetscUnreachable();
183*0e6b6b59SJacob Faibussowitsch   return "invalid";
184*0e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
185*0e6b6b59SJacob Faibussowitsch }
186*0e6b6b59SJacob Faibussowitsch 
187*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscMemType PetscOffloadMaskToMemType(PetscOffloadMask mask) {
188*0e6b6b59SJacob Faibussowitsch   switch (mask) {
189*0e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_UNALLOCATED:
190*0e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_CPU: return PETSC_MEMTYPE_HOST;
191*0e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_GPU:
192*0e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_BOTH: return PETSC_MEMTYPE_DEVICE;
193*0e6b6b59SJacob Faibussowitsch   case PETSC_OFFLOAD_KOKKOS: return PETSC_MEMTYPE_KOKKOS;
194*0e6b6b59SJacob Faibussowitsch   }
195*0e6b6b59SJacob Faibussowitsch   PetscUnreachable();
196*0e6b6b59SJacob Faibussowitsch   return PETSC_MEMTYPE_HOST;
197*0e6b6b59SJacob Faibussowitsch }
198*0e6b6b59SJacob Faibussowitsch 
199030f984aSJacob Faibussowitsch /*E
20087497f52SBarry Smith   PetscDeviceInitType - Initialization strategy for `PetscDevice`
201a4af0ceeSJacob Faibussowitsch 
202a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_INIT_NONE  - PetscDevice is never initialized
203a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_INIT_LAZY  - PetscDevice is initialized on demand
204a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_INIT_EAGER - PetscDevice is initialized as soon as possible
205a4af0ceeSJacob Faibussowitsch 
206a4af0ceeSJacob Faibussowitsch   Notes:
207*0e6b6b59SJacob Faibussowitsch   `PETSC_DEVICE_INIT_NONE` implies that any initialization of `PetscDevice` is disallowed and
208a4af0ceeSJacob Faibussowitsch   doing so results in an error. Useful to ensure that no accelerator is used in a program.
209a4af0ceeSJacob Faibussowitsch 
210a4af0ceeSJacob Faibussowitsch   Level: beginner
211a4af0ceeSJacob Faibussowitsch 
212*0e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceType`, `PetscDeviceInitialize()`,
213*0e6b6b59SJacob Faibussowitsch `PetscDeviceInitialized()`, `PetscDeviceCreate()`
214a4af0ceeSJacob Faibussowitsch E*/
215a4af0ceeSJacob Faibussowitsch typedef enum {
216a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_NONE,
217a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_LAZY,
218a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_EAGER
219a4af0ceeSJacob Faibussowitsch } PetscDeviceInitType;
220a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceInitTypes[];
221a4af0ceeSJacob Faibussowitsch 
222a4af0ceeSJacob Faibussowitsch /*E
223a4af0ceeSJacob Faibussowitsch   PetscDeviceType - Kind of accelerator device backend
224030f984aSJacob Faibussowitsch 
225*0e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_HOST - Host, no accelerator backend found
226030f984aSJacob Faibussowitsch $ PETSC_DEVICE_CUDA - CUDA enabled GPU
227030f984aSJacob Faibussowitsch $ PETSC_DEVICE_HIP  - ROCM/HIP enabled GPU
228a2158755SJunchao Zhang $ PETSC_DEVICE_SYCL - SYCL enabled device
229a4af0ceeSJacob Faibussowitsch $ PETSC_DEVICE_MAX  - Always 1 greater than the largest valid PetscDeviceType, invalid type, do not use
230030f984aSJacob Faibussowitsch 
231030f984aSJacob Faibussowitsch   Notes:
232*0e6b6b59SJacob Faibussowitsch   One can also use the `PETSC_DEVICE_DEFAULT()` routine to get the current default `PetscDeviceType`.
233030f984aSJacob Faibussowitsch 
234030f984aSJacob Faibussowitsch   Level: beginner
235030f984aSJacob Faibussowitsch 
236*0e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceInitType`, `PetscDeviceCreate()`, `PETSC_DEVICE_DEFAULT()`
237030f984aSJacob Faibussowitsch E*/
238030f984aSJacob Faibussowitsch typedef enum {
239*0e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_HOST,
240a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_CUDA,
241a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_HIP,
242a2158755SJunchao Zhang   PETSC_DEVICE_SYCL,
243a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_MAX
244a4af0ceeSJacob Faibussowitsch } PetscDeviceType;
245a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceTypes[];
246030f984aSJacob Faibussowitsch 
247a16fd2c9SJacob Faibussowitsch /*E
248a16fd2c9SJacob Faibussowitsch   PetscDeviceAttribute - Attribute detailing a property or feature of a `PetscDevice`
249a16fd2c9SJacob Faibussowitsch 
250a16fd2c9SJacob Faibussowitsch $ PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK - The maximum amount of shared memory per block in a
251a16fd2c9SJacob Faibussowitsch device kernel
252a16fd2c9SJacob Faibussowitsch $ PETSC_DEVICE_ATTR_MAX                         - Invalid attribute, do not use
253a16fd2c9SJacob Faibussowitsch 
254a16fd2c9SJacob Faibussowitsch   Level: beginner
255a16fd2c9SJacob Faibussowitsch 
256a16fd2c9SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceGetAttribute()`
257a16fd2c9SJacob Faibussowitsch E*/
258a16fd2c9SJacob Faibussowitsch typedef enum {
259a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK,
260a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_MAX
261a16fd2c9SJacob Faibussowitsch } PetscDeviceAttribute;
262a16fd2c9SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceAttributes[];
263a16fd2c9SJacob Faibussowitsch 
264030f984aSJacob Faibussowitsch /*S
26587497f52SBarry Smith   PetscDevice - Object to manage an accelerator "device" (usually a GPU)
266030f984aSJacob Faibussowitsch 
267*0e6b6b59SJacob Faibussowitsch   Notes:
268*0e6b6b59SJacob Faibussowitsch   This object is used to house configuration and state of a device, but does not offer any
269*0e6b6b59SJacob Faibussowitsch   ability to interact with or drive device computation. This functionality is facilitated
270*0e6b6b59SJacob Faibussowitsch   instead by the `PetscDeviceContext` object.
271030f984aSJacob Faibussowitsch 
272030f984aSJacob Faibussowitsch   Level: beginner
273030f984aSJacob Faibussowitsch 
274*0e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceType`, `PetscDeviceInitType`, `PetscDeviceCreate()`,
275*0e6b6b59SJacob Faibussowitsch `PetscDeviceConfigure()`, `PetscDeviceDestroy()`, `PetscDeviceContext`,
276*0e6b6b59SJacob Faibussowitsch `PetscDeviceContextSetDevice()`, `PetscDeviceContextGetDevice()`, `PetscDeviceGetAttribute()`
277030f984aSJacob Faibussowitsch S*/
278030f984aSJacob Faibussowitsch typedef struct _n_PetscDevice *PetscDevice;
279030f984aSJacob Faibussowitsch 
280030f984aSJacob Faibussowitsch /*E
281*0e6b6b59SJacob Faibussowitsch   PetscStreamType - Stream blocking mode, indicates how a stream implementation will interact
282*0e6b6b59SJacob Faibussowitsch   with the default "NULL" stream, which is usually blocking.
283030f984aSJacob Faibussowitsch 
284030f984aSJacob 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.
285030f984aSJacob Faibussowitsch $ PETSC_STREAM_DEFAULT_BLOCKING   - Stream will act independent of other streams, but will still be blocked by actions on the NULL stream.
286030f984aSJacob Faibussowitsch $ PETSC_STREAM_GLOBAL_NONBLOCKING - Stream is truly asynchronous, and is blocked by nothing, not even the NULL stream.
287030f984aSJacob Faibussowitsch $ PETSC_STREAM_MAX                - Always 1 greater than the largest PetscStreamType, do not use
288030f984aSJacob Faibussowitsch 
289030f984aSJacob Faibussowitsch   Level: intermediate
290030f984aSJacob Faibussowitsch 
291db781477SPatrick Sanan .seealso: `PetscDeviceContextSetStreamType()`, `PetscDeviceContextGetStreamType()`
292030f984aSJacob Faibussowitsch E*/
293030f984aSJacob Faibussowitsch typedef enum {
294a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_GLOBAL_BLOCKING,
295a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_DEFAULT_BLOCKING,
296a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_GLOBAL_NONBLOCKING,
297a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_MAX
298030f984aSJacob Faibussowitsch } PetscStreamType;
299030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscStreamTypes[];
300030f984aSJacob Faibussowitsch 
301030f984aSJacob Faibussowitsch /*E
302*0e6b6b59SJacob Faibussowitsch   PetscDeviceContextJoinMode - Describes the type of join operation to perform in
303*0e6b6b59SJacob Faibussowitsch   `PetscDeviceContextJoin()`
304030f984aSJacob Faibussowitsch 
3055d84059aSJacob Faibussowitsch $ PETSC_DEVICE_CONTEXT_JOIN_DESTROY - Destroy all incoming sub-contexts after join.
3065d84059aSJacob Faibussowitsch $ PETSC_DEVICE_CONTEXT_JOIN_SYNC    - Synchronize incoming sub-contexts after join.
3075d84059aSJacob Faibussowitsch $ PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC - Do not synchronize incoming sub-contexts after join.
308030f984aSJacob Faibussowitsch 
309030f984aSJacob Faibussowitsch   Level: beginner
310030f984aSJacob Faibussowitsch 
311db781477SPatrick Sanan .seealso: `PetscDeviceContext`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
312030f984aSJacob Faibussowitsch E*/
313030f984aSJacob Faibussowitsch typedef enum {
314030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_DESTROY,
315030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_SYNC,
316030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC
317030f984aSJacob Faibussowitsch } PetscDeviceContextJoinMode;
318030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceContextJoinModes[];
319030f984aSJacob Faibussowitsch 
320030f984aSJacob Faibussowitsch /*S
321*0e6b6b59SJacob Faibussowitsch   PetscDeviceContext - Container to manage stream dependencies and the various solver handles
322*0e6b6b59SJacob Faibussowitsch   for asynchronous device compute.
323030f984aSJacob Faibussowitsch 
324030f984aSJacob Faibussowitsch   Level: beginner
325030f984aSJacob Faibussowitsch 
326*0e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceContextCreate()`, `PetscDeviceContextSetDevice()`,
327*0e6b6b59SJacob Faibussowitsch `PetscDeviceContextDestroy()`,`PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
328030f984aSJacob Faibussowitsch S*/
329*0e6b6b59SJacob Faibussowitsch typedef struct _p_PetscDeviceContext *PetscDeviceContext;
330*0e6b6b59SJacob Faibussowitsch 
331*0e6b6b59SJacob Faibussowitsch /*E
332*0e6b6b59SJacob Faibussowitsch   PetscDeviceCopyMode - Describes the copy direction of a device-aware memcpy
333*0e6b6b59SJacob Faibussowitsch 
334*0e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_HTOH - Copy from host memory to host memory
335*0e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_DTOH - Copy from device memory to host memory
336*0e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_HTOD - Copy from host memory to device memory
337*0e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_DTOD - Copy from device memory to device memory
338*0e6b6b59SJacob Faibussowitsch $ PETSC_DEVICE_COPY_AUTO - Infer the copy direction from the pointers
339*0e6b6b59SJacob Faibussowitsch 
340*0e6b6b59SJacob Faibussowitsch   Level: beginner
341*0e6b6b59SJacob Faibussowitsch 
342*0e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceArrayCopy()`, `PetscDeviceMemcpy()`
343*0e6b6b59SJacob Faibussowitsch E*/
344*0e6b6b59SJacob Faibussowitsch typedef enum {
345*0e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOH,
346*0e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOH,
347*0e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOD,
348*0e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOD,
349*0e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_AUTO,
350*0e6b6b59SJacob Faibussowitsch } PetscDeviceCopyMode;
351*0e6b6b59SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceCopyModes[];
352*0e6b6b59SJacob Faibussowitsch 
353*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static inline PetscDeviceCopyMode PetscOffloadMaskToDeviceCopyMode(PetscOffloadMask dest, PetscOffloadMask src) {
354*0e6b6b59SJacob Faibussowitsch   PetscDeviceCopyMode mode;
355*0e6b6b59SJacob Faibussowitsch 
356*0e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
357*0e6b6b59SJacob Faibussowitsch   PetscAssertAbort(dest != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy to unallocated");
358*0e6b6b59SJacob Faibussowitsch   PetscAssertAbort(src != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy from unallocated");
359*0e6b6b59SJacob Faibussowitsch 
360*0e6b6b59SJacob Faibussowitsch   if (PetscOffloadDevice(dest)) {
361*0e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOD : PETSC_DEVICE_COPY_DTOD;
362*0e6b6b59SJacob Faibussowitsch   } else {
363*0e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
364*0e6b6b59SJacob Faibussowitsch   }
365*0e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(mode);
366*0e6b6b59SJacob Faibussowitsch }
367*0e6b6b59SJacob Faibussowitsch 
368*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscDeviceCopyMode PetscMemTypeToDeviceCopyMode(PetscMemType dest, PetscMemType src) {
369*0e6b6b59SJacob Faibussowitsch   if (PetscMemTypeHost(dest)) {
370*0e6b6b59SJacob Faibussowitsch     return PetscMemTypeHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
371*0e6b6b59SJacob Faibussowitsch   } else {
372*0e6b6b59SJacob Faibussowitsch     return PetscMemTypeDevice(src) ? PETSC_DEVICE_COPY_DTOD : PETSC_DEVICE_COPY_HTOD;
373*0e6b6b59SJacob Faibussowitsch   }
374*0e6b6b59SJacob Faibussowitsch }
375*0e6b6b59SJacob Faibussowitsch 
376*0e6b6b59SJacob Faibussowitsch /*E
377*0e6b6b59SJacob Faibussowitsch   PetscMemoryAccessMode - Describes the intended usage of a memory region
378*0e6b6b59SJacob Faibussowitsch 
379*0e6b6b59SJacob Faibussowitsch + PETSC_MEMORY_ACCESS_READ       - Read only
380*0e6b6b59SJacob Faibussowitsch . PETSC_MEMORY_ACCESS_WRITE      - Write only
381*0e6b6b59SJacob Faibussowitsch - PETSC_MEMORY_ACCESS_READ_WRITE - Read and write
382*0e6b6b59SJacob Faibussowitsch 
383*0e6b6b59SJacob Faibussowitsch   Notes:
384*0e6b6b59SJacob Faibussowitsch   This `enum` is a bitmask with the following encoding (assuming 2 bit)\:
385*0e6b6b59SJacob Faibussowitsch 
386*0e6b6b59SJacob Faibussowitsch .vb
387*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0b01
388*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0b10
389*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0b11
390*0e6b6b59SJacob Faibussowitsch 
391*0e6b6b59SJacob Faibussowitsch   // consequently
392*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE = PETSC_MEMORY_ACCESS_READ_WRITE
393*0e6b6b59SJacob Faibussowitsch .ve
394*0e6b6b59SJacob Faibussowitsch 
395*0e6b6b59SJacob Faibussowitsch   The following convience macros are also provided\:
396*0e6b6b59SJacob Faibussowitsch 
397*0e6b6b59SJacob Faibussowitsch   - `PetscMemoryAccessRead(mode)`\: `true` if `mode` is any kind of read, `false` otherwise
398*0e6b6b59SJacob Faibussowitsch   - `PetscMemoryAccessWrite(mode)`\: `true` if `mode` is any kind of write, `false` otherwise
399*0e6b6b59SJacob Faibussowitsch 
400*0e6b6b59SJacob Faibussowitsch   Developer Notes:
401*0e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemoryAccessModeToString()`) to convert values to string
402*0e6b6b59SJacob Faibussowitsch   representation, so cannot be used in `PetscOptionsEnum()`.
403*0e6b6b59SJacob Faibussowitsch 
404*0e6b6b59SJacob Faibussowitsch   Level: beginner
405*0e6b6b59SJacob Faibussowitsch 
406*0e6b6b59SJacob Faibussowitsch .seealso: `PetscMemoryAccessModeToString()`, `PetscDevice`, `PetscDeviceContext`
407*0e6b6b59SJacob Faibussowitsch E*/
408*0e6b6b59SJacob Faibussowitsch typedef enum {
409*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0x1, // 01
410*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0x2, // 10
411*0e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0x3, // 11
412*0e6b6b59SJacob Faibussowitsch } PetscMemoryAccessMode;
413*0e6b6b59SJacob Faibussowitsch 
414*0e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessRead(m)  (((m)&PETSC_MEMORY_ACCESS_READ) == PETSC_MEMORY_ACCESS_READ)
415*0e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessWrite(m) (((m)&PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_WRITE)
416*0e6b6b59SJacob Faibussowitsch 
417*0e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
418*0e6b6b59SJacob Faibussowitsch #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
419*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic push
420*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic ignored "-Wtautological-compare"
421*0e6b6b59SJacob Faibussowitsch #endif
422*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ), "");
423*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ_WRITE), "");
424*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_WRITE), "");
425*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_WRITE), "");
426*0e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ_WRITE), "");
427*0e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ), "");
428*0e6b6b59SJacob Faibussowitsch static_assert((PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_READ_WRITE, "");
429*0e6b6b59SJacob Faibussowitsch #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
430*0e6b6b59SJacob Faibussowitsch #pragma GCC diagnostic pop
431*0e6b6b59SJacob Faibussowitsch #endif
432*0e6b6b59SJacob Faibussowitsch #endif
433*0e6b6b59SJacob Faibussowitsch 
434*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemoryAccessModeToString(PetscMemoryAccessMode mode) {
435*0e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
436*0e6b6b59SJacob Faibussowitsch   case v: return PetscStringize(v)
437*0e6b6b59SJacob Faibussowitsch 
438*0e6b6b59SJacob Faibussowitsch   switch (mode) {
439*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ);
440*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_WRITE);
441*0e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ_WRITE);
442*0e6b6b59SJacob Faibussowitsch   }
443*0e6b6b59SJacob Faibussowitsch   PetscUnreachable();
444*0e6b6b59SJacob Faibussowitsch   return "invalid";
445*0e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
446*0e6b6b59SJacob Faibussowitsch }
447*0e6b6b59SJacob Faibussowitsch 
448*0e6b6b59SJacob Faibussowitsch #undef PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
449*0e6b6b59SJacob Faibussowitsch 
450030f984aSJacob Faibussowitsch #endif /* PETSCDEVICETYPES_H */
451