xref: /petsc/include/petscdevicetypes.h (revision 16a05f60a523f53ab316acaac9f77b7425611adc)
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 
19*16a05f60SBarry 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 
28*16a05f60SBarry Smith   Developer Note:
29*16a05f60SBarry Smith   Encoding of the bitmask in binary: xxxxyyyz
30*16a05f60SBarry Smith .vb
31*16a05f60SBarry Smith  z = 0                - Host memory
32*16a05f60SBarry Smith  z = 1                - Device memory
33*16a05f60SBarry Smith  yyy = 000            - CUDA-related memory
34*16a05f60SBarry Smith  yyy = 001            - HIP-related memory
35*16a05f60SBarry Smith  yyy = 010            - SYCL-related memory
36*16a05f60SBarry Smith  xxxxyyy1 = 0000,0001 - CUDA memory
37*16a05f60SBarry Smith  xxxxyyy1 = 0001,0001 - CUDA NVSHMEM memory
38*16a05f60SBarry Smith  xxxxyyy1 = 0000,0011 - HIP memory
39*16a05f60SBarry Smith  xxxxyyy1 = 0000,0101 - SYCL memory
40*16a05f60SBarry Smith .ve
41*16a05f60SBarry Smith 
42*16a05f60SBarry Smith   Other types of memory, e.g., CUDA managed memory, can be added when needed.
43*16a05f60SBarry 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 
1205b5f62f7SJacob Faibussowitsch #define PETSC_OFFLOAD_VECKOKKOS_DEPRECATED PETSC_OFFLOAD_VECKOKKOS PETSC_DEPRECATED_ENUM("Use PETSC_OFFLOAD_KOKKOS (since version 3.17.0)")
1210e6b6b59SJacob Faibussowitsch 
122030f984aSJacob Faibussowitsch /*E
123030f984aSJacob Faibussowitsch   PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data
124030f984aSJacob Faibussowitsch 
125*16a05f60SBarry Smith   Values:
126*16a05f60SBarry Smith + `PETSC_OFFLOAD_UNALLOCATED` - no memory contains valid matrix entries; NEVER used for vectors
127*16a05f60SBarry Smith . `PETSC_OFFLOAD_GPU`         - GPU has valid vector/matrix entries
128*16a05f60SBarry Smith . `PETSC_OFFLOAD_CPU`         - CPU has valid vector/matrix entries
129*16a05f60SBarry Smith . `PETSC_OFFLOAD_BOTH`        - Both GPU and CPU have valid vector/matrix entries and they match
130*16a05f60SBarry 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.
131*16a05f60SBarry Smith 
132*16a05f60SBarry 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 
218*16a05f60SBarry Smith   Values:
219*16a05f60SBarry Smith + `PETSC_DEVICE_INIT_NONE`  - PetscDevice is never initialized
220*16a05f60SBarry Smith . `PETSC_DEVICE_INIT_LAZY`  - PetscDevice is initialized on demand
221*16a05f60SBarry Smith - `PETSC_DEVICE_INIT_EAGER` - PetscDevice is initialized as soon as possible
222*16a05f60SBarry Smith 
223*16a05f60SBarry 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 
242*16a05f60SBarry Smith   Values:
243*16a05f60SBarry Smith + `PETSC_DEVICE_HOST` - Host, no accelerator backend found
244*16a05f60SBarry Smith . `PETSC_DEVICE_CUDA` - CUDA enabled GPU
245*16a05f60SBarry Smith . `PETSC_DEVICE_HIP`  - ROCM/HIP enabled GPU
246*16a05f60SBarry Smith . `PETSC_DEVICE_SYCL` - SYCL enabled device
247*16a05f60SBarry Smith - `PETSC_DEVICE_MAX`  - Always 1 greater than the largest valid `PetscDeviceType`, invalid type, do not use
248*16a05f60SBarry Smith 
249*16a05f60SBarry 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 
268*16a05f60SBarry Smith   Values:
269*16a05f60SBarry Smith + `PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK` - The maximum amount of shared memory per block in a device kernel
270*16a05f60SBarry 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 
285*16a05f60SBarry Smith   Level: beginner
286*16a05f60SBarry 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
300*16a05f60SBarry Smith   with the default `NULL` stream, which is usually blocking.
301030f984aSJacob Faibussowitsch 
302*16a05f60SBarry Smith   Values:
303*16a05f60SBarry 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.
304*16a05f60SBarry Smith . `PETSC_STREAM_DEFAULT_BLOCKING`   - Stream will act independent of other streams, but will still be blocked by actions on the `NULL` stream.
305*16a05f60SBarry Smith . `PETSC_STREAM_GLOBAL_NONBLOCKING` - Stream is truly asynchronous, and is blocked by nothing, not even the `NULL` stream.
306*16a05f60SBarry 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 
324*16a05f60SBarry Smith   Values:
325*16a05f60SBarry Smith + `PETSC_DEVICE_CONTEXT_JOIN_DESTROY` - Destroy all incoming sub-contexts after join.
326*16a05f60SBarry Smith . `PETSC_DEVICE_CONTEXT_JOIN_SYNC`    - Synchronize incoming sub-contexts after join.
327*16a05f60SBarry 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
352*16a05f60SBarry Smith   PetscDeviceCopyMode - Describes the copy direction of a device-aware `memcpy`
3530e6b6b59SJacob Faibussowitsch 
354*16a05f60SBarry Smith   Values:
355*16a05f60SBarry Smith + `PETSC_DEVICE_COPY_HTOH` - Copy from host memory to host memory
356*16a05f60SBarry Smith . `PETSC_DEVICE_COPY_DTOH` - Copy from device memory to host memory
357*16a05f60SBarry Smith . `PETSC_DEVICE_COPY_HTOD` - Copy from host memory to device memory
358*16a05f60SBarry Smith . `PETSC_DEVICE_COPY_DTOD` - Copy from device memory to device memory
359*16a05f60SBarry 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 
402*16a05f60SBarry Smith   Values:
403*16a05f60SBarry Smith + `PETSC_MEMORY_ACCESS_READ`       - Read only
404*16a05f60SBarry Smith . `PETSC_MEMORY_ACCESS_WRITE`      - Write only
405*16a05f60SBarry Smith - `PETSC_MEMORY_ACCESS_READ_WRITE` - Read and write
406*16a05f60SBarry Smith 
407*16a05f60SBarry 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 
423*16a05f60SBarry Smith + `PetscMemoryAccessRead(mode)` - `true` if `mode` is any kind of read, `false` otherwise
424*16a05f60SBarry 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