12#include <Kokkos_Core.hpp>
13#if defined(__CUDACC__)
17#include <hip/hip_runtime.h>
20#include "ddc/discrete_domain.hpp"
21#include "ddc/discrete_space.hpp"
22#include "ddc/dual_discretization.hpp"
28#if defined(__CUDACC__)
29#define CUDA_THROW_ON_ERROR(val) ddc::detail::cuda_throw_on_error((val), #val, __FILE__, __LINE__)
31void cuda_throw_on_error(
33 const char*
const func,
34 const char*
const file,
37 if (err != cudaSuccess) {
39 ss <<
"CUDA Runtime Error at: " << file <<
":" << line << std::endl;
40 ss << cudaGetErrorString(err) <<
" " << func << std::endl;
41 throw std::runtime_error(ss.str());
44#elif defined(__HIPCC__)
45#define HIP_THROW_ON_ERROR(val) ddc::detail::hip_throw_on_error((val), #val, __FILE__, __LINE__)
47void hip_throw_on_error(T
const err,
const char*
const func,
const char*
const file,
const int line)
49 if (err != hipSuccess) {
51 ss <<
"HIP Runtime Error at: " << file <<
":" << line << std::endl;
52 ss << hipGetErrorString(err) <<
" " << func << std::endl;
53 throw std::runtime_error(ss.str());
58template <
class DDim,
class MemorySpace>
59using ddim_impl_t =
typename DDim::
template Impl<MemorySpace>;
75 alignas(T) Kokkos::Array<std::byte,
sizeof(T)> m_data;
78 KOKKOS_FORCEINLINE_FUNCTION
81 return reinterpret_cast<T*>(m_data.data());
84 KOKKOS_FORCEINLINE_FUNCTION
87 return *
reinterpret_cast<T*>(m_data.data());
90 KOKKOS_FORCEINLINE_FUNCTION
93 return reinterpret_cast<T*>(m_data.data());
98inline std::optional<std::map<std::string, std::function<
void()>>> g_discretization_store;
102inline std::optional<DualDiscretization<DDim>> g_discrete_space_dual;
104#if defined(__CUDACC__)
107__constant__ gpu_proxy<ddim_impl_t<DDim, Kokkos::CudaSpace>> g_discrete_space_device;
108#elif defined(__HIPCC__)
112__constant__ gpu_proxy<ddim_impl_t<DDim, Kokkos::HIPSpace>> g_discrete_space_device;
115inline void display_discretization_store(std::ostream& os)
117 if (g_discretization_store) {
118 os <<
"The host discretization store is initialized:\n";
119 for (
auto const& [key, value] : *g_discretization_store) {
120 os <<
" - " << key <<
"\n";
123 os <<
"The host discretization store is not initialized:\n";
127template <
class Tuple, std::size_t... Ids>
128auto extract_after(Tuple&& t, std::index_sequence<Ids...>)
130 return std::make_tuple(std::move(std::get<Ids + 1>(t))...);
136
137
138
139template <
class DDim,
class... Args>
142 if (detail::g_discrete_space_dual<DDim>) {
143 throw std::runtime_error(
"Discrete space function already initialized.");
145 detail::g_discrete_space_dual<DDim>.emplace(std::forward<Args>(args)...);
146 detail::g_discretization_store->emplace(
typeid(DDim).name(), []() {
147 detail::g_discrete_space_dual<DDim>.reset();
149#if defined(__CUDACC__)
150 CUDA_THROW_ON_ERROR(cudaMemcpyToSymbol(
151 detail::g_discrete_space_device<DDim>,
152 &detail::g_discrete_space_dual<DDim>->get_device(),
153 sizeof(detail::g_discrete_space_dual<DDim>->get_device())));
154#elif defined(__HIPCC__)
155 HIP_THROW_ON_ERROR(hipMemcpyToSymbol(
156 detail::g_discrete_space_device<DDim>,
157 &detail::g_discrete_space_dual<DDim>->get_device(),
158 sizeof(detail::g_discrete_space_dual<DDim>->get_device())));
163
164
165
166
167template <
class DDimImpl,
class Arg>
170 using DDim =
typename DDimImpl::discrete_dimension_type;
171 init_discrete_space<DDim>(std::move(std::get<0>(a)));
172 return std::get<1>(a);
176
177
178
179
180template <
class DDimImpl,
class... Args>
181std::enable_if_t<2 <=
sizeof...(Args), std::tuple<Args...>> init_discrete_space(
182 std::tuple<DDimImpl, Args...>&& a)
184 using DDim =
typename DDimImpl::discrete_dimension_type;
185 init_discrete_space<DDim>(std::move(std::get<0>(a)));
186 return detail::extract_after(std::move(a), std::index_sequence_for<Args...>());
189template <
class DDim,
class MemorySpace = DDC_CURRENT_KOKKOS_SPACE>
192 if constexpr (std::is_same_v<MemorySpace, Kokkos::HostSpace>) {
193 return detail::g_discrete_space_dual<DDim>->get_host();
195#if defined(__CUDACC__)
196 else if constexpr (std::is_same_v<MemorySpace, Kokkos::CudaSpace>) {
197 return *detail::g_discrete_space_device<DDim>;
199#elif defined(__HIPCC__)
200 else if constexpr (std::is_same_v<MemorySpace, Kokkos::HIPSpace>) {
201 return *detail::g_discrete_space_device<DDim>;
205 static_assert(std::is_same_v<MemorySpace, MemorySpace>,
"Memory space not handled");
212 return detail::g_discrete_space_dual<DDim>->get_host();
Definition: aligned_allocator.hpp:9
void init_discrete_space(Args &&... args)
Initialize (emplace) a global singleton discrete space.
Definition: discrete_space.hpp:140
detail::ddim_impl_t< DDim, Kokkos::HostSpace > const & host_discrete_space()
Definition: discrete_space.hpp:210
std::enable_if_t< 2<=sizeof...(Args), std::tuple< Args... > > init_discrete_space(std::tuple< DDimImpl, Args... > &&a){ using DDim=typename DDimImpl::discrete_dimension_type;init_discrete_space< DDim >(std::move(std::get< 0 >(a)));return detail::extract_after(std::move(a), std::index_sequence_for< Args... >());}template< class DDim, class MemorySpace=DDC_CURRENT_KOKKOS_SPACE > KOKKOS_FORCEINLINE_FUNCTION detail::ddim_impl_t< DDim, MemorySpace > const & discrete_space()
Move construct a global singleton discrete space and pass through remaining arguments.
Definition: discrete_space.hpp:190
Arg init_discrete_space(std::tuple< DDimImpl, Arg > &&a)
Move construct a global singleton discrete space and pass through the other argument.
Definition: discrete_space.hpp:168