MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
backends.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_BACKENDS_HPP
13#define MFEM_BACKENDS_HPP
14
15#include "../config/config.hpp"
16
17#if defined(MFEM_USE_CUDA) && defined(__CUDACC__)
18#include <cusparse.h>
19#include <library_types.h>
20#include <cuda_runtime.h>
21#include <cuda.h>
22#endif
23#include "cuda.hpp"
24
25#if defined(MFEM_USE_HIP) && defined(__HIP__)
26#include <hip/hip_runtime.h>
27#endif
28#include "hip.hpp"
29
30#ifdef MFEM_USE_OCCA
31#include "occa.hpp"
32#endif
33
34#ifdef MFEM_USE_RAJA
35// The following two definitions suppress CUB and THRUST deprecation warnings
36// about requiring c++14 with c++11 deprecated but still supported (to be
37// removed in a future release).
38#define CUB_IGNORE_DEPRECATED_CPP_DIALECT
39#define THRUST_IGNORE_DEPRECATED_CPP_DIALECT
40#include "RAJA/RAJA.hpp"
41#if defined(RAJA_ENABLE_CUDA) && !defined(MFEM_USE_CUDA)
42#error When RAJA is built with CUDA, MFEM_USE_CUDA=YES is required
43#endif
44#endif
45
46#if !defined(MFEM_USE_CUDA_OR_HIP)
47#define MFEM_DEVICE
48#define MFEM_HOST
49#define MFEM_LAMBDA
50// #define MFEM_HOST_DEVICE // defined in config/config.hpp
51// MFEM_DEVICE_SYNC is made available for debugging purposes
52#define MFEM_DEVICE_SYNC
53// MFEM_STREAM_SYNC is used for UVM and MPI GPU-Aware kernels
54#define MFEM_STREAM_SYNC
55#endif
56
57#if !((defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__)) || \
58 (defined(MFEM_USE_HIP) && defined(__HIP_DEVICE_COMPILE__)))
59#define MFEM_SHARED
60#define MFEM_SYNC_THREAD
61#define MFEM_BLOCK_ID(k) 0
62#define MFEM_THREAD_ID(k) 0
63#define MFEM_THREAD_SIZE(k) 1
64#define MFEM_FOREACH_THREAD(i,k,N) for(int i=0; i<N; i++)
65#define MFEM_FOREACH_THREAD_DIRECT(i,k,N) MFEM_FOREACH_THREAD(i,k,N)
66#endif
67
68// 'double' and 'float' atomicAdd implementation for previous versions of CUDA
69#if defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__) && (__CUDA_ARCH__ < 600)
70MFEM_DEVICE inline mfem::real_t atomicAdd(mfem::real_t *add, mfem::real_t val)
71{
72 unsigned long long int *ptr = (unsigned long long int *) add;
73 unsigned long long int old = *ptr, reg;
74 do
75 {
76 reg = old;
77 old = atomicCAS(ptr, reg,
78#ifdef MFEM_USE_SINGLE
79 __float_as_int(val + __int_as_float(reg)));
80#else
81 __double_as_longlong(val + __longlong_as_double(reg)));
82#endif
83 }
84 while (reg != old);
85#ifdef MFEM_USE_SINGLE
86 return __int_as_float(old);
87#else
88 return __longlong_as_double(old);
89#endif
90}
91#endif
92
93template <typename T>
94MFEM_HOST_DEVICE T AtomicAdd(T &add, const T val)
95{
96#if ((defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__)) || \
97 (defined(MFEM_USE_HIP) && defined(__HIP_DEVICE_COMPILE__)))
98 return atomicAdd(&add,val);
99#else
100 T old = add;
101#ifdef MFEM_USE_OPENMP
102 #pragma omp atomic
103#endif
104 add += val;
105 return old;
106#endif
107}
108
109#endif // MFEM_BACKENDS_HPP
MFEM_HOST_DEVICE T AtomicAdd(T &add, const T val)
Definition backends.hpp:94
MFEM_DEVICE mfem::real_t atomicAdd(mfem::real_t *add, mfem::real_t val)
Definition backends.hpp:70
float real_t
Definition config.hpp:46