YAC 3.21.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
7#include <yaxt.h>
8
10#include "utils_core.h"
15
17 struct yac_interp_operator * interp);
19 struct yac_interp_operator * interp);
21 struct yac_interp_operator * interp,
22 double *** src_fields, double *** src_frac_masks, double ** tgt_field,
23 double frac_mask_fallback_value, double scale_factor, double scale_summand);
25 struct yac_interp_operator * interp,
26 double *** src_fields, double *** src_frac_masks,
27 int is_target, double frac_mask_fallback_value,
28 double scale_factor, double scale_summand);
30 struct yac_interp_operator * interp, double ** tgt_field,
31 double frac_mask_fallback_value, double scale_factor, double scale_summand);
33 struct yac_interp_operator * interp, double ** tgt_field,
34 double frac_mask_fallback_value, double scale_factor, double scale_summand);
36 struct yac_interp_operator * interp);
38 struct yac_interp_operator * interp);
40 struct yac_interp_operator * interp);
42 struct yac_interp_operator * interp);
44 struct yac_interp_operator * interp);
45
46static struct yac_interp_operator_vtable const
60
76
78 struct yac_collection_selection const * collection_selection,
79 struct yac_interpolation_exchange * src2tgt,
80 struct yac_interpolation_buffer src_data, size_t num_src_fields) {
81
82 struct yac_interp_operator_direct_mf * direct_mf = xmalloc(1 * sizeof(*direct_mf));
83
84 size_t collection_size =
86
88 direct_mf->collection_selection =
90 direct_mf->src_data = src_data;
91 direct_mf->src2tgt = src2tgt;
92 direct_mf->src_field_buffer =
94 sizeof(*(direct_mf->src_field_buffer)));
95 direct_mf->tgt_field_buffer =
97 sizeof(*(direct_mf->tgt_field_buffer)));
98 direct_mf->num_src_fields = num_src_fields;
101
102 return (struct yac_interp_operator *)direct_mf;
103}
104
106 struct yac_collection_selection const * collection_selection,
107 Xt_redist * redists, size_t num_src_fields) {
108
109 size_t collection_size =
111
112 return
114 collection_selection,
116 redists, num_src_fields, collection_size, 0, "source to target"),
118 redists, num_src_fields, collection_size, SEND_BUFFER), num_src_fields);
119}
120
122 struct yac_interp_operator * interp) {
123
124 struct yac_interp_operator_direct_mf * direct_mf =
125 (struct yac_interp_operator_direct_mf *)interp;
126
127 return direct_mf->is_source;
128}
129
131 struct yac_interp_operator * interp) {
132
133 struct yac_interp_operator_direct_mf * direct_mf =
134 (struct yac_interp_operator_direct_mf *)interp;
135
136 return direct_mf->is_target;
137}
138
140 struct yac_interp_operator * interp,
141 double *** src_fields, double *** src_frac_masks, double ** tgt_field,
142 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
143
144 struct yac_interp_operator_direct_mf * direct_mf =
145 (struct yac_interp_operator_direct_mf *)interp;
146
147 double ** src_send_buffer = NULL;
148 size_t collection_size =
150 direct_mf->collection_selection);
151 size_t num_src_fields = direct_mf->num_src_fields;
152
154 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute");
155
156 if (direct_mf->is_source) {
157
158 size_t const * collection_indices =
160
161 if (collection_indices != NULL) {
162
163 double *** temp_src_fields =
164 xmalloc(collection_size * sizeof(*temp_src_fields));
165 temp_src_fields[0] =
166 xmalloc(collection_size * num_src_fields * sizeof(**temp_src_fields));
167 for (size_t i = 0; i < collection_size; ++i) {
168 temp_src_fields[i] = temp_src_fields[0] + i * num_src_fields;
169 for (size_t j = 0; j < num_src_fields; ++j)
170 temp_src_fields[i][j] = src_fields[collection_indices[i]][j];
171 }
172 src_fields = temp_src_fields;
173
174 if (src_frac_masks != NULL) {
175 double *** temp_src_frac_masks =
176 xmalloc(collection_size * sizeof(*temp_src_frac_masks));
177 temp_src_frac_masks[0] =
178 xmalloc(
179 collection_size * num_src_fields * sizeof(**temp_src_frac_masks));
180 for (size_t i = 0; i < collection_size; ++i) {
181 temp_src_frac_masks[i] = temp_src_frac_masks[0] + i * num_src_fields;
182 for (size_t j = 0; j < num_src_fields; ++j)
183 temp_src_frac_masks[i][j] =
184 src_frac_masks[collection_indices[i]][j];
185 }
186 src_frac_masks = temp_src_frac_masks;
187 }
188 }
189
190 if ((YAC_FRAC_MASK_VALUE_IS_VALID(frac_mask_fallback_value)) ||
191 (scale_factor != 1.0) || (scale_summand != 0.0)) {
192
193 src_send_buffer = direct_mf->src_data.buffer;
194
196 (double const * restrict **)src_fields,
197 (double const * restrict **)src_frac_masks, src_send_buffer,
199 collection_size, frac_mask_fallback_value,
200 scale_factor, scale_summand);
201
202 } else {
203
204 src_send_buffer = direct_mf->src_field_buffer;
205 for (size_t i = 0; i < collection_size; ++i)
206 for (size_t j = 0; j < num_src_fields; ++j)
207 src_send_buffer[i * num_src_fields + j] = src_fields[i][j];
208 }
209
210 if (collection_indices != NULL) {
211 free(src_fields[0]);
212 free(src_fields);
213 if (src_frac_masks != NULL) {
214 free(src_frac_masks[0]);
215 free(src_frac_masks);
216 }
217 }
218 }
219
220 double ** tgt_field_buffer = direct_mf->tgt_field_buffer;
221 if (direct_mf->is_target)
222 for (size_t i = 0; i < collection_size; ++i)
223 for (size_t j = 0; j < num_src_fields; ++j)
224 tgt_field_buffer[i * num_src_fields + j] = tgt_field[i];
225
226 // send source points to the target processes
228 direct_mf->src2tgt, (double const **)src_send_buffer, tgt_field_buffer,
229 "yac_interp_operator_direct_mf_execute");
230}
231
233 struct yac_interp_operator * interp,
234 double *** src_fields, double *** src_frac_masks, int is_target,
235 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
236
238
239 struct yac_interp_operator_direct_mf * direct_mf =
240 (struct yac_interp_operator_direct_mf *)interp;
241
242 double ** src_send_buffer = NULL;
243
244 if (direct_mf->is_source) {
245
246 size_t collection_size =
248 direct_mf->collection_selection);
249 size_t num_src_fields = direct_mf->num_src_fields;
250 size_t const * collection_indices =
252
253 if (collection_indices != NULL) {
254
255 double *** temp_src_fields =
256 xmalloc(collection_size * sizeof(*temp_src_fields));
257 temp_src_fields[0] =
258 xmalloc(collection_size * num_src_fields * sizeof(**temp_src_fields));
259 for (size_t i = 0; i < collection_size; ++i) {
260 temp_src_fields[i] = temp_src_fields[0] + i * num_src_fields;
261 for (size_t j = 0; j < num_src_fields; ++j)
262 temp_src_fields[i][j] = src_fields[collection_indices[i]][j];
263 }
264 src_fields = temp_src_fields;
265
266 if (src_frac_masks != NULL) {
267 double *** temp_src_frac_masks =
268 xmalloc(collection_size * sizeof(*temp_src_frac_masks));
269 temp_src_frac_masks[0] =
270 xmalloc(
271 collection_size * num_src_fields * sizeof(**temp_src_frac_masks));
272 for (size_t i = 0; i < collection_size; ++i) {
273 temp_src_frac_masks[i] = temp_src_frac_masks[0] + i * num_src_fields;
274 for (size_t j = 0; j < num_src_fields; ++j)
275 temp_src_frac_masks[i][j] =
276 src_frac_masks[collection_indices[i]][j];
277 }
278 src_frac_masks = temp_src_frac_masks;
279 }
280 }
281
282 // wait until previous exchange is completed
284 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_put") ==
287 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_put");
288
289 src_send_buffer = direct_mf->src_data.buffer;
290
292 (double const * restrict **)src_fields,
293 (double const * restrict **)src_frac_masks, src_send_buffer,
295 collection_size, frac_mask_fallback_value,
296 scale_factor, scale_summand);
297
298 if (collection_indices != NULL) {
299 free(src_fields[0]);
300 free(src_fields);
301 if (src_frac_masks != NULL) {
302 free(src_frac_masks[0]);
303 free(src_frac_masks);
304 }
305 }
306 }
307
309 direct_mf->src2tgt, (double const **)src_send_buffer,
310 "yac_interp_operator_direct_mf_execute_put");
311}
312
314 struct yac_interp_operator * interp, double ** tgt_field,
315 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
316
317 UNUSED(frac_mask_fallback_value);
318 UNUSED(scale_factor);
319 UNUSED(scale_summand);
320
321 struct yac_interp_operator_direct_mf * direct_mf =
322 (struct yac_interp_operator_direct_mf*)interp;
323
324 double ** tgt_field_buffer = NULL;
325
326 if (direct_mf->is_target) {
328 size_t collection_size =
330 direct_mf->collection_selection);
331 size_t num_src_fields = direct_mf->num_src_fields;
332 for (size_t i = 0; i < collection_size; ++i)
333 for (size_t j = 0; j < num_src_fields; ++j)
334 tgt_field_buffer[i * num_src_fields + j] = tgt_field[i];
335 }
336
338 direct_mf->src2tgt, tgt_field_buffer,
339 "yac_interp_operator_direct_mf_execute_get");
340}
341
343 struct yac_interp_operator * interp, double ** tgt_field,
344 double frac_mask_fallback_value, double scale_factor, double scale_summand) {
345
346 UNUSED(frac_mask_fallback_value);
347 UNUSED(scale_factor);
348 UNUSED(scale_summand);
349
350 struct yac_interp_operator_direct_mf * direct_mf =
351 (struct yac_interp_operator_direct_mf*)interp;
352
353 // wait until previous exchange is completed
355 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_get_async") ==
358 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_get_async");
359
360 double ** tgt_field_buffer = NULL;
361
362 if (direct_mf->is_target) {
364 size_t collection_size =
366 direct_mf->collection_selection);
367 size_t num_src_fields = direct_mf->num_src_fields;
368 for (size_t i = 0; i < collection_size; ++i)
369 for (size_t j = 0; j < num_src_fields; ++j)
370 tgt_field_buffer[i * num_src_fields + j] = tgt_field[i];
371 }
372
374 direct_mf->src2tgt, tgt_field_buffer,
375 "yac_interp_operator_direct_mf_execute_get_async");
376}
377
379 struct yac_interp_operator * interp) {
380
381 struct yac_interp_operator_direct_mf * direct_mf =
382 (struct yac_interp_operator_direct_mf*)interp;
383
384 return
386 direct_mf->src2tgt,
387 "yac_interp_operator_direct_mf_execute_put_test") ==
389}
390
392 struct yac_interp_operator * interp) {
393
394 struct yac_interp_operator_direct_mf * direct_mf =
395 (struct yac_interp_operator_direct_mf*)interp;
396
397 return
399 direct_mf->src2tgt,
400 "yac_interp_operator_direct_mf_execute_get_test") ==
402}
403
405 struct yac_interp_operator * interp) {
406
407 struct yac_interp_operator_direct_mf * direct_mf =
408 (struct yac_interp_operator_direct_mf*)interp;
409
411 direct_mf->src2tgt, "yac_interp_operator_direct_mf_execute_wait");
412}
413
431
433 struct yac_interp_operator * interp) {
434 if (interp == NULL) return;
435
436 struct yac_interp_operator_direct_mf * direct_mf =
437 (struct yac_interp_operator_direct_mf*)interp;
438
440 direct_mf->src2tgt, "yac_interp_operator_direct_mf_delete");
442 free(direct_mf->src_field_buffer);
443 free(direct_mf->tgt_field_buffer);
445 free(direct_mf);
446}
#define UNUSED(x)
Definition core.h:72
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.
struct Xt_redist_ * Xt_redist
void yac_interpolation_exchange_execute_get(struct yac_interpolation_exchange *exchange, double **recv_data, char const *routine)
Execute the get phase and receive target data synchronously.
enum YAC_INTERP_EXCH_TEST_STATUS yac_interpolation_exchange_put_test(struct yac_interpolation_exchange *exchange, char const *routine)
Test whether the put phase has completed.
int yac_interpolation_exchange_is_target(struct yac_interpolation_exchange *exchange)
Query whether the current process participates as target.
enum YAC_INTERP_EXCH_TEST_STATUS yac_interpolation_exchange_get_test(struct yac_interpolation_exchange *exchange, char const *routine)
Test whether the get phase has completed.
void yac_interpolation_exchange_execute(struct yac_interpolation_exchange *exchange, double const **send_data_, double **recv_data_, char const *routine)
Execute the full exchange (put + get) synchronously.
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_execute_put(struct yac_interpolation_exchange *exchange, double const **send_data, char const *routine)
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.
enum YAC_INTERP_EXCH_STATUS yac_interpolation_exchange_status(struct yac_interpolation_exchange *exchange, char const *routine)
void yac_interpolation_exchange_execute_get_async(struct yac_interpolation_exchange *exchange, double **recv_data, char const *routine)
Execute the get phase asynchronously.
void yac_interpolation_exchange_delete(struct yac_interpolation_exchange *exchange, char const *routine)
Delete an interpolation exchange and release resources.
void yac_interpolation_exchange_wait(struct yac_interpolation_exchange *exchange, char const *routine)
Wait for completion of pending put/get phases.
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)
Utility macros and functions for interpolation operators. This file contains utility macros for targe...
static void compute_tgt_field_direct(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)
Copy source field values to target buffers, optionally applying fractional masking and scaling.
@ 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