xref: /petsc/include/petscdevicetypes.h (revision 6d8694c4fbab79f9439f1ad13c0386ba7ee1ca4b)
1a4963045SJacob Faibussowitsch #pragma once
2030f984aSJacob Faibussowitsch 
30e6b6b59SJacob Faibussowitsch #include <petscsys.h> /*I <petscdevicetypes.h> I*/
40e6b6b59SJacob Faibussowitsch 
50e6b6b59SJacob Faibussowitsch // Some overzealous older gcc versions warn that the comparisons below are always true. Neat
60e6b6b59SJacob Faibussowitsch // that it can detect this, but the tautology *is* the point of the static_assert()!
70e6b6b59SJacob Faibussowitsch #if defined(__GNUC__) && __GNUC__ >= 6 && !PetscDefined(HAVE_WINDOWS_COMPILERS)
80e6b6b59SJacob Faibussowitsch   #define PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING 1
90e6b6b59SJacob Faibussowitsch #else
100e6b6b59SJacob Faibussowitsch   #define PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING 0
110e6b6b59SJacob Faibussowitsch #endif
12030f984aSJacob Faibussowitsch 
13ac09b921SBarry Smith /* SUBMANSEC = Sys */
14ac09b921SBarry Smith 
15030f984aSJacob Faibussowitsch /*E
16030f984aSJacob Faibussowitsch   PetscMemType - Memory type of a pointer
17030f984aSJacob Faibussowitsch 
1816a05f60SBarry Smith   Level: intermediate
19fe0d65a2SJacob Faibussowitsch 
2095bd0b28SBarry Smith   Note:
2187497f52SBarry Smith   `PETSC_MEMTYPE_KOKKOS` depends on the Kokkos backend configuration
223214990dSStefano Zampini 
230e6b6b59SJacob Faibussowitsch   Developer Notes:
240e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemTypeToString()`) to convert to string representation so
250e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
260e6b6b59SJacob Faibussowitsch 
27af27ebaaSBarry Smith   Encoding of the bitmask in binary\: xxxxyyyz
2816a05f60SBarry Smith .vb
2916a05f60SBarry Smith  z = 0                - Host memory
3016a05f60SBarry Smith  z = 1                - Device memory
3116a05f60SBarry Smith  yyy = 000            - CUDA-related memory
3216a05f60SBarry Smith  yyy = 001            - HIP-related memory
3316a05f60SBarry Smith  yyy = 010            - SYCL-related memory
3416a05f60SBarry Smith  xxxxyyy1 = 0000,0001 - CUDA memory
3516a05f60SBarry Smith  xxxxyyy1 = 0001,0001 - CUDA NVSHMEM memory
3616a05f60SBarry Smith  xxxxyyy1 = 0000,0011 - HIP memory
3716a05f60SBarry Smith  xxxxyyy1 = 0000,0101 - SYCL memory
3816a05f60SBarry Smith .ve
3916a05f60SBarry Smith 
4016a05f60SBarry Smith   Other types of memory, e.g., CUDA managed memory, can be added when needed.
4116a05f60SBarry Smith 
420e6b6b59SJacob Faibussowitsch .seealso: `PetscMemTypeToString()`, `VecGetArrayAndMemType()`,
430e6b6b59SJacob Faibussowitsch `PetscSFBcastWithMemTypeBegin()`, `PetscSFReduceWithMemTypeBegin()`
44030f984aSJacob Faibussowitsch E*/
45fe0d65a2SJacob Faibussowitsch typedef enum {
46fe0d65a2SJacob Faibussowitsch   PETSC_MEMTYPE_HOST    = 0,
47*ce78bad3SBarry Smith   PETSC_MEMTYPE_DEVICE  = 1,  /* 0x01 */
48*ce78bad3SBarry Smith   PETSC_MEMTYPE_CUDA    = 1,  /* 0x01 */
49*ce78bad3SBarry Smith   PETSC_MEMTYPE_NVSHMEM = 17, /* 0x11 */
50*ce78bad3SBarry Smith   PETSC_MEMTYPE_HIP     = 3,  /* 0x03 */
51*ce78bad3SBarry Smith   PETSC_MEMTYPE_SYCL    = 5   /* 0x05 */
52fe0d65a2SJacob Faibussowitsch } PetscMemType;
53c0288c05SSatish Balay #if PetscDefined(HAVE_CUDA)
54c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_CUDA
55c0288c05SSatish Balay #elif PetscDefined(HAVE_HIP)
56c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_HIP
57c0288c05SSatish Balay #elif PetscDefined(HAVE_SYCL)
58c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_SYCL
59c0288c05SSatish Balay #else
60c0288c05SSatish Balay   #define PETSC_MEMTYPE_KOKKOS PETSC_MEMTYPE_HOST
61c0288c05SSatish Balay #endif
62030f984aSJacob Faibussowitsch 
63030f984aSJacob Faibussowitsch #define PetscMemTypeHost(m)    (((m) & 0x1) == PETSC_MEMTYPE_HOST)
64030f984aSJacob Faibussowitsch #define PetscMemTypeDevice(m)  (((m) & 0x1) == PETSC_MEMTYPE_DEVICE)
65030f984aSJacob Faibussowitsch #define PetscMemTypeCUDA(m)    (((m) & 0xF) == PETSC_MEMTYPE_CUDA)
66030f984aSJacob Faibussowitsch #define PetscMemTypeHIP(m)     (((m) & 0xF) == PETSC_MEMTYPE_HIP)
67a2158755SJunchao Zhang #define PetscMemTypeSYCL(m)    (((m) & 0xF) == PETSC_MEMTYPE_SYCL)
68030f984aSJacob Faibussowitsch #define PetscMemTypeNVSHMEM(m) ((m) == PETSC_MEMTYPE_NVSHMEM)
69030f984aSJacob Faibussowitsch 
700e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
710e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
720e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
730e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
740e6b6b59SJacob Faibussowitsch   #endif
750e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeHost(PETSC_MEMTYPE_HOST), "");
760e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_DEVICE), "");
770e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_CUDA), "");
780e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_HIP), "");
790e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_SYCL), "");
800e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeHost(PETSC_MEMTYPE_NVSHMEM), "");
810e6b6b59SJacob Faibussowitsch 
820e6b6b59SJacob Faibussowitsch static_assert(!PetscMemTypeDevice(PETSC_MEMTYPE_HOST), "");
830e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_DEVICE), "");
840e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_CUDA), "");
850e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_HIP), "");
860e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_SYCL), "");
870e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeDevice(PETSC_MEMTYPE_NVSHMEM), "");
880e6b6b59SJacob Faibussowitsch 
890e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_CUDA), "");
900e6b6b59SJacob Faibussowitsch static_assert(PetscMemTypeCUDA(PETSC_MEMTYPE_NVSHMEM), "");
910e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
920e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
930e6b6b59SJacob Faibussowitsch   #endif
940e6b6b59SJacob Faibussowitsch #endif // __cplusplus
950e6b6b59SJacob Faibussowitsch 
PetscMemTypeToString(PetscMemType mtype)96d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemTypeToString(PetscMemType mtype)
97d71ae5a4SJacob Faibussowitsch {
980e6b6b59SJacob Faibussowitsch #ifdef __cplusplus
990e6b6b59SJacob Faibussowitsch   static_assert(PETSC_MEMTYPE_CUDA == PETSC_MEMTYPE_DEVICE, "");
1000e6b6b59SJacob Faibussowitsch #endif
1010e6b6b59SJacob Faibussowitsch #define PETSC_CASE_NAME(v) \
102d71ae5a4SJacob Faibussowitsch   case v: \
103d71ae5a4SJacob Faibussowitsch     return PetscStringize(v)
1040e6b6b59SJacob Faibussowitsch 
1050e6b6b59SJacob Faibussowitsch   switch (mtype) {
1060e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HOST);
1070e6b6b59SJacob Faibussowitsch     /* PETSC_CASE_NAME(PETSC_MEMTYPE_DEVICE); same as PETSC_MEMTYPE_CUDA */
1080e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_CUDA);
1090e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_NVSHMEM);
1100e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_HIP);
1110e6b6b59SJacob Faibussowitsch     PETSC_CASE_NAME(PETSC_MEMTYPE_SYCL);
1120e6b6b59SJacob Faibussowitsch   }
1130e6b6b59SJacob Faibussowitsch   PetscUnreachable();
1140e6b6b59SJacob Faibussowitsch   return "invalid";
1150e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_NAME
1160e6b6b59SJacob Faibussowitsch }
1170e6b6b59SJacob Faibussowitsch 
118edd03b47SJacob Faibussowitsch #define PETSC_OFFLOAD_VECKOKKOS_DEPRECATED PETSC_OFFLOAD_VECKOKKOS PETSC_DEPRECATED_ENUM(3, 17, 0, "PETSC_OFFLOAD_KOKKOS", )
1190e6b6b59SJacob Faibussowitsch 
120030f984aSJacob Faibussowitsch /*E
121030f984aSJacob Faibussowitsch   PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data
122030f984aSJacob Faibussowitsch 
12316a05f60SBarry Smith   Values:
12416a05f60SBarry Smith + `PETSC_OFFLOAD_UNALLOCATED` - no memory contains valid matrix entries; NEVER used for vectors
12516a05f60SBarry Smith . `PETSC_OFFLOAD_GPU`         - GPU has valid vector/matrix entries
12616a05f60SBarry Smith . `PETSC_OFFLOAD_CPU`         - CPU has valid vector/matrix entries
12716a05f60SBarry Smith . `PETSC_OFFLOAD_BOTH`        - Both GPU and CPU have valid vector/matrix entries and they match
12816a05f60SBarry 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.
12916a05f60SBarry Smith 
13016a05f60SBarry Smith   Level: developer
131030f984aSJacob Faibussowitsch 
13295bd0b28SBarry Smith   Developer Note:
1330e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscOffloadMaskToString()`) to convert to string representation so
1340e6b6b59SJacob Faibussowitsch   cannot be used in `PetscOptionsEnum()`.
1350e6b6b59SJacob Faibussowitsch 
1360e6b6b59SJacob Faibussowitsch .seealso: `PetscOffloadMaskToString()`, `PetscOffloadMaskToMemType()`, `PetscOffloadMaskToDeviceCopyMode()`
137030f984aSJacob Faibussowitsch E*/
138fe0d65a2SJacob Faibussowitsch typedef enum {
139*ce78bad3SBarry Smith   PETSC_OFFLOAD_UNALLOCATED          = 0,   /* 0x0 */
140*ce78bad3SBarry Smith   PETSC_OFFLOAD_CPU                  = 1,   /* 0x1 */
141*ce78bad3SBarry Smith   PETSC_OFFLOAD_GPU                  = 2,   /* 0x2 */
142*ce78bad3SBarry Smith   PETSC_OFFLOAD_BOTH                 = 3,   /* 0x3 */
143*ce78bad3SBarry Smith   PETSC_OFFLOAD_VECKOKKOS_DEPRECATED = 256, /* 0x100 */
144*ce78bad3SBarry Smith   PETSC_OFFLOAD_KOKKOS               = 256  /* 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 
PetscOffloadMaskToString(PetscOffloadMask mask)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 
PetscOffloadMaskToMemType(PetscOffloadMask mask)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 
21616a05f60SBarry Smith   Values:
21716a05f60SBarry Smith + `PETSC_DEVICE_INIT_NONE`  - PetscDevice is never initialized
21816a05f60SBarry Smith . `PETSC_DEVICE_INIT_LAZY`  - PetscDevice is initialized on demand
21916a05f60SBarry Smith - `PETSC_DEVICE_INIT_EAGER` - PetscDevice is initialized as soon as possible
22016a05f60SBarry Smith 
22116a05f60SBarry Smith   Level: beginner
222a4af0ceeSJacob Faibussowitsch 
22395bd0b28SBarry Smith   Note:
2240e6b6b59SJacob Faibussowitsch   `PETSC_DEVICE_INIT_NONE` implies that any initialization of `PetscDevice` is disallowed and
225a4af0ceeSJacob Faibussowitsch   doing so results in an error. Useful to ensure that no accelerator is used in a program.
226a4af0ceeSJacob Faibussowitsch 
2270e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceType`, `PetscDeviceInitialize()`,
2280e6b6b59SJacob Faibussowitsch `PetscDeviceInitialized()`, `PetscDeviceCreate()`
229a4af0ceeSJacob Faibussowitsch E*/
230a4af0ceeSJacob Faibussowitsch typedef enum {
231a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_NONE,
232a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_LAZY,
233a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_INIT_EAGER
234a4af0ceeSJacob Faibussowitsch } PetscDeviceInitType;
235a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceInitTypes[];
236a4af0ceeSJacob Faibussowitsch 
237a4af0ceeSJacob Faibussowitsch /*E
238a4af0ceeSJacob Faibussowitsch   PetscDeviceType - Kind of accelerator device backend
239030f984aSJacob Faibussowitsch 
24016a05f60SBarry Smith   Values:
24116a05f60SBarry Smith + `PETSC_DEVICE_HOST` - Host, no accelerator backend found
24216a05f60SBarry Smith . `PETSC_DEVICE_CUDA` - CUDA enabled GPU
24316a05f60SBarry Smith . `PETSC_DEVICE_HIP`  - ROCM/HIP enabled GPU
24416a05f60SBarry Smith . `PETSC_DEVICE_SYCL` - SYCL enabled device
24516a05f60SBarry Smith - `PETSC_DEVICE_MAX`  - Always 1 greater than the largest valid `PetscDeviceType`, invalid type, do not use
24616a05f60SBarry Smith 
24716a05f60SBarry Smith   Level: beginner
248030f984aSJacob Faibussowitsch 
24995bd0b28SBarry Smith   Note:
2500e6b6b59SJacob Faibussowitsch   One can also use the `PETSC_DEVICE_DEFAULT()` routine to get the current default `PetscDeviceType`.
251030f984aSJacob Faibussowitsch 
2520e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceInitType`, `PetscDeviceCreate()`, `PETSC_DEVICE_DEFAULT()`
253030f984aSJacob Faibussowitsch E*/
254030f984aSJacob Faibussowitsch typedef enum {
2550e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_HOST,
256a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_CUDA,
257a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_HIP,
258a2158755SJunchao Zhang   PETSC_DEVICE_SYCL,
259a4af0ceeSJacob Faibussowitsch   PETSC_DEVICE_MAX
260a4af0ceeSJacob Faibussowitsch } PetscDeviceType;
261a4af0ceeSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceTypes[];
262030f984aSJacob Faibussowitsch 
263a16fd2c9SJacob Faibussowitsch /*E
264a16fd2c9SJacob Faibussowitsch   PetscDeviceAttribute - Attribute detailing a property or feature of a `PetscDevice`
265a16fd2c9SJacob Faibussowitsch 
26616a05f60SBarry Smith   Values:
26716a05f60SBarry Smith + `PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK` - The maximum amount of shared memory per block in a device kernel
26816a05f60SBarry Smith - `PETSC_DEVICE_ATTR_MAX`                         - Invalid attribute, do not use
269a16fd2c9SJacob Faibussowitsch 
270a16fd2c9SJacob Faibussowitsch   Level: beginner
271a16fd2c9SJacob Faibussowitsch 
272a16fd2c9SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceGetAttribute()`
273a16fd2c9SJacob Faibussowitsch E*/
274a16fd2c9SJacob Faibussowitsch typedef enum {
275a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_SIZE_T_SHARED_MEM_PER_BLOCK,
276a16fd2c9SJacob Faibussowitsch   PETSC_DEVICE_ATTR_MAX
277a16fd2c9SJacob Faibussowitsch } PetscDeviceAttribute;
278a16fd2c9SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceAttributes[];
279a16fd2c9SJacob Faibussowitsch 
280030f984aSJacob Faibussowitsch /*S
28187497f52SBarry Smith   PetscDevice - Object to manage an accelerator "device" (usually a GPU)
282030f984aSJacob Faibussowitsch 
28316a05f60SBarry Smith   Level: beginner
28416a05f60SBarry Smith 
285af27ebaaSBarry Smith   Note:
2860e6b6b59SJacob Faibussowitsch   This object is used to house configuration and state of a device, but does not offer any
2870e6b6b59SJacob Faibussowitsch   ability to interact with or drive device computation. This functionality is facilitated
2880e6b6b59SJacob Faibussowitsch   instead by the `PetscDeviceContext` object.
289030f984aSJacob Faibussowitsch 
2900e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceType`, `PetscDeviceInitType`, `PetscDeviceCreate()`,
2910e6b6b59SJacob Faibussowitsch `PetscDeviceConfigure()`, `PetscDeviceDestroy()`, `PetscDeviceContext`,
2920e6b6b59SJacob Faibussowitsch `PetscDeviceContextSetDevice()`, `PetscDeviceContextGetDevice()`, `PetscDeviceGetAttribute()`
293030f984aSJacob Faibussowitsch S*/
294030f984aSJacob Faibussowitsch typedef struct _n_PetscDevice *PetscDevice;
295030f984aSJacob Faibussowitsch 
296030f984aSJacob Faibussowitsch /*E
297d9acb416SHong Zhang   PetscStreamType - indicates how a stream implementation will interact
298d9acb416SHong Zhang   with other streams and if it blocks the host.
299030f984aSJacob Faibussowitsch 
30016a05f60SBarry Smith   Values:
301d9acb416SHong Zhang + `PETSC_STREAM_DEFAULT`                  - Same as the default stream in CUDA or HIP. Streams of this type may or may not synchronize implicitly with other streams. It does not block the host.
302d9acb416SHong Zhang . `PETSC_STREAM_NONBLOCKING`              - Same as the nonblocking stream in CUDA or HIP. Streams of this type is truly asynchronous, and is blocked by nothing. It does not block the host. In CUDA, it is created with cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking).
303d9acb416SHong Zhang . `PETSC_STREAM_DEFAULT_WITH_BARRIER`     - Same as the default stream in CUDA or HIP. PETSc async functions using this kind of stream will end with a stream synchronization. Stream of this type may or may not synchronize implicitly with other streams.
304d9acb416SHong Zhang . `PETSC_STREAM_NONBLOCKING_WITH_BARRIER` - Same as the nonblocking stream in CUDA or HIP. PETSc async functions using this kind of stream will end with a stream synchronization. Streams of this type are truly asynchronous and are blocked by nothing.
30516a05f60SBarry Smith - `PETSC_STREAM_MAX`                - Always 1 greater than the largest `PetscStreamType`, do not use
306030f984aSJacob Faibussowitsch 
307030f984aSJacob Faibussowitsch   Level: intermediate
308030f984aSJacob Faibussowitsch 
309d9acb416SHong Zhang   Note:
310d9acb416SHong Zhang   The default stream, also known as the NULL stream or stream 0, can have two different behaviors: legacy behavior and per-thread behavior.
311d9acb416SHong Zhang   The behavior is determined at compile time. By default, the legacy default stream is used.
312d9acb416SHong Zhang   The legacy default stream implicitly synchronizes with per-thread default streams.
313d9acb416SHong Zhang   The per-thread default stream, like nonblocking streams, does not synchronizes with other per-thread streams, but synchronize with the default stream.
314d9acb416SHong Zhang   The per-thread default stream may be useful for running kernels launched from different threads concurrently on the same GPU when the Multi-Process Service is not available.
315d9acb416SHong Zhang   To use the per-thread default stream, one can enable it by using the nvcc option "--default-stream per-thread" or the hipcc option "-fgpu-default-stream=per-thread", depending on the backend used.
316d9acb416SHong Zhang 
317db781477SPatrick Sanan .seealso: `PetscDeviceContextSetStreamType()`, `PetscDeviceContextGetStreamType()`
318030f984aSJacob Faibussowitsch E*/
319030f984aSJacob Faibussowitsch typedef enum {
320d9acb416SHong Zhang   PETSC_STREAM_DEFAULT,
321d9acb416SHong Zhang   PETSC_STREAM_NONBLOCKING,
322d9acb416SHong Zhang   PETSC_STREAM_DEFAULT_WITH_BARRIER,
323d9acb416SHong Zhang   PETSC_STREAM_NONBLOCKING_WITH_BARRIER,
324a4af0ceeSJacob Faibussowitsch   PETSC_STREAM_MAX
325030f984aSJacob Faibussowitsch } PetscStreamType;
326030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscStreamTypes[];
327030f984aSJacob Faibussowitsch 
328030f984aSJacob Faibussowitsch /*E
3290e6b6b59SJacob Faibussowitsch   PetscDeviceContextJoinMode - Describes the type of join operation to perform in
3300e6b6b59SJacob Faibussowitsch   `PetscDeviceContextJoin()`
331030f984aSJacob Faibussowitsch 
33216a05f60SBarry Smith   Values:
33316a05f60SBarry Smith + `PETSC_DEVICE_CONTEXT_JOIN_DESTROY` - Destroy all incoming sub-contexts after join.
33416a05f60SBarry Smith . `PETSC_DEVICE_CONTEXT_JOIN_SYNC`    - Synchronize incoming sub-contexts after join.
33516a05f60SBarry Smith - `PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC` - Do not synchronize incoming sub-contexts after join.
336030f984aSJacob Faibussowitsch 
337030f984aSJacob Faibussowitsch   Level: beginner
338030f984aSJacob Faibussowitsch 
339db781477SPatrick Sanan .seealso: `PetscDeviceContext`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
340030f984aSJacob Faibussowitsch E*/
341030f984aSJacob Faibussowitsch typedef enum {
342030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_DESTROY,
343030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_SYNC,
344030f984aSJacob Faibussowitsch   PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC
345030f984aSJacob Faibussowitsch } PetscDeviceContextJoinMode;
346030f984aSJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceContextJoinModes[];
347030f984aSJacob Faibussowitsch 
348030f984aSJacob Faibussowitsch /*S
3490e6b6b59SJacob Faibussowitsch   PetscDeviceContext - Container to manage stream dependencies and the various solver handles
3500e6b6b59SJacob Faibussowitsch   for asynchronous device compute.
351030f984aSJacob Faibussowitsch 
352030f984aSJacob Faibussowitsch   Level: beginner
353030f984aSJacob Faibussowitsch 
3540e6b6b59SJacob Faibussowitsch .seealso: `PetscDevice`, `PetscDeviceContextCreate()`, `PetscDeviceContextSetDevice()`,
3550e6b6b59SJacob Faibussowitsch `PetscDeviceContextDestroy()`, `PetscDeviceContextFork()`, `PetscDeviceContextJoin()`
356030f984aSJacob Faibussowitsch S*/
3570e6b6b59SJacob Faibussowitsch typedef struct _p_PetscDeviceContext *PetscDeviceContext;
3580e6b6b59SJacob Faibussowitsch 
3590e6b6b59SJacob Faibussowitsch /*E
36016a05f60SBarry Smith   PetscDeviceCopyMode - Describes the copy direction of a device-aware `memcpy`
3610e6b6b59SJacob Faibussowitsch 
36216a05f60SBarry Smith   Values:
36316a05f60SBarry Smith + `PETSC_DEVICE_COPY_HTOH` - Copy from host memory to host memory
36416a05f60SBarry Smith . `PETSC_DEVICE_COPY_DTOH` - Copy from device memory to host memory
36516a05f60SBarry Smith . `PETSC_DEVICE_COPY_HTOD` - Copy from host memory to device memory
36616a05f60SBarry Smith . `PETSC_DEVICE_COPY_DTOD` - Copy from device memory to device memory
36716a05f60SBarry Smith - `PETSC_DEVICE_COPY_AUTO` - Infer the copy direction from the pointers
3680e6b6b59SJacob Faibussowitsch 
3690e6b6b59SJacob Faibussowitsch   Level: beginner
3700e6b6b59SJacob Faibussowitsch 
3710e6b6b59SJacob Faibussowitsch .seealso: `PetscDeviceArrayCopy()`, `PetscDeviceMemcpy()`
3720e6b6b59SJacob Faibussowitsch E*/
3730e6b6b59SJacob Faibussowitsch typedef enum {
3740e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOH,
3750e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOH,
3760e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_HTOD,
3770e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_DTOD,
3780e6b6b59SJacob Faibussowitsch   PETSC_DEVICE_COPY_AUTO,
3790e6b6b59SJacob Faibussowitsch } PetscDeviceCopyMode;
3800e6b6b59SJacob Faibussowitsch PETSC_EXTERN const char *const PetscDeviceCopyModes[];
3810e6b6b59SJacob Faibussowitsch 
PetscOffloadMaskToDeviceCopyMode(PetscOffloadMask dest,PetscOffloadMask src)382d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PetscDeviceCopyMode PetscOffloadMaskToDeviceCopyMode(PetscOffloadMask dest, PetscOffloadMask src)
383d71ae5a4SJacob Faibussowitsch {
3840e6b6b59SJacob Faibussowitsch   PetscDeviceCopyMode mode;
3850e6b6b59SJacob Faibussowitsch 
3860e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
3870e6b6b59SJacob Faibussowitsch   PetscAssertAbort(dest != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy to unallocated");
3880e6b6b59SJacob Faibussowitsch   PetscAssertAbort(src != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot copy from unallocated");
3890e6b6b59SJacob Faibussowitsch 
3900e6b6b59SJacob Faibussowitsch   if (PetscOffloadDevice(dest)) {
3910e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOD : PETSC_DEVICE_COPY_DTOD;
3920e6b6b59SJacob Faibussowitsch   } else {
3930e6b6b59SJacob Faibussowitsch     mode = PetscOffloadHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
3940e6b6b59SJacob Faibussowitsch   }
3950e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(mode);
3960e6b6b59SJacob Faibussowitsch }
3970e6b6b59SJacob Faibussowitsch 
PetscMemTypeToDeviceCopyMode(PetscMemType dest,PetscMemType src)398d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 PetscDeviceCopyMode PetscMemTypeToDeviceCopyMode(PetscMemType dest, PetscMemType src)
399d71ae5a4SJacob Faibussowitsch {
4000e6b6b59SJacob Faibussowitsch   if (PetscMemTypeHost(dest)) {
4010e6b6b59SJacob Faibussowitsch     return PetscMemTypeHost(src) ? PETSC_DEVICE_COPY_HTOH : PETSC_DEVICE_COPY_DTOH;
4020e6b6b59SJacob Faibussowitsch   } else {
4030e6b6b59SJacob Faibussowitsch     return PetscMemTypeDevice(src) ? PETSC_DEVICE_COPY_DTOD : PETSC_DEVICE_COPY_HTOD;
4040e6b6b59SJacob Faibussowitsch   }
4050e6b6b59SJacob Faibussowitsch }
4060e6b6b59SJacob Faibussowitsch 
4070e6b6b59SJacob Faibussowitsch /*E
4080e6b6b59SJacob Faibussowitsch   PetscMemoryAccessMode - Describes the intended usage of a memory region
4090e6b6b59SJacob Faibussowitsch 
41016a05f60SBarry Smith   Values:
41116a05f60SBarry Smith + `PETSC_MEMORY_ACCESS_READ`       - Read only
41216a05f60SBarry Smith . `PETSC_MEMORY_ACCESS_WRITE`      - Write only
41316a05f60SBarry Smith - `PETSC_MEMORY_ACCESS_READ_WRITE` - Read and write
41416a05f60SBarry Smith 
41516a05f60SBarry Smith   Level: beginner
4160e6b6b59SJacob Faibussowitsch 
4170e6b6b59SJacob Faibussowitsch   Notes:
4180e6b6b59SJacob Faibussowitsch   This `enum` is a bitmask with the following encoding (assuming 2 bit)\:
4190e6b6b59SJacob Faibussowitsch 
4200e6b6b59SJacob Faibussowitsch .vb
4210e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ       = 0b01
4220e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_WRITE      = 0b10
4230e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ_WRITE = 0b11
4240e6b6b59SJacob Faibussowitsch 
4250e6b6b59SJacob Faibussowitsch   // consequently
4260e6b6b59SJacob Faibussowitsch   PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE = PETSC_MEMORY_ACCESS_READ_WRITE
4270e6b6b59SJacob Faibussowitsch .ve
4280e6b6b59SJacob Faibussowitsch 
429aaa8cc7dSPierre Jolivet   The following convenience macros are also provided\:
4300e6b6b59SJacob Faibussowitsch 
43116a05f60SBarry Smith + `PetscMemoryAccessRead(mode)` - `true` if `mode` is any kind of read, `false` otherwise
43216a05f60SBarry Smith - `PetscMemoryAccessWrite(mode)` - `true` if `mode` is any kind of write, `false` otherwise
4330e6b6b59SJacob Faibussowitsch 
434af27ebaaSBarry Smith   Developer Note:
4350e6b6b59SJacob Faibussowitsch   This enum uses a function (`PetscMemoryAccessModeToString()`) to convert values to string
4360e6b6b59SJacob Faibussowitsch   representation, so cannot be used in `PetscOptionsEnum()`.
4370e6b6b59SJacob Faibussowitsch 
4380e6b6b59SJacob Faibussowitsch .seealso: `PetscMemoryAccessModeToString()`, `PetscDevice`, `PetscDeviceContext`
4390e6b6b59SJacob Faibussowitsch E*/
4400e6b6b59SJacob Faibussowitsch typedef enum {
441*ce78bad3SBarry Smith   PETSC_MEMORY_ACCESS_READ       = 1, /* 01 */
442*ce78bad3SBarry Smith   PETSC_MEMORY_ACCESS_WRITE      = 2, /* 10 */
443*ce78bad3SBarry Smith   PETSC_MEMORY_ACCESS_READ_WRITE = 3  /* 11 */
4440e6b6b59SJacob Faibussowitsch } PetscMemoryAccessMode;
4450e6b6b59SJacob Faibussowitsch 
4460e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessRead(m)  (((m) & PETSC_MEMORY_ACCESS_READ) == PETSC_MEMORY_ACCESS_READ)
4470e6b6b59SJacob Faibussowitsch #define PetscMemoryAccessWrite(m) (((m) & PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_WRITE)
4480e6b6b59SJacob Faibussowitsch 
4490e6b6b59SJacob Faibussowitsch #if defined(__cplusplus)
4500e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4510e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic push
4520e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic ignored "-Wtautological-compare"
4530e6b6b59SJacob Faibussowitsch   #endif
4540e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ), "");
4550e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_READ_WRITE), "");
4560e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessRead(PETSC_MEMORY_ACCESS_WRITE), "");
4570e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_WRITE), "");
4580e6b6b59SJacob Faibussowitsch static_assert(PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ_WRITE), "");
4590e6b6b59SJacob Faibussowitsch static_assert(!PetscMemoryAccessWrite(PETSC_MEMORY_ACCESS_READ), "");
4600e6b6b59SJacob Faibussowitsch static_assert((PETSC_MEMORY_ACCESS_READ | PETSC_MEMORY_ACCESS_WRITE) == PETSC_MEMORY_ACCESS_READ_WRITE, "");
4610e6b6b59SJacob Faibussowitsch   #if PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
4620e6b6b59SJacob Faibussowitsch     #pragma GCC diagnostic pop
4630e6b6b59SJacob Faibussowitsch   #endif
4640e6b6b59SJacob Faibussowitsch #endif
4650e6b6b59SJacob Faibussowitsch 
PetscMemoryAccessModeToString(PetscMemoryAccessMode mode)466d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD static inline PETSC_CONSTEXPR_14 const char *PetscMemoryAccessModeToString(PetscMemoryAccessMode mode)
467d71ae5a4SJacob Faibussowitsch {
4680e6b6b59SJacob Faibussowitsch #define PETSC_CASE_RETURN(v) \
469d71ae5a4SJacob Faibussowitsch   case v: \
470d71ae5a4SJacob Faibussowitsch     return PetscStringize(v)
4710e6b6b59SJacob Faibussowitsch 
4720e6b6b59SJacob Faibussowitsch   switch (mode) {
4730e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ);
4740e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_WRITE);
4750e6b6b59SJacob Faibussowitsch     PETSC_CASE_RETURN(PETSC_MEMORY_ACCESS_READ_WRITE);
4760e6b6b59SJacob Faibussowitsch   }
4770e6b6b59SJacob Faibussowitsch   PetscUnreachable();
4780e6b6b59SJacob Faibussowitsch   return "invalid";
4790e6b6b59SJacob Faibussowitsch #undef PETSC_CASE_RETURN
4800e6b6b59SJacob Faibussowitsch }
4810e6b6b59SJacob Faibussowitsch 
4820e6b6b59SJacob Faibussowitsch #undef PETSC_SHOULD_SILENCE_GCC_TAUTOLOGICAL_COMPARE_WARNING
483