/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/integration/lattice/integrator_lat_1d.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/integration/lattice/integrator_lat_1d.hh Source File
DiFfRG
integrator_lat_1d.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
5
6// standard libraries
7#include <array>
8
9namespace DiFfRG
10{
11 template <typename NT, typename KERNEL, typename ExecutionSpace> class IntegratorLat1D
12 {
13 public:
17 using ctype = typename get_type::ctype<NT>;
18 using execution_space = ExecutionSpace;
19
20 IntegratorLat1D(const std::array<uint, 1> grid_size, const std::array<ctype, 1> a, bool q0_symmetric = false)
22 {
23 if (grid_size[0] % 2 != 0) throw std::runtime_error("IntegratorLat1D: Grid size must be even");
24 }
25
26 void set_a(const std::array<ctype, 1> a) { this->a = a; }
27 void set_q0_symmetric(bool symmetric) { this->q0_symmetric = symmetric; }
28
29 template <typename... T> void get(NT &dest, const T &...t) const
30 {
31 // create an execution space
32 ExecutionSpace space;
33
34 Kokkos::View<NT, typename ExecutionSpace::memory_space> result(Kokkos::view_alloc(space, "result"));
35
36 get(space, result, t...);
37 space.fence();
38
39 auto result_host = Kokkos::create_mirror_view(result);
40 Kokkos::deep_copy(space, result_host, result);
41 dest = result_host();
42 }
43
44 template <typename OT, typename... T>
45 requires(!std::is_same_v<OT, NT>)
46 void get(OT &dest, const T &...t) const
47 {
48 ExecutionSpace space;
49 get(space, dest, t...);
50 }
51
52 template <typename OT, typename... T>
53 requires(!std::is_same_v<OT, NT>)
54 void get(ExecutionSpace &space, OT &dest, const T &...t) const
55 {
56 const auto args = std::make_tuple(t...);
57
58 const ctype fac = powr<-1>(a[0] * (ctype)grid_size[0]);
59
60 const uint q0_mult = (q0_symmetric ? 2 : 1);
61
62 const ctype xfac = 2 * M_PI / (ctype)grid_size[0] / a[0];
63 const auto x0size = grid_size[0] / q0_mult;
64
65 Kokkos::parallel_reduce(
66 "integral_lat_1D", // name of the kernel
67 Kokkos::RangePolicy<ExecutionSpace, Kokkos::IndexType<uint>>(space, 0,
68 x0size), // range of the kernel
69 KOKKOS_LAMBDA(const uint idx_x, NT &update) {
70 const ctype q0 = xfac * idx_x;
71 const NT result = std::apply([&](const auto &...args) { return KERNEL::kernel(q0, args...); }, args);
72 update += q0_mult * fac * result;
73 },
74 SumPlus<NT, NT, ExecutionSpace>(dest, KERNEL::constant(t...)));
75 }
76
77 template <typename view_type, typename Coordinates, typename... Args>
78 void map(ExecutionSpace &space, const view_type integral_view, const Coordinates &coordinates, const Args &...args)
79 {
80 const auto m_args = std::make_tuple(args...);
81
82 using TeamPolicy = Kokkos::TeamPolicy<ExecutionSpace>;
83 using TeamType = Kokkos::TeamPolicy<ExecutionSpace>::member_type;
84
85 const ctype fac = powr<-1>(a[0] * (ctype)grid_size[0]);
86
87 const uint q0_mult = (q0_symmetric ? 2 : 1);
88
89 const ctype xfac = 2 * M_PI / (ctype)grid_size[0] / a[0];
90 const auto x0size = grid_size[0] / q0_mult;
91
92 Kokkos::parallel_for(
93 Kokkos::TeamPolicy(space, integral_view.size(), Kokkos::AUTO), KOKKOS_LAMBDA(const TeamType &team) {
94 // get the current (continuous) index
95 const uint k = team.league_rank();
96 // make subview
97 auto subview = Kokkos::subview(integral_view, k);
98 // get the position for the current index
99 const auto idx = coordinates.from_linear_index(k);
100 const auto pos = coordinates.forward(idx);
101
102 const auto full_args = std::tuple_cat(pos, m_args);
103
104 // compute the constant value
105 // TODO: do this only once...
106 const auto constant =
107 std::apply([&](const auto &...iargs) { return KERNEL::constant(iargs...); }, full_args);
108
109 Kokkos::parallel_reduce(
110 Kokkos::TeamThreadRange(team, 0, x0size), // range of the kernel
111 [&](const uint idx_x, NT &update) {
112 const ctype q0 = xfac * idx_x;
113 const NT result =
114 std::apply([&](const auto &...iargs) { return KERNEL::kernel(q0, iargs...); }, full_args);
115 update += q0_mult * fac * result;
116 },
117 SumPlus<NT, NT, ExecutionSpace>(subview, constant));
118 });
119 }
120
121 template <typename Coordinates, typename... Args>
122 auto map(NT *dest, const Coordinates &coordinates, const Args &...args)
123 {
124 // create an execution space
125 ExecutionSpace space;
126
127 // create unmanaged host view for dest
128 auto dest_view = Kokkos::View<NT *, CPU_memory, Kokkos::MemoryUnmanaged>(dest, coordinates.size());
129
130 // create device view for dest
131 auto dest_device_view = Kokkos::View<NT *, ExecutionSpace>(
132 Kokkos::view_alloc(space, "MapIntegrators_device_view"), coordinates.size());
133
134 // run the map function
135 map(space, dest_device_view, coordinates, args...);
136
137 // copy the result from device to host
138 auto dest_host_view = Kokkos::create_mirror_view(space, dest_device_view);
139 Kokkos::deep_copy(space, dest_host_view, dest_device_view);
140
141 // copy the result from the mirror to the requested destination
142 Kokkos::deep_copy(space, dest_view, dest_host_view);
143
144 return std::move(space);
145 }
146
147 const std::array<uint, 1> grid_size;
148
149 private:
150 std::array<ctype, 1> a;
152 };
153} // namespace DiFfRG
Definition integrator_lat_1d.hh:12
void get(ExecutionSpace &space, OT &dest, const T &...t) const
Definition integrator_lat_1d.hh:54
void get(NT &dest, const T &...t) const
Definition integrator_lat_1d.hh:29
ExecutionSpace execution_space
Definition integrator_lat_1d.hh:18
void set_q0_symmetric(bool symmetric)
Definition integrator_lat_1d.hh:27
IntegratorLat1D(const std::array< uint, 1 > grid_size, const std::array< ctype, 1 > a, bool q0_symmetric=false)
Definition integrator_lat_1d.hh:20
auto map(NT *dest, const Coordinates &coordinates, const Args &...args)
Definition integrator_lat_1d.hh:122
bool q0_symmetric
Definition integrator_lat_1d.hh:151
void map(ExecutionSpace &space, const view_type integral_view, const Coordinates &coordinates, const Args &...args)
Definition integrator_lat_1d.hh:78
void set_a(const std::array< ctype, 1 > a)
Definition integrator_lat_1d.hh:26
void get(OT &dest, const T &...t) const
Definition integrator_lat_1d.hh:46
const std::array< uint, 1 > grid_size
Definition integrator_lat_1d.hh:147
typename get_type::ctype< NT > ctype
Numerical type to be used for integration tasks e.g. the argument or possible jacobians.
Definition integrator_lat_1d.hh:17
std::array< ctype, 1 > a
Definition integrator_lat_1d.hh:150
typename internal::_ctype< CT >::value ctype
Definition types.hh:134
Definition complex_math.hh:10
unsigned int uint
Definition utils.hh:24
An extension of the Kokkos::Sum reducer that adds a constant value to the result.
Definition kokkos.hh:66