diff --git a/first_steps.html b/first_steps.html index 252da8d1a..eb0979ccf 100644 --- a/first_steps.html +++ b/first_steps.html @@ -112,6 +112,10 @@

Once the types are defined, we can start the main function where we will define our various domains.

int main(int argc, char** argv)
{
+
#ifdef DDC_BUILD_PDI_WRAPPER
+
auto pdi_conf = PC_parse_string("");
+
PDI_init(pdi_conf);
+
#endif
ddc::ScopeGuard scope(argc, argv);
// some parameters that would typically be read from some form of
diff --git a/heat_equation.html b/heat_equation.html index efad5a104..2113a2b73 100644 --- a/heat_equation.html +++ b/heat_equation.html @@ -97,238 +97,254 @@

a discrete 65 std::cout << std::setw(6) << temp_slice(ix);

66 });
67 std::cout << " }" << std::endl;
-
68}
-
70
-
71
-
73int main(int argc, char** argv)
-
74{
-
75 ddc::ScopeGuard scope(argc, argv);
-
76
-
77 // some parameters that would typically be read from some form of
-
78 // configuration file in a more realistic code
-
79
-
81 // Start of the domain of interest in the X dimension
-
82 double const x_start = -1.;
-
83 // End of the domain of interest in the X dimension
-
84 double const x_end = 1.;
-
85 // Number of discretization points in the X dimension
-
86 size_t const nb_x_points = 10;
-
87 // Thermal diffusion coefficient
-
88 double const kx = .01;
-
89 // Start of the domain of interest in the Y dimension
-
90 double const y_start = -1.;
-
91 // End of the domain of interest in the Y dimension
-
92 double const y_end = 1.;
-
93 // Number of discretization points in the Y dimension
-
94 size_t const nb_y_points = 100;
-
95 // Thermal diffusion coefficient
-
96 double const ky = .002;
-
97 // Simulated time at which to start simulation
-
98 double const start_time = 0.;
-
99 // Simulated time to reach as target of the simulation
-
100 double const end_time = 10.;
-
101 // Number of time-steps between outputs
-
102 ptrdiff_t const t_output_period = 10;
-
104
-
107 // Number of ghost points to use on each side in X
-
108 ddc::DiscreteVector<DDimX> static constexpr gwx {1};
-
110
-
112 // Initialization of the global domain in X with gwx ghost points on
-
113 // each side
-
114 auto const [x_domain, ghosted_x_domain, x_pre_ghost, x_post_ghost]
-
115 = ddc::init_discrete_space(DDimX::init_ghosted(
-
116 ddc::Coordinate<X>(x_start),
-
117 ddc::Coordinate<X>(x_end),
-
118 ddc::DiscreteVector<DDimX>(nb_x_points),
-
119 gwx));
+
68
+
69#ifdef DDC_BUILD_PDI_WRAPPER
+
70 ddc::PdiEvent("display")
+
71 .with("temp", temp)
+
72 .and_with("mean_temp", mean_temp)
+
73 .and_with("temp_slice", temp_slice);
+
74#endif
+
75}
+
77
+
78
+
80int main(int argc, char** argv)
+
81{
+
82#ifdef DDC_BUILD_PDI_WRAPPER
+
83 auto pdi_conf = PC_parse_string("");
+
84 PDI_init(pdi_conf);
+
85#endif
+
86 ddc::ScopeGuard scope(argc, argv);
+
87
+
88 // some parameters that would typically be read from some form of
+
89 // configuration file in a more realistic code
+
90
+
92 // Start of the domain of interest in the X dimension
+
93 double const x_start = -1.;
+
94 // End of the domain of interest in the X dimension
+
95 double const x_end = 1.;
+
96 // Number of discretization points in the X dimension
+
97 size_t const nb_x_points = 10;
+
98 // Thermal diffusion coefficient
+
99 double const kx = .01;
+
100 // Start of the domain of interest in the Y dimension
+
101 double const y_start = -1.;
+
102 // End of the domain of interest in the Y dimension
+
103 double const y_end = 1.;
+
104 // Number of discretization points in the Y dimension
+
105 size_t const nb_y_points = 100;
+
106 // Thermal diffusion coefficient
+
107 double const ky = .002;
+
108 // Simulated time at which to start simulation
+
109 double const start_time = 0.;
+
110 // Simulated time to reach as target of the simulation
+
111 double const end_time = 10.;
+
112 // Number of time-steps between outputs
+
113 ptrdiff_t const t_output_period = 10;
+
115
+
118 // Number of ghost points to use on each side in X
+
119 ddc::DiscreteVector<DDimX> static constexpr gwx {1};
121
-
123 // our zone at the start of the domain that will be mirrored to the
-
124 // ghost
-
125 ddc::DiscreteDomain<DDimX> const
-
126 x_domain_begin(x_domain.front(), x_post_ghost.extents());
-
127 // our zone at the end of the domain that will be mirrored to the
-
128 // ghost
-
129 ddc::DiscreteDomain<DDimX> const x_domain_end(
-
130 x_domain.back() - x_pre_ghost.extents() + 1,
-
131 x_pre_ghost.extents());
-
133
-
135 // Number of ghost points to use on each side in Y
-
136 ddc::DiscreteVector<DDimY> static constexpr gwy {1};
-
137
-
138 // Initialization of the global domain in Y with gwy ghost points on
-
139 // each side
-
140 auto const [y_domain, ghosted_y_domain, y_pre_ghost, y_post_ghost]
-
141 = ddc::init_discrete_space(DDimY::init_ghosted(
-
142 ddc::Coordinate<Y>(y_start),
-
143 ddc::Coordinate<Y>(y_end),
-
144 ddc::DiscreteVector<DDimY>(nb_y_points),
-
145 gwy));
-
146
-
147 // our zone at the start of the domain that will be mirrored to the
-
148 // ghost
-
149 ddc::DiscreteDomain<DDimY> const
-
150 y_domain_begin(y_domain.front(), y_post_ghost.extents());
-
151 // our zone at the end of the domain that will be mirrored to the
-
152 // ghost
-
153 ddc::DiscreteDomain<DDimY> const y_domain_end(
-
154 y_domain.back() - y_pre_ghost.extents() + 1,
-
155 y_pre_ghost.extents());
+
123 // Initialization of the global domain in X with gwx ghost points on
+
124 // each side
+
125 auto const [x_domain, ghosted_x_domain, x_pre_ghost, x_post_ghost]
+
126 = ddc::init_discrete_space(DDimX::init_ghosted(
+
127 ddc::Coordinate<X>(x_start),
+
128 ddc::Coordinate<X>(x_end),
+
129 ddc::DiscreteVector<DDimX>(nb_x_points),
+
130 gwx));
+
132
+
134 // our zone at the start of the domain that will be mirrored to the
+
135 // ghost
+
136 ddc::DiscreteDomain<DDimX> const
+
137 x_domain_begin(x_domain.front(), x_post_ghost.extents());
+
138 // our zone at the end of the domain that will be mirrored to the
+
139 // ghost
+
140 ddc::DiscreteDomain<DDimX> const x_domain_end(
+
141 x_domain.back() - x_pre_ghost.extents() + 1,
+
142 x_pre_ghost.extents());
+
144
+
146 // Number of ghost points to use on each side in Y
+
147 ddc::DiscreteVector<DDimY> static constexpr gwy {1};
+
148
+
149 // Initialization of the global domain in Y with gwy ghost points on
+
150 // each side
+
151 auto const [y_domain, ghosted_y_domain, y_pre_ghost, y_post_ghost]
+
152 = ddc::init_discrete_space(DDimY::init_ghosted(
+
153 ddc::Coordinate<Y>(y_start),
+
154 ddc::Coordinate<Y>(y_end),
+
155 ddc::DiscreteVector<DDimY>(nb_y_points),
+
156 gwy));
157
-
159 // max(1/dx^2)
-
160 double const invdx2_max = ddc::transform_reduce(
-
161 x_domain,
-
162 0.,
-
163 ddc::reducer::max<double>(),
-
164 [](ddc::DiscreteElement<DDimX> ix) {
-
165 return 1.
-
166 / (ddc::distance_at_left(ix)
-
167 * ddc::distance_at_right(ix));
-
168 });
-
169 // max(1/dy^2)
-
170 double const invdy2_max = ddc::transform_reduce(
-
171 y_domain,
-
172 0.,
-
173 ddc::reducer::max<double>(),
-
174 [](ddc::DiscreteElement<DDimY> iy) {
-
175 return 1.
-
176 / (ddc::distance_at_left(iy)
-
177 * ddc::distance_at_right(iy));
-
178 });
-
179 ddc::Coordinate<T> const max_dt {
-
180 .5 / (kx * invdx2_max + ky * invdy2_max)};
-
181
-
182 // number of time intervals required to reach the end time
-
183 ddc::DiscreteVector<DDimT> const nb_time_steps {
-
184 std::ceil((end_time - start_time) / max_dt) + .2};
-
185 // Initialization of the global domain in time:
-
186 // - the number of discrete time-points is equal to the number of
-
187 // steps + 1
-
188 ddc::DiscreteDomain<DDimT> const time_domain
-
189 = ddc::init_discrete_space(
-
190 DDimT::
-
191 init(ddc::Coordinate<T>(start_time),
-
192 ddc::Coordinate<T>(end_time),
-
193 nb_time_steps + 1));
-
195
-
197 // Maps temperature into the full domain (including ghosts) twice:
-
198 // - once for the last fully computed time-step
-
199 ddc::Chunk ghosted_last_temp(
-
200 "ghosted_last_temp",
-
201 ddc::DiscreteDomain<
-
202 DDimX,
-
203 DDimY>(ghosted_x_domain, ghosted_y_domain),
-
204 ddc::DeviceAllocator<double>());
-
205
-
206 // - once for time-step being computed
-
207 ddc::Chunk ghosted_next_temp(
-
208 "ghosted_next_temp",
-
209 ddc::DiscreteDomain<
-
210 DDimX,
-
211 DDimY>(ghosted_x_domain, ghosted_y_domain),
-
212 ddc::DeviceAllocator<double>());
-
214
-
216 ddc::ChunkSpan const ghosted_initial_temp
-
217 = ghosted_last_temp.span_view();
-
218 // Initialize the temperature on the main domain
-
219 ddc::for_each(
-
220 ddc::policies::parallel_device,
-
221 ddc::DiscreteDomain<DDimX, DDimY>(x_domain, y_domain),
-
222 DDC_LAMBDA(ddc::DiscreteElement<DDimX, DDimY> const ixy) {
-
223 double const x
-
224 = ddc::coordinate(ddc::select<DDimX>(ixy));
-
225 double const y
-
226 = ddc::coordinate(ddc::select<DDimY>(ixy));
-
227 ghosted_initial_temp(ixy)
-
228 = 9.999 * ((x * x + y * y) < 0.25);
-
229 });
-
231
-
232 ddc::Chunk ghosted_temp(
-
233 "ghost_temp",
-
234 ddc::DiscreteDomain<
-
235 DDimX,
-
236 DDimY>(ghosted_x_domain, ghosted_y_domain),
-
237 ddc::HostAllocator<double>());
-
238
-
239
-
241 // display the initial data
-
242 ddc::deepcopy(ghosted_temp, ghosted_last_temp);
-
243 display(ddc::coordinate(time_domain.front()),
-
244 ghosted_temp[x_domain][y_domain]);
-
245 // time of the iteration where the last output happened
-
246 ddc::DiscreteElement<DDimT> last_output = time_domain.front();
-
248
-
250 for (auto const iter :
-
251 time_domain.remove_first(ddc::DiscreteVector<DDimT>(1))) {
-
253
-
255 // Periodic boundary conditions
-
256 ddc::deepcopy(
-
257 ghosted_last_temp[x_pre_ghost][y_domain],
-
258 ghosted_last_temp[y_domain][x_domain_end]);
-
259 ddc::deepcopy(
-
260 ghosted_last_temp[y_domain][x_post_ghost],
-
261 ghosted_last_temp[y_domain][x_domain_begin]);
-
262 ddc::deepcopy(
-
263 ghosted_last_temp[x_domain][y_pre_ghost],
-
264 ghosted_last_temp[x_domain][y_domain_end]);
-
265 ddc::deepcopy(
-
266 ghosted_last_temp[x_domain][y_post_ghost],
-
267 ghosted_last_temp[x_domain][y_domain_begin]);
-
269
-
271 // a span excluding ghosts of the temperature at the time-step we
-
272 // will build
-
273 ddc::ChunkSpan const next_temp {
-
274 ghosted_next_temp[x_domain][y_domain]};
-
275 // a read-only view of the temperature at the previous time-step
-
276 ddc::ChunkSpan const last_temp {ghosted_last_temp.span_view()};
-
278
-
280 // Stencil computation on the main domain
-
281 ddc::for_each(
-
282 ddc::policies::parallel_device,
-
283 next_temp.domain(),
-
284 DDC_LAMBDA(
-
285 ddc::DiscreteElement<DDimX, DDimY> const ixy) {
-
286 ddc::DiscreteElement<DDimX> const ix
-
287 = ddc::select<DDimX>(ixy);
-
288 ddc::DiscreteElement<DDimY> const iy
-
289 = ddc::select<DDimY>(ixy);
-
290 double const dx_l = ddc::distance_at_left(ix);
-
291 double const dx_r = ddc::distance_at_right(ix);
-
292 double const dx_m = 0.5 * (dx_l + dx_r);
-
293 double const dy_l = ddc::distance_at_left(iy);
-
294 double const dy_r = ddc::distance_at_right(iy);
-
295 double const dy_m = 0.5 * (dy_l + dy_r);
-
296 next_temp(ix, iy) = last_temp(ix, iy);
-
297 next_temp(ix, iy)
-
298 += kx * ddc::step<DDimT>()
-
299 * (dx_l * last_temp(ix + 1, iy)
-
300 - 2.0 * dx_m * last_temp(ix, iy)
-
301 + dx_r * last_temp(ix - 1, iy))
-
302 / (dx_l * dx_m * dx_r);
-
303 next_temp(ix, iy)
-
304 += ky * ddc::step<DDimT>()
-
305 * (dy_l * last_temp(ix, iy + 1)
-
306 - 2.0 * dy_m * last_temp(ix, iy)
-
307 + dy_r * last_temp(ix, iy - 1))
-
308 / (dy_l * dy_m * dy_r);
-
309 });
-
311
-
313 if (iter - last_output >= t_output_period) {
-
314 last_output = iter;
-
315 ddc::deepcopy(ghosted_temp, ghosted_last_temp);
-
316 display(ddc::coordinate(iter),
-
317 ghosted_temp[x_domain][y_domain]);
-
318 }
-
320
-
322 // Swap our two buffers
-
323 std::swap(ghosted_last_temp, ghosted_next_temp);
-
325 }
-
326
-
328 if (last_output < time_domain.back()) {
-
329 ddc::deepcopy(ghosted_temp, ghosted_last_temp);
-
330 display(ddc::coordinate(time_domain.back()),
-
331 ghosted_temp[x_domain][y_domain]);
-
332 }
-
334}
+
158 // our zone at the start of the domain that will be mirrored to the
+
159 // ghost
+
160 ddc::DiscreteDomain<DDimY> const
+
161 y_domain_begin(y_domain.front(), y_post_ghost.extents());
+
162 // our zone at the end of the domain that will be mirrored to the
+
163 // ghost
+
164 ddc::DiscreteDomain<DDimY> const y_domain_end(
+
165 y_domain.back() - y_pre_ghost.extents() + 1,
+
166 y_pre_ghost.extents());
+
168
+
170 // max(1/dx^2)
+
171 double const invdx2_max = ddc::transform_reduce(
+
172 x_domain,
+
173 0.,
+
174 ddc::reducer::max<double>(),
+
175 [](ddc::DiscreteElement<DDimX> ix) {
+
176 return 1.
+
177 / (ddc::distance_at_left(ix)
+
178 * ddc::distance_at_right(ix));
+
179 });
+
180 // max(1/dy^2)
+
181 double const invdy2_max = ddc::transform_reduce(
+
182 y_domain,
+
183 0.,
+
184 ddc::reducer::max<double>(),
+
185 [](ddc::DiscreteElement<DDimY> iy) {
+
186 return 1.
+
187 / (ddc::distance_at_left(iy)
+
188 * ddc::distance_at_right(iy));
+
189 });
+
190 ddc::Coordinate<T> const max_dt {
+
191 .5 / (kx * invdx2_max + ky * invdy2_max)};
+
192
+
193 // number of time intervals required to reach the end time
+
194 ddc::DiscreteVector<DDimT> const nb_time_steps {
+
195 std::ceil((end_time - start_time) / max_dt) + .2};
+
196 // Initialization of the global domain in time:
+
197 // - the number of discrete time-points is equal to the number of
+
198 // steps + 1
+
199 ddc::DiscreteDomain<DDimT> const time_domain
+
200 = ddc::init_discrete_space(
+
201 DDimT::
+
202 init(ddc::Coordinate<T>(start_time),
+
203 ddc::Coordinate<T>(end_time),
+
204 nb_time_steps + 1));
+
206
+
208 // Maps temperature into the full domain (including ghosts) twice:
+
209 // - once for the last fully computed time-step
+
210 ddc::Chunk ghosted_last_temp(
+
211 "ghosted_last_temp",
+
212 ddc::DiscreteDomain<
+
213 DDimX,
+
214 DDimY>(ghosted_x_domain, ghosted_y_domain),
+
215 ddc::DeviceAllocator<double>());
+
216
+
217 // - once for time-step being computed
+
218 ddc::Chunk ghosted_next_temp(
+
219 "ghosted_next_temp",
+
220 ddc::DiscreteDomain<
+
221 DDimX,
+
222 DDimY>(ghosted_x_domain, ghosted_y_domain),
+
223 ddc::DeviceAllocator<double>());
+
225
+
227 ddc::ChunkSpan const ghosted_initial_temp
+
228 = ghosted_last_temp.span_view();
+
229 // Initialize the temperature on the main domain
+
230 ddc::for_each(
+
231 ddc::policies::parallel_device,
+
232 ddc::DiscreteDomain<DDimX, DDimY>(x_domain, y_domain),
+
233 DDC_LAMBDA(ddc::DiscreteElement<DDimX, DDimY> const ixy) {
+
234 double const x
+
235 = ddc::coordinate(ddc::select<DDimX>(ixy));
+
236 double const y
+
237 = ddc::coordinate(ddc::select<DDimY>(ixy));
+
238 ghosted_initial_temp(ixy)
+
239 = 9.999 * ((x * x + y * y) < 0.25);
+
240 });
+
242
+
243 ddc::Chunk ghosted_temp(
+
244 "ghost_temp",
+
245 ddc::DiscreteDomain<
+
246 DDimX,
+
247 DDimY>(ghosted_x_domain, ghosted_y_domain),
+
248 ddc::HostAllocator<double>());
+
249
+
250
+
252 // display the initial data
+
253 ddc::deepcopy(ghosted_temp, ghosted_last_temp);
+
254 display(ddc::coordinate(time_domain.front()),
+
255 ghosted_temp[x_domain][y_domain]);
+
256 // time of the iteration where the last output happened
+
257 ddc::DiscreteElement<DDimT> last_output = time_domain.front();
+
259
+
261 for (auto const iter :
+
262 time_domain.remove_first(ddc::DiscreteVector<DDimT>(1))) {
+
264
+
266 // Periodic boundary conditions
+
267 ddc::deepcopy(
+
268 ghosted_last_temp[x_pre_ghost][y_domain],
+
269 ghosted_last_temp[y_domain][x_domain_end]);
+
270 ddc::deepcopy(
+
271 ghosted_last_temp[y_domain][x_post_ghost],
+
272 ghosted_last_temp[y_domain][x_domain_begin]);
+
273 ddc::deepcopy(
+
274 ghosted_last_temp[x_domain][y_pre_ghost],
+
275 ghosted_last_temp[x_domain][y_domain_end]);
+
276 ddc::deepcopy(
+
277 ghosted_last_temp[x_domain][y_post_ghost],
+
278 ghosted_last_temp[x_domain][y_domain_begin]);
+
280
+
282 // a span excluding ghosts of the temperature at the time-step we
+
283 // will build
+
284 ddc::ChunkSpan const next_temp {
+
285 ghosted_next_temp[x_domain][y_domain]};
+
286 // a read-only view of the temperature at the previous time-step
+
287 ddc::ChunkSpan const last_temp {ghosted_last_temp.span_view()};
+
289
+
291 // Stencil computation on the main domain
+
292 ddc::for_each(
+
293 ddc::policies::parallel_device,
+
294 next_temp.domain(),
+
295 DDC_LAMBDA(
+
296 ddc::DiscreteElement<DDimX, DDimY> const ixy) {
+
297 ddc::DiscreteElement<DDimX> const ix
+
298 = ddc::select<DDimX>(ixy);
+
299 ddc::DiscreteElement<DDimY> const iy
+
300 = ddc::select<DDimY>(ixy);
+
301 double const dx_l = ddc::distance_at_left(ix);
+
302 double const dx_r = ddc::distance_at_right(ix);
+
303 double const dx_m = 0.5 * (dx_l + dx_r);
+
304 double const dy_l = ddc::distance_at_left(iy);
+
305 double const dy_r = ddc::distance_at_right(iy);
+
306 double const dy_m = 0.5 * (dy_l + dy_r);
+
307 next_temp(ix, iy) = last_temp(ix, iy);
+
308 next_temp(ix, iy)
+
309 += kx * ddc::step<DDimT>()
+
310 * (dx_l * last_temp(ix + 1, iy)
+
311 - 2.0 * dx_m * last_temp(ix, iy)
+
312 + dx_r * last_temp(ix - 1, iy))
+
313 / (dx_l * dx_m * dx_r);
+
314 next_temp(ix, iy)
+
315 += ky * ddc::step<DDimT>()
+
316 * (dy_l * last_temp(ix, iy + 1)
+
317 - 2.0 * dy_m * last_temp(ix, iy)
+
318 + dy_r * last_temp(ix, iy - 1))
+
319 / (dy_l * dy_m * dy_r);
+
320 });
+
322
+
324 if (iter - last_output >= t_output_period) {
+
325 last_output = iter;
+
326 ddc::deepcopy(ghosted_temp, ghosted_last_temp);
+
327 display(ddc::coordinate(iter),
+
328 ghosted_temp[x_domain][y_domain]);
+
329 }
+
331
+
333 // Swap our two buffers
+
334 std::swap(ghosted_last_temp, ghosted_next_temp);
+
336 }
+
337
+
339 if (last_output < time_domain.back()) {
+
340 ddc::deepcopy(ghosted_temp, ghosted_last_temp);
+
341 display(ddc::coordinate(time_domain.back()),
+
342 ghosted_temp[x_domain][y_domain]);
+
343 }
+
345
+
346#ifdef DDC_BUILD_PDI_WRAPPER
+
347 PDI_finalize();
+
348 PC_tree_destroy(&pdi_conf);
+
349#endif
+
350}
Definition: discrete_domain.hpp:48
KOKKOS_FUNCTION constexpr discrete_element_type front() const noexcept
Definition: discrete_domain.hpp:132
KOKKOS_FUNCTION constexpr DiscreteDomain remove_first(mlength_type n) const
Definition: discrete_domain.hpp:152
@@ -336,6 +352,9 @@

a discrete
A DiscreteElement identifies an element of the discrete dimension.
Definition: discrete_element.hpp:145
A DiscreteVector is a vector in the discrete dimension.
Definition: discrete_vector.hpp:251
Definition: kokkos_allocator.hpp:15
+
Definition: pdi.hpp:27
+
PdiEvent & and_with(std::string const &name, T &&t)
Definition: pdi.hpp:84
+
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
Definition: pdi.hpp:45
Definition: scope_guard.hpp:14
UniformPointSampling models a uniform discretization of the provided continuous dimension.
Definition: uniform_point_sampling.hpp:24
constexpr parallel_device_policy parallel_device
Definition: for_each.hpp:230
diff --git a/pdi_8hpp_source.html b/pdi_8hpp_source.html index d5123ac3e..17baa7116 100644 --- a/pdi_8hpp_source.html +++ b/pdi_8hpp_source.html @@ -50,144 +50,154 @@

a discrete 2
3#pragma once
4
-
5#include <string>
-
6#include <type_traits>
-
7
-
8#include <pdi.h>
+
5#include <memory_resource>
+
6#include <string>
+
7#include <type_traits>
+
8#include <vector>
9
-
10#include "ddc/chunk_span.hpp"
+
10#include <pdi.h>
11
-
12namespace ddc {
-
13
-
14template <class T>
-
15static constexpr PDI_inout_t default_access_v
-
16 = (std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>)
-
17 ? PDI_INOUT
-
18 : PDI_OUT;
-
19
-
20template <class T>
-
21static constexpr PDI_inout_t chunk_default_access_v = is_writable_chunk_v<T> ? PDI_INOUT : PDI_OUT;
+
12#include "ddc/chunk_span.hpp"
+
13#include "ddc/discrete_domain.hpp"
+
14
+
15namespace ddc {
+
16
+
17template <class T>
+
18static constexpr PDI_inout_t default_access_v
+
19 = (std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>)
+
20 ? PDI_INOUT
+
21 : PDI_OUT;
22
-
23class PdiEvent
-
24{
-
25 std::string m_event;
-
26
-
27 std::vector<std::string> m_names;
-
28
-
29public:
-
30 PdiEvent(std::string const& event_name) : m_event(event_name) {}
+
23template <class T>
+
24static constexpr PDI_inout_t chunk_default_access_v = is_writable_chunk_v<T> ? PDI_INOUT : PDI_OUT;
+
25
+
26class PdiEvent
+
27{
+
28 std::string m_event;
+
29
+
30 std::vector<std::string> m_names;
31
-
32 /// @{
-
33 /// API with access argument
+
32 /// a memory buffer where temporary variables are stored until the class is destroyed
+
33 std::pmr::monotonic_buffer_resource m_metadata;
34
-
35 template <
-
36 PDI_inout_t access,
-
37 class BorrowedChunk,
-
38 std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
-
39 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
-
40 {
-
41 static_assert(
-
42 !(access & PDI_IN) || (chunk_default_access_v<BorrowedChunk> & PDI_IN),
-
43 "Invalid access for constant data");
-
44 auto extents = detail::array(data.domain().extents());
-
45 size_t rank = extents.size();
-
46 PDI_share((name + "_rank").c_str(), &rank, PDI_OUT);
-
47 m_names.push_back(name + "_rank");
-
48 PDI_share((name + "_extents").c_str(), extents.data(), PDI_OUT);
-
49 m_names.push_back(name + "_extents");
-
50 PDI_share(
-
51 name.c_str(),
-
52 const_cast<chunk_value_t<BorrowedChunk>*>(data.data_handle()),
-
53 access);
-
54 m_names.push_back(name);
-
55 return *this;
-
56 }
-
57
-
58 template <
-
59 PDI_inout_t access,
-
60 class Arithmetic,
-
61 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
-
62 PdiEvent& with(std::string const& name, Arithmetic&& data)
-
63 {
-
64 static_assert(
-
65 !(access & PDI_IN) || (default_access_v<Arithmetic> & PDI_IN),
-
66 "Invalid access for constant data");
-
67 using value_type = std::remove_cv_t<std::remove_reference_t<Arithmetic>>;
-
68 PDI_share(name.c_str(), const_cast<value_type*>(&data), access);
-
69 m_names.push_back(name);
-
70 return *this;
-
71 }
-
72
-
73 template <PDI_inout_t access, class T>
-
74 PdiEvent& and_with(std::string const& name, T&& t)
-
75 {
-
76 return with<access>(name, std::forward<T>(t));
-
77 }
-
78
-
79 /// @}
-
80 /// API with access deduction
-
81 /// @{
+
35public:
+
36 PdiEvent(std::string const& event_name) : m_event(event_name) {}
+
37
+
38 /// @{
+
39 /// API with access argument
+
40
+
41 template <
+
42 PDI_inout_t access,
+
43 class BorrowedChunk,
+
44 std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
+
45 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
+
46 {
+
47 static_assert(
+
48 !(access & PDI_IN) || (chunk_default_access_v<BorrowedChunk> & PDI_IN),
+
49 "Invalid access for constant data");
+
50 auto extents = detail::array(data.domain().extents());
+
51 size_t& rank = *std::pmr::polymorphic_allocator<size_t>(&m_metadata).allocate(1);
+
52 rank = extents.size();
+
53 PDI_share((name + "_rank").c_str(), &rank, PDI_OUT);
+
54 m_names.push_back(name + "_rank");
+
55 PDI_share(
+
56 (name + "_extents").c_str(),
+
57 std::pmr::vector<size_t>(extents.begin(), extents.end(), &m_metadata).data(),
+
58 PDI_OUT);
+
59 m_names.push_back(name + "_extents");
+
60 PDI_share(
+
61 name.c_str(),
+
62 const_cast<chunk_value_t<BorrowedChunk>*>(data.data_handle()),
+
63 access);
+
64 m_names.push_back(name);
+
65 return *this;
+
66 }
+
67
+
68 template <
+
69 PDI_inout_t access,
+
70 class Arithmetic,
+
71 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
+
72 PdiEvent& with(std::string const& name, Arithmetic&& data)
+
73 {
+
74 static_assert(
+
75 !(access & PDI_IN) || (default_access_v<Arithmetic> & PDI_IN),
+
76 "Invalid access for constant data");
+
77 using value_type = std::remove_cv_t<std::remove_reference_t<Arithmetic>>;
+
78 PDI_share(name.c_str(), const_cast<value_type*>(&data), access);
+
79 m_names.push_back(name);
+
80 return *this;
+
81 }
82
-
83 /// Borrowed chunk overload (Chunk (const)& or ChunkSpan&& or ChunkSpan (const)&)
-
84 template <class BorrowedChunk, std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
-
85 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
-
86 {
-
87 return with<chunk_default_access_v<BorrowedChunk>>(name, std::forward<BorrowedChunk>(data));
-
88 }
-
89
-
90 /// Arithmetic overload
-
91 template <
-
92 class Arithmetic,
-
93 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
-
94 PdiEvent& with(std::string const& name, Arithmetic&& data)
-
95 {
-
96 return with<default_access_v<Arithmetic>>(name, std::forward<Arithmetic>(data));
-
97 }
-
98
-
99 /// With synonym
-
100 template <class T>
-
101 PdiEvent& and_with(std::string const& name, T&& t)
-
102 {
-
103 return with(name, std::forward<T>(t));
-
104 }
-
105
-
106 /// @}
-
107
-
108 ~PdiEvent()
-
109 {
-
110 PDI_event(m_event.c_str());
-
111 for (std::string const& one_name : m_names) {
-
112 PDI_reclaim(one_name.c_str());
-
113 }
+
83 template <PDI_inout_t access, class T>
+
84 PdiEvent& and_with(std::string const& name, T&& t)
+
85 {
+
86 return with<access>(name, std::forward<T>(t));
+
87 }
+
88
+
89 /// @}
+
90 /// API with access deduction
+
91 /// @{
+
92
+
93 /// Borrowed chunk overload (Chunk (const)& or ChunkSpan&& or ChunkSpan (const)&)
+
94 template <class BorrowedChunk, std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
+
95 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
+
96 {
+
97 return with<chunk_default_access_v<BorrowedChunk>>(name, std::forward<BorrowedChunk>(data));
+
98 }
+
99
+
100 /// Arithmetic overload
+
101 template <
+
102 class Arithmetic,
+
103 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
+
104 PdiEvent& with(std::string const& name, Arithmetic&& data)
+
105 {
+
106 return with<default_access_v<Arithmetic>>(name, std::forward<Arithmetic>(data));
+
107 }
+
108
+
109 /// With synonym
+
110 template <class T>
+
111 PdiEvent& and_with(std::string const& name, T&& t)
+
112 {
+
113 return with(name, std::forward<T>(t));
114 }
-
115};
-
116
-
117template <PDI_inout_t access, class DataType>
-
118void expose_to_pdi(std::string const& name, DataType&& data)
-
119{
-
120 PdiEvent(name).with<access>(name, std::forward<DataType>(data));
-
121}
-
122
-
123template <class DataType>
-
124void expose_to_pdi(std::string const& name, DataType&& data)
-
125{
-
126 PdiEvent(name).with(name, std::forward<DataType>(data));
-
127}
-
128
-
129
-
130} // namespace ddc
-
Definition: pdi.hpp:24
-
PdiEvent & and_with(std::string const &name, T &&t)
With synonym.
Definition: pdi.hpp:101
-
PdiEvent & and_with(std::string const &name, T &&t)
Definition: pdi.hpp:74
-
~PdiEvent()
Definition: pdi.hpp:108
-
PdiEvent(std::string const &event_name)
Definition: pdi.hpp:30
-
PdiEvent & with(std::string const &name, Arithmetic &&data)
Arithmetic overload.
Definition: pdi.hpp:94
-
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
API with access deduction.
Definition: pdi.hpp:85
-
PdiEvent & with(std::string const &name, Arithmetic &&data)
Definition: pdi.hpp:62
-
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
Definition: pdi.hpp:39
+
115
+
116 /// @}
+
117
+
118 ~PdiEvent()
+
119 {
+
120 PDI_event(m_event.c_str());
+
121 for (std::string const& one_name : m_names) {
+
122 PDI_reclaim(one_name.c_str());
+
123 }
+
124 }
+
125};
+
126
+
127template <PDI_inout_t access, class DataType>
+
128void expose_to_pdi(std::string const& name, DataType&& data)
+
129{
+
130 PdiEvent(name).with<access>(name, std::forward<DataType>(data));
+
131}
+
132
+
133template <class DataType>
+
134void expose_to_pdi(std::string const& name, DataType&& data)
+
135{
+
136 PdiEvent(name).with(name, std::forward<DataType>(data));
+
137}
+
138
+
139
+
140} // namespace ddc
+
Definition: pdi.hpp:27
+
PdiEvent & and_with(std::string const &name, T &&t)
With synonym.
Definition: pdi.hpp:111
+
PdiEvent & and_with(std::string const &name, T &&t)
Definition: pdi.hpp:84
+
~PdiEvent()
Definition: pdi.hpp:118
+
PdiEvent(std::string const &event_name)
Definition: pdi.hpp:36
+
PdiEvent & with(std::string const &name, Arithmetic &&data)
Arithmetic overload.
Definition: pdi.hpp:104
+
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
API with access deduction.
Definition: pdi.hpp:95
+
PdiEvent & with(std::string const &name, Arithmetic &&data)
Definition: pdi.hpp:72
+
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
Definition: pdi.hpp:45
Definition: aligned_allocator.hpp:9
-
void expose_to_pdi(std::string const &name, DataType &&data)
Definition: pdi.hpp:118
-
void expose_to_pdi(std::string const &name, DataType &&data)
Definition: pdi.hpp:124
+
void expose_to_pdi(std::string const &name, DataType &&data)
Definition: pdi.hpp:128
+
void expose_to_pdi(std::string const &name, DataType &&data)
Definition: pdi.hpp:134