YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
interp_operator_direct_mf.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <string.h>
6
8#include "utils_core.h"
13
15 struct yac_interp_operator * interp);
17 struct yac_interp_operator * interp);
19 struct yac_interp_operator * interp,
20 double *** src_fields, double *** src_frac_masks, double ** tgt_field,
21 double frac_mask_fallback_value, double scale_factor, double scale_summand);
23 struct yac_interp_operator * interp,
24 double *** src_fields, double *** src_frac_masks,
25 int is_target, double frac_mask_fallback_value,
26 double scale_factor, double scale_summand);
28 struct yac_interp_operator * interp, double ** tgt_field,
29 double frac_mask_fallback_value, double scale_factor, double scale_summand);
31 struct yac_interp_operator * interp, double ** tgt_field,
32 double frac_mask_fallback_value, double scale_factor, double scale_summand);
34 struct yac_interp_operator * interp);
36 struct yac_interp_operator * interp);
38 struct yac_interp_operator * interp);
40 struct yac_interp_operator * interp);
42 struct yac_interp_operator * interp);
43
44static struct yac_interp_operator_vtable const
58
74
76 struct yac_collection_selection const * collection_selection,
77 struct yac_interpolation_exchange * src2tgt,
78 struct yac_interpolation_buffer src_data, size_t num_src_fields) {
79
80 struct yac_interp_operator_direct_mf * direct_mf = xmalloc(1 * sizeof(*direct_mf));
81
82 size_t collection_size =
84
86 direct_mf->collection_selection =
88 direct_mf->src_data = src_data;
89 direct_mf->src2tgt = src2tgt;
90 direct_mf->src_field_buffer =
92 sizeof(*(direct_mf->src_field_buffer)));
93 direct_mf->tgt_field_buffer =
95 sizeof(*(direct_mf->tgt_field_buffer)));
96 direct_mf->num_src_fields = num_src_fields;
99
100 return (struct yac_interp_operator *)direct_mf;
101}
102
104 struct yac_collection_selection const * collection_selection,
105 Xt_redist * redists, size_t num_src_fields) {
106
107 size_t collection_size =
109
110 return
112 collection_selection,
114 redists, num_src_fields, collection_size, 0, "source to target"),
116 redists, num_src_fields, collection_size, SEND_BUFFER), num_src_fields);
117}
118
120 struct yac_interp_operator * interp) {
121
122 struct yac_interp_operator_direct_mf * direct_mf =
123 (struct yac_interp_operator_direct_mf *)interp;
124
125 return direct_mf->is_source;
126}
127
129 struct yac_interp_operator * interp) {
130
131 struct yac_interp_operator_direct_mf * direct_mf =
132 (struct yac_interp_operator_direct_mf *)interp;
133
134 return direct_mf->is_target;
135}
136
138 struct yac_interp_operator * interp,
139 double *** src_fields, double *** src_frac_masks, double ** tgt_field,
140 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
141
142 struct yac_interp_operator_direct_mf * direct_mf =
143 (struct yac_interp_operator_direct_mf *)interp;
144
145 double ** src_send_buffer = NULL;
146 size_t collection_size =
148 direct_mf->collection_selection);
149 size_t num_src_fields = direct_mf->num_src_fields;
150
152 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute");
153
154 if (direct_mf->is_source) {
155
156 size_t const * collection_indices =
158
159 if (collection_indices != NULL) {
160
161 double *** temp_src_fields =
162 xmalloc(collection_size * sizeof(*temp_src_fields));
163 temp_src_fields[0] =
164 xmalloc(collection_size * num_src_fields * sizeof(**temp_src_fields));
165 for (size_t i = 0; i < collection_size; ++i) {
166 temp_src_fields[i] = temp_src_fields[0] + i * num_src_fields;
167 for (size_t j = 0; j < num_src_fields; ++j)
168 temp_src_fields[i][j] = src_fields[collection_indices[i]][j];
169 }
170 src_fields = temp_src_fields;
171
172 if (src_frac_masks != NULL) {
173 double *** temp_src_frac_masks =
174 xmalloc(collection_size * sizeof(*temp_src_frac_masks));
175 temp_src_frac_masks[0] =
176 xmalloc(
177 collection_size * num_src_fields * sizeof(**temp_src_frac_masks));
178 for (size_t i = 0; i < collection_size; ++i) {
179 temp_src_frac_masks[i] = temp_src_frac_masks[0] + i * num_src_fields;
180 for (size_t j = 0; j < num_src_fields; ++j)
181 temp_src_frac_masks[i][j] =
182 src_frac_masks[collection_indices[i]][j];
183 }
184 src_frac_masks = temp_src_frac_masks;
185 }
186 }
187
188 if ((YAC_FRAC_MASK_VALUE_IS_VALID(frac_mask_fallback_value)) ||
189 (scale_factor != 1.0) || (scale_summand != 0.0)) {
190
191 src_send_buffer = direct_mf->src_data.buffer;
192
194 (double const * restrict **)src_fields,
195 (double const * restrict **)src_frac_masks, src_send_buffer,
197 collection_size, frac_mask_fallback_value,
198 scale_factor, scale_summand);
199
200 } else {
201
202 src_send_buffer = direct_mf->src_field_buffer;
203 for (size_t i = 0; i < collection_size; ++i)
204 for (size_t j = 0; j < num_src_fields; ++j)
205 src_send_buffer[i * num_src_fields + j] = src_fields[i][j];
206 }
207
208 if (collection_indices != NULL) {
209 free(src_fields[0]);
210 free(src_fields);
211 if (src_frac_masks != NULL) {
212 free(src_frac_masks[0]);
213 free(src_frac_masks);
214 }
215 }
216 }
217
218 double ** tgt_field_buffer = direct_mf->tgt_field_buffer;
219 if (direct_mf->is_target)
220 for (size_t i = 0; i < collection_size; ++i)
221 for (size_t j = 0; j < num_src_fields; ++j)
222 tgt_field_buffer[i * num_src_fields + j] = tgt_field[i];
223
224 // send source points to the target processes
226 direct_mf->src2tgt, (double const **)src_send_buffer, tgt_field_buffer,
227 "yac_interp_operator_direct_mf_execute");
228}
229
231 struct yac_interp_operator * interp,
232 double *** src_fields, double *** src_frac_masks, int is_target,
233 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
234
236
237 struct yac_interp_operator_direct_mf * direct_mf =
238 (struct yac_interp_operator_direct_mf *)interp;
239
240 double ** src_send_buffer = NULL;
241
242 if (direct_mf->is_source) {
243
244 size_t collection_size =
246 direct_mf->collection_selection);
247 size_t num_src_fields = direct_mf->num_src_fields;
248 size_t const * collection_indices =
250
251 if (collection_indices != NULL) {
252
253 double *** temp_src_fields =
254 xmalloc(collection_size * sizeof(*temp_src_fields));
255 temp_src_fields[0] =
256 xmalloc(collection_size * num_src_fields * sizeof(**temp_src_fields));
257 for (size_t i = 0; i < collection_size; ++i) {
258 temp_src_fields[i] = temp_src_fields[0] + i * num_src_fields;
259 for (size_t j = 0; j < num_src_fields; ++j)
260 temp_src_fields[i][j] = src_fields[collection_indices[i]][j];
261 }
262 src_fields = temp_src_fields;
263
264 if (src_frac_masks != NULL) {
265 double *** temp_src_frac_masks =
266 xmalloc(collection_size * sizeof(*temp_src_frac_masks));
267 temp_src_frac_masks[0] =
268 xmalloc(
269 collection_size * num_src_fields * sizeof(**temp_src_frac_masks));
270 for (size_t i = 0; i < collection_size; ++i) {
271 temp_src_frac_masks[i] = temp_src_frac_masks[0] + i * num_src_fields;
272 for (size_t j = 0; j < num_src_fields; ++j)
273 temp_src_frac_masks[i][j] =
274 src_frac_masks[collection_indices[i]][j];
275 }
276 src_frac_masks = temp_src_frac_masks;
277 }
278 }
279
280 // wait until previous exchange is completed
282 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_put") ==
285 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_put");
286
287 src_send_buffer = direct_mf->src_data.buffer;
288
290 (double const * restrict **)src_fields,
291 (double const * restrict **)src_frac_masks, src_send_buffer,
293 collection_size, frac_mask_fallback_value,
294 scale_factor, scale_summand);
295
296 if (collection_indices != NULL) {
297 free(src_fields[0]);
298 free(src_fields);
299 if (src_frac_masks != NULL) {
300 free(src_frac_masks[0]);
301 free(src_frac_masks);
302 }
303 }
304 }
305
307 direct_mf->src2tgt, (double const **)src_send_buffer,
308 "yac_interp_operator_direct_mf_execute_put");
309}
310
312 struct yac_interp_operator * interp, double ** tgt_field,
313 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
314
315 UNUSED(frac_mask_fallback_value);
316 UNUSED(scale_factor);
317 UNUSED(scale_summand);
318
319 struct yac_interp_operator_direct_mf * direct_mf =
320 (struct yac_interp_operator_direct_mf*)interp;
321
322 double ** tgt_field_buffer = NULL;
323
324 if (direct_mf->is_target) {
326 size_t collection_size =
328 direct_mf->collection_selection);
329 size_t num_src_fields = direct_mf->num_src_fields;
330 for (size_t i = 0; i < collection_size; ++i)
331 for (size_t j = 0; j < num_src_fields; ++j)
332 tgt_field_buffer[i * num_src_fields + j] = tgt_field[i];
333 }
334
336 direct_mf->src2tgt, tgt_field_buffer,
337 "yac_interp_operator_direct_mf_execute_get");
338}
339
341 struct yac_interp_operator * interp, double ** tgt_field,
342 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
343
344 UNUSED(frac_mask_fallback_value);
345 UNUSED(scale_factor);
346 UNUSED(scale_summand);
347
348 struct yac_interp_operator_direct_mf * direct_mf =
349 (struct yac_interp_operator_direct_mf*)interp;
350
351 // wait until previous exchange is completed
353 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_get_async") ==
356 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_get_async");
357
358 double ** tgt_field_buffer = NULL;
359
360 if (direct_mf->is_target) {
362 size_t collection_size =
364 direct_mf->collection_selection);
365 size_t num_src_fields = direct_mf->num_src_fields;
366 for (size_t i = 0; i < collection_size; ++i)
367 for (size_t j = 0; j < num_src_fields; ++j)
368 tgt_field_buffer[i * num_src_fields + j] = tgt_field[i];
369 }
370
372 direct_mf->src2tgt, tgt_field_buffer,
373 "yac_interp_operator_direct_mf_execute_get_async");
374}
375
377 struct yac_interp_operator * interp) {
378
379 struct yac_interp_operator_direct_mf * direct_mf =
380 (struct yac_interp_operator_direct_mf*)interp;
381
382 return
384 direct_mf->src2tgt,
385 "yac_interp_operator_direct_mf_execute_put_test") ==
387}
388
390 struct yac_interp_operator * interp) {
391
392 struct yac_interp_operator_direct_mf * direct_mf =
393 (struct yac_interp_operator_direct_mf*)interp;
394
395 return
397 direct_mf->src2tgt,
398 "yac_interp_operator_direct_mf_execute_get_test") ==
400}
401
403 struct yac_interp_operator * interp) {
404
405 struct yac_interp_operator_direct_mf * direct_mf =
406 (struct yac_interp_operator_direct_mf*)interp;
407
409 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_wait");
410}
411
429
431 struct yac_interp_operator * interp) {
432 if (interp == NULL) return;
433
434 struct yac_interp_operator_direct_mf * direct_mf =
435 (struct yac_interp_operator_direct_mf*)interp;
436
438 direct_mf->src2tgt, "yac_interp_operator_direct_mf_delete");
440 free(direct_mf->src_field_buffer);
441 free(direct_mf->tgt_field_buffer);
443 free(direct_mf);
444}
#define UNUSED(x)
Definition core.h:73
size_t yac_collection_selection_get_collection_size(struct yac_collection_selection const *collection_selection)
Get the size of the collection selection.
size_t const * yac_collection_selection_get_indices(struct yac_collection_selection const *collection_selection)
Get explicit selection indices if non-contiguous.
void yac_collection_selection_delete(struct yac_collection_selection *collection_selection)
Delete a collection selection object.
struct yac_collection_selection * yac_collection_selection_copy(const struct yac_collection_selection *collection_selection)
Selection of indices from a collection.
struct yac_interp_operator * yac_interp_operator_direct_mf_new(struct yac_collection_selection const *collection_selection, Xt_redist *redists, size_t num_src_fields)
Create a direct redistribution operator for multiple source fields.
YAC_INTERP_TEST_STATUS
@ YAC_INTERP_INCOMPLETE
@ YAC_INTERP_COMPLETE
static int yac_interp_operator_direct_mf_is_target(struct yac_interp_operator *interp)
static void yac_interp_operator_direct_mf_execute_get_async(struct yac_interp_operator *interp, double **tgt_field, double frac_mask_fallback_value, double scale_factor, double scale_summand)
static struct yac_interp_operator * yac_interp_operator_direct_mf_new_(struct yac_collection_selection const *collection_selection, struct yac_interpolation_exchange *src2tgt, struct yac_interpolation_buffer src_data, size_t num_src_fields)
static void yac_interp_operator_direct_mf_execute_put(struct yac_interp_operator *interp, double ***src_fields, double ***src_frac_masks, int is_target, double frac_mask_fallback_value, double scale_factor, double scale_summand)
static enum YAC_INTERP_TEST_STATUS yac_interp_operator_direct_mf_execute_get_test(struct yac_interp_operator *interp)
static void yac_interp_operator_direct_mf_execute_wait(struct yac_interp_operator *interp)
static enum YAC_INTERP_TEST_STATUS yac_interp_operator_direct_mf_execute_put_test(struct yac_interp_operator *interp)
static void yac_interp_operator_direct_mf_delete(struct yac_interp_operator *interp)
static int yac_interp_operator_direct_mf_is_source(struct yac_interp_operator *interp)
static void yac_interp_operator_direct_mf_execute(struct yac_interp_operator *interp, double ***src_fields, double ***src_frac_masks, double **tgt_field, double frac_mask_fallback_value, double scale_factor, double scale_summand)
static struct yac_interp_operator_vtable const interpolation_direct_mf_vtable
static void yac_interp_operator_direct_mf_execute_get(struct yac_interp_operator *interp, double **tgt_field, double frac_mask_fallback_value, double scale_factor, double scale_summand)
static struct yac_interp_operator * yac_interp_operator_direct_mf_copy(struct yac_interp_operator *interp)
Multi-field direct redistribution operator in YAC.
int yac_interpolation_exchange_is_target(struct yac_interpolation_exchange *exchange)
Query whether the current process participates as target.
void yac_interpolation_exchange_execute_get_async(struct yac_interpolation_exchange *exchange, double **recv_data, char const *routine_name)
Execute the get phase asynchronously.
enum YAC_INTERP_EXCH_TEST_STATUS yac_interpolation_exchange_put_test(struct yac_interpolation_exchange *exchange, char const *routine_name)
Test whether the put phase has completed.
struct yac_interpolation_exchange * yac_interpolation_exchange_copy(struct yac_interpolation_exchange *exchange)
Create a deep copy of an interpolation exchange.
void yac_interpolation_exchange_delete(struct yac_interpolation_exchange *exchange, char const *routine_name)
Delete an interpolation exchange and release resources.
void yac_interpolation_exchange_execute_get(struct yac_interpolation_exchange *exchange, double **recv_data, char const *routine_name)
Execute the get phase and receive target data synchronously.
void yac_interpolation_exchange_wait(struct yac_interpolation_exchange *exchange, char const *routine_name)
Wait for completion of pending put/get phases.
enum YAC_INTERP_EXCH_TEST_STATUS yac_interpolation_exchange_get_test(struct yac_interpolation_exchange *exchange, char const *routine_name)
Test whether the get phase has completed.
void yac_interpolation_exchange_execute_put(struct yac_interpolation_exchange *exchange, double const **send_data, char const *routine_name)
Execute only the put phase asynchronously.
struct yac_interpolation_exchange * yac_interpolation_exchange_new(Xt_redist *redists, size_t num_fields, size_t collection_size, int with_frac_mask, char const *name)
Create a new interpolation exchange object.
void yac_interpolation_exchange_execute(struct yac_interpolation_exchange *exchange, double const **send_data_, double **recv_data_, char const *routine_name)
Execute the full exchange (put + get) synchronously.
enum YAC_INTERP_EXCH_STATUS yac_interpolation_exchange_status(struct yac_interpolation_exchange *exchange, char const *routine_name)
int yac_interpolation_exchange_is_source(struct yac_interpolation_exchange *exchange)
Query whether the current process participates as source.
Interpolation exchange object for temporary buffers and MPI exchanges.
@ YAC_INTERP_EXCH_COMPLETE
No ongoing operation.
@ YAC_INTERP_EXCH_ACTIVE
Exchange is active.
#define YAC_FRAC_MASK_VALUE_IS_VALID(value)
Test whether a fractional mask value is valid.
struct yac_interpolation_buffer yac_interpolation_buffer_copy(struct yac_interpolation_buffer src, size_t num_fields, size_t collection_size)
void yac_interpolation_buffer_free(struct yac_interpolation_buffer *buffer)
struct yac_interpolation_buffer yac_interpolation_buffer_init(Xt_redist *redists, size_t num_fields, size_t collection_size, enum yac_interpolation_buffer_type type)
static void compute_tgt_field(double const *restrict **src_fields, double const *restrict **src_frac_masks, double *restrict *tgt_field, size_t *restrict tgt_buffer_sizes, size_t num_src_fields, size_t collection_size, double frac_mask_fallback_value, double scale_factor, double scale_summand)
@ SEND_BUFFER
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
struct yac_interpolation_buffer src_data
struct yac_interp_operator_vtable const * vtable
struct yac_collection_selection * collection_selection
struct yac_interpolation_exchange * src2tgt
Virtual function table for interpolation operators.
int(* is_source)(struct yac_interp_operator *interp)
Abstract interpolation operator type.
int collection_size