12#ifndef MFEM_BACKENDS_HPP
13#define MFEM_BACKENDS_HPP
17#if defined(MFEM_USE_CUDA)
19#include <library_types.h>
20#include <cuda_runtime.h>
25#if defined(MFEM_USE_HIP)
26#include <hip/hip_runtime.h>
38#define CUB_IGNORE_DEPRECATED_CPP_DIALECT
39#define THRUST_IGNORE_DEPRECATED_CPP_DIALECT
41#include "RAJA/RAJA.hpp"
42#if defined(RAJA_ENABLE_CUDA) && !defined(MFEM_USE_CUDA)
43#error When RAJA is built with CUDA, MFEM_USE_CUDA=YES is required
47#if !defined(MFEM_USE_CUDA_OR_HIP)
49#define MFEM_DEVICE_SYNC
51#define MFEM_STREAM_SYNC
54#if !defined(MFEM_USE_CUDA_OR_HIP_LANG)
59#define MFEM_LAUNCH_BOUNDS(...)
62#if !((defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__)) || \
63 (defined(MFEM_USE_HIP) && defined(__HIP_DEVICE_COMPILE__)))
65#define MFEM_SYNC_THREAD
66#define MFEM_BLOCK_ID(k) 0
67#define MFEM_THREAD_ID(k) 0
68#define MFEM_THREAD_SIZE(k) 1
69#define MFEM_FOREACH_THREAD(i,k,N) for(int i=0; i<N; i++)
70#define MFEM_FOREACH_THREAD_DIRECT(i,k,N) MFEM_FOREACH_THREAD(i,k,N)
75#define MFEM_FOREACH_THREAD_DIRECT_3D(ix, iy, iz, k, SX, SY, SZ) \
76 for (int iz = 0; iz < SZ; ++iz) \
77 for (int iy = 0; iy < SY; ++iy) \
78 for (int ix = 0; ix < SX; ++ix)
85#define MFEM_FOREACH_THREAD_DIRECT_3D_OFFSET(ix, iy, iz, k, SX, SY, SZ, OX, \
87 MFEM_FOREACH_THREAD_DIRECT_3D(ix, iy, iz, k, SX, SY, SZ)
91#if defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__) && (__CUDA_ARCH__ < 600)
94 unsigned long long int *ptr = (
unsigned long long int *) add;
95 unsigned long long int old = *ptr, reg;
99 old = atomicCAS(ptr, reg,
100#ifdef MFEM_USE_SINGLE
101 __float_as_int(val + __int_as_float(reg)));
103 __double_as_longlong(val + __longlong_as_double(reg)));
107#ifdef MFEM_USE_SINGLE
108 return __int_as_float(old);
110 return __longlong_as_double(old);
118#if ((defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__)) || \
119 (defined(MFEM_USE_HIP) && defined(__HIP_DEVICE_COMPILE__)))
123#ifdef MFEM_USE_OPENMP
131namespace mfem::internal
134#if defined(MFEM_USE_CUDA_OR_HIP) && !defined(MFEM_USE_CUDA_OR_HIP_LANG)
135static constexpr bool can_compile_kernels =
false;
137static constexpr bool can_compile_kernels =
true;
140template <
bool can_compile_kernels = can_compile_kernels>
141void RequireKernelCompilation()
145 "The calling function needs to be compiled with CUDA/HIP language!");
MFEM_HOST_DEVICE T AtomicAdd(T &add, const T val)
MFEM_DEVICE mfem::real_t atomicAdd(mfem::real_t *add, mfem::real_t val)