YAC 3.13.2
Yet Another Coupler
Loading...
Searching...
No Matches
interpolation_exchange.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
9#include "utils_core.h"
11
18
28
48
49static Xt_redist combine_redists(
50 Xt_redist * redists, size_t num_redists, size_t collection_size) {
51
52 // check redists
53 if (redists != NULL) {
54 int redists_are_null = redists[0] == NULL;
55 for (size_t i = 1; i < num_redists; ++i)
57 redists_are_null == (redists[i] == NULL),
58 "ERROR(combine_redists): invalid argument")
59 if (redists_are_null) return NULL;
60 } else {
61 return NULL;
62 }
63
64 if (collection_size == 1) {
65 if (num_redists == 1) return xt_redist_copy(redists[0]);
66 else
67 return
68 xt_redist_collection_new(
69 redists, (int)(num_redists * collection_size), -1,
70 xt_redist_get_MPI_Comm(redists[0]));
71
72 } else {
73 Xt_redist * redists_buffer =
74 xmalloc(collection_size * num_redists * sizeof(*redists_buffer));
75 for (size_t i = 0; i < collection_size; ++i)
76 for (size_t j = 0; j < num_redists; ++j)
77 redists_buffer[i * num_redists + j] = redists[j];
78 Xt_redist redist =
79 xt_redist_collection_new(
80 redists_buffer, (int)(num_redists * collection_size), -1,
81 xt_redist_get_MPI_Comm(redists[0]));
82 free(redists_buffer);
83 return redist;
84 }
85}
86
88 struct yac_interpolation_exchange * exchange, int is_put,
89 char const * routine_name) {
90
92 exchange->empty_state != EXCHANGE_INVALID,
93 "ERROR(%s): state of exchange \"%s\" is inconsistent",
94 routine_name, exchange->name);
95
96 if (exchange->empty_state == EXCHANGE_UNSET)
97 exchange->empty_state =
99
100 if ((is_put && (exchange->empty_state == EXCHANGE_AT_PUT)) ||
101 (!is_put && (exchange->empty_state == EXCHANGE_AT_GET)))
102 xt_redist_s_exchange(
103 exchange->redist, exchange->count,
104 (const void **)(exchange->dummy_buffer),
105 (void **)(exchange->dummy_buffer));
106}
107
109 Xt_redist redist, size_t count, char const * name, int with_frac_mask) {
110
111 struct yac_interpolation_exchange * exchange = xmalloc(1 * sizeof(*exchange));
112
113 exchange->name = strdup(name);
114
115 exchange->ref_count = 1;
116
117 exchange->redist = redist;
118 exchange->request = XT_REQUEST_NULL;
119 exchange->state = EXCHANGE_IDLE;
120 exchange->count = count;
121
122 exchange->is_source =
123 (redist != NULL) && (xt_redist_get_num_send_msg(redist) > 0);
124 exchange->is_target =
125 (redist != NULL) && (xt_redist_get_num_recv_msg(redist) > 0);
126 exchange->temp_send_buffer =
127 xmalloc(exchange->count * sizeof(*(exchange->temp_send_buffer)));
128 exchange->temp_recv_buffer =
129 xmalloc(exchange->count * sizeof(*(exchange->temp_recv_buffer)));
130 exchange->dummy_buffer =
131 xcalloc(exchange->count, sizeof(*(exchange->dummy_buffer)));
132
133 exchange->empty_state =
134 (exchange->is_source || exchange->is_target)?
136
137 exchange->with_frac_mask = with_frac_mask;
138
139 return exchange;
140}
141
143 Xt_redist * redists, size_t num_fields, size_t collection_size,
144 int with_frac_mask, char const * name) {
145
147
148 Xt_redist redist =
150
151 return
154}
155
157 struct yac_interpolation_exchange * exchange) {
158
160 (exchange->redist == NULL)?NULL:xt_redist_copy(exchange->redist),
161 exchange->count, exchange->name, exchange->with_frac_mask);
162}
163
165 struct yac_interpolation_exchange * exchange) {
166
167 exchange->ref_count++;
168}
169
171 struct yac_interpolation_exchange * exchange) {
172
173 return exchange->is_source;
174}
175
177 struct yac_interpolation_exchange * exchange) {
178
179 return exchange->is_target;
180}
181
183 struct yac_interpolation_exchange * exchange, char const * routine_name) {
184
185 // ensure that the exchange is not in waiting state
187 exchange->state != EXCHANGE_WAIT_PUT, "ERROR(%s): "
188 "the \"%s\"-exchange is currently in wait state (are you missing a get?)",
189 routine_name, exchange->name);
191 exchange->state != EXCHANGE_WAIT_GET, "ERROR(%s): "
192 "the \"%s\"-exchange is currently in wait state (are you missing a put?)",
193 routine_name, exchange->name);
194
195 // if a previous put has not yet been completed
196 if (exchange->state == EXCHANGE_ACTIVE) {
197 xt_request_wait(&(exchange->request));
198 exchange->state = EXCHANGE_IDLE;
199 }
200}
201
203 struct yac_interpolation_exchange * exchange, char const * routine_name) {
204
206 (exchange->state == EXCHANGE_IDLE) ||
207 (exchange->state == EXCHANGE_WAIT_PUT) ||
208 (exchange->state == EXCHANGE_WAIT_GET) ||
209 (exchange->state == EXCHANGE_ACTIVE),
210 "ERROR(%s): invalid exchange state", routine_name);
211
212 switch (exchange->state) {
213 default:
214 case (EXCHANGE_IDLE):
215 case (EXCHANGE_WAIT_GET):
217 case (EXCHANGE_WAIT_PUT):
219 case (EXCHANGE_ACTIVE): {
220 int flag;
221 xt_request_test(&(exchange->request), &flag);
222 if (flag) exchange->state = EXCHANGE_IDLE;
224 }
225 }
226}
227
229 struct yac_interpolation_exchange * exchange, char const * routine_name) {
230
232 (exchange->state == EXCHANGE_IDLE) ||
233 (exchange->state == EXCHANGE_WAIT_PUT) ||
234 (exchange->state == EXCHANGE_WAIT_GET) ||
235 (exchange->state == EXCHANGE_ACTIVE),
236 "ERROR(%s): invalid exchange state", routine_name);
237
238 switch (exchange->state) {
239 default:
240 case (EXCHANGE_IDLE):
241 case (EXCHANGE_WAIT_PUT):
243 case (EXCHANGE_WAIT_GET):
245 case (EXCHANGE_ACTIVE): {
246 int flag;
247 xt_request_test(&(exchange->request), &flag);
248 if (flag) exchange->state = EXCHANGE_IDLE;
250 }
251 }
252}
253
255 struct yac_interpolation_exchange * exchange, char const * routine_name) {
256
258 (exchange->state == EXCHANGE_IDLE) ||
259 (exchange->state == EXCHANGE_WAIT_PUT) ||
260 (exchange->state == EXCHANGE_WAIT_GET) ||
261 (exchange->state == EXCHANGE_ACTIVE),
262 "ERROR(%s): invalid exchange state", routine_name);
263
264 switch (exchange->state) {
265 default:
266 case (EXCHANGE_IDLE):
268 case (EXCHANGE_WAIT_PUT):
270 case (EXCHANGE_WAIT_GET):
272 case (EXCHANGE_ACTIVE):
274 }
275}
276
278 struct yac_interpolation_exchange * exchange, double const ** send_data,
279 char const * routine_name) {
280
281 // if we have to do an exchange
282 if (exchange->redist != NULL) {
283
284 switch ((exchange->is_source << 1) +
285 (exchange->is_target)) {
286
287 // neither source nor target
288 default:
289 case(0): {
290
291 // we should be in idle state
293 exchange->state == EXCHANGE_IDLE,
294 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
295 "internal error?", routine_name, exchange->name);
296 do_empty_exchange(exchange, 1, routine_name);
297 break;
298 }
299 // only target
300 case(1): {
301
302 // we should be either in idle or active state
304 (exchange->state == EXCHANGE_IDLE) ||
305 (exchange->state == EXCHANGE_ACTIVE),
306 "ERROR(%s): the \"%s\"-exchange is invalid state, "
307 "internal error?", routine_name, exchange->name);
308 yac_interpolation_exchange_get_test(exchange, routine_name);
309 break;
310 }
311 // only source
312 case(2): {
313
314 // if a previous exchange operation has not yet been completed
315 if (exchange->state == EXCHANGE_ACTIVE) {
316 xt_request_wait(&(exchange->request));
317 exchange->state = EXCHANGE_IDLE;
318 }
319
320 // ensure that we are in idle state
322 exchange->state == EXCHANGE_IDLE,
323 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
324 "are you missing a get or wait?", routine_name, exchange->name);
325
326 // do the actual exchange
327 xt_redist_a_exchange(
328 exchange->redist, exchange->count,
329 (void const **)send_data, exchange->dummy_buffer,
330 &(exchange->request));
331 exchange->state = EXCHANGE_ACTIVE;
332 break;
333 }
334 // both source and target
335 case(3): {
336
337 // if a previous exchange operation has not yet been completed
338 if (exchange->state == EXCHANGE_ACTIVE) {
339 xt_request_wait(&(exchange->request));
340 exchange->state = EXCHANGE_IDLE;
341 }
342
344 (exchange->state == EXCHANGE_IDLE) ||
345 (exchange->state == EXCHANGE_WAIT_GET),
346 "ERROR(%s): the \"%s\"-exchange is in an invalid state",
347 routine_name, exchange->name);
348
349 switch (exchange->state) {
350
351 default:
352 case (EXCHANGE_WAIT_GET): {
353
354 // do the actual exchange
355 xt_redist_a_exchange(
356 exchange->redist, exchange->count, (void const **)send_data,
357 exchange->temp_recv_buffer, &(exchange->request));
358 exchange->state = EXCHANGE_ACTIVE;
359
360 break;
361 }
362 case (EXCHANGE_IDLE): {
363
364 // we have to wait for the receive array before we can start the
365 // actual exchange, therefore we just buffer the send array
366 for (size_t i = 0; i < exchange->count; ++i)
367 exchange->temp_send_buffer[i] =
368 (void const *)(send_data[i]);
369 exchange->state = EXCHANGE_WAIT_PUT;
370 }
371 }
372 break;
373 }
374 }
375 }
376}
377
379 struct yac_interpolation_exchange * exchange, double ** recv_data,
380 int is_async, char const * routine_name) {
381
382 // if we have to do an exchange
383 if (exchange->redist != NULL) {
384
385 switch ((exchange->is_source << 1) +
386 (exchange->is_target)) {
387
388 // neither source nor target
389 default:
390 case(0): {
391
392 // we should be in idle state
394 exchange->state == EXCHANGE_IDLE,
395 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
396 "internal error?", routine_name, exchange->name);
397 do_empty_exchange(exchange, 0, routine_name);
398 break;
399 }
400 // only target
401 case(1): {
402
403 // if a previous exchange operation has not yet been completed
404 if (exchange->state == EXCHANGE_ACTIVE) {
405 xt_request_wait(&(exchange->request));
406 exchange->state = EXCHANGE_IDLE;
407 }
408
409 // we should be in idle state
411 exchange->state == EXCHANGE_IDLE,
412 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
413 "internal error?", routine_name, exchange->name);
414
415 // if we have to send data
416 void const ** send_data =
417 (void const **)(exchange->dummy_buffer);
418
419 // do the actual exchange
420 if (is_async) {
421 xt_redist_a_exchange(
422 exchange->redist, exchange->count, send_data, (void **)recv_data,
423 &(exchange->request));
424 exchange->state = EXCHANGE_ACTIVE;
425 } else {
426 xt_redist_s_exchange(
427 exchange->redist, exchange->count, send_data, (void **)recv_data);
428 exchange->state = EXCHANGE_IDLE;
429 }
430 break;
431 }
432 // only source
433 case(2): {
434
435 // if this exchange is currently active
436 if (exchange->state == EXCHANGE_ACTIVE) {
437
438 if (is_async) {
439
440 yac_interpolation_exchange_get_test(exchange, routine_name);
441
442 } else {
443
444 xt_request_wait(&(exchange->request));
445 exchange->state = EXCHANGE_IDLE;
446 }
447 }
448 break;
449 }
450 // both source and target
451 case(3): {
452
453 // if a previous exchange operation has not yet been completed
454 if (exchange->state == EXCHANGE_ACTIVE) {
455 xt_request_wait(&(exchange->request));
456 exchange->state = EXCHANGE_IDLE;
457 }
458
460 (exchange->state == EXCHANGE_IDLE) ||
461 (exchange->state == EXCHANGE_WAIT_PUT),
462 "ERROR(%s): the \"%s\"-exchange is in an invalid state",
463 routine_name, exchange->name);
464
465 switch (exchange->state) {
466
467 default:
468 case (EXCHANGE_WAIT_PUT): {
469
470 void const ** send_data =
471 exchange->temp_send_buffer;
472
473 // do the actual exchange
474 if (is_async) {
475 xt_redist_a_exchange(
476 exchange->redist, exchange->count, send_data,
477 (void **)recv_data, &(exchange->request));
478 exchange->state = EXCHANGE_ACTIVE;
479 } else {
480 xt_redist_s_exchange(
481 exchange->redist, exchange->count, send_data,
482 (void **)recv_data);
483 exchange->state = EXCHANGE_IDLE;
484 }
485 break;
486 };
487
488 case (EXCHANGE_IDLE): {
489
491 is_async,
492 "ERROR(%s): the \"%s\"-exchange is in an invalid state, "
493 "is there a put missing?", routine_name, exchange->name);
494
495 // we have to wait for the send array before we can start the
496 // actual exchange, therefore we just buffer the recv array
497 for (size_t i = 0; i < exchange->count; ++i)
498 exchange->temp_recv_buffer[i] = (void **)(recv_data[i]);
499 exchange->state = EXCHANGE_WAIT_GET;
500
501 break;
502 };
503 }
504 break;
505 }
506 }
507 }
508}
509
511 struct yac_interpolation_exchange * exchange, double ** recv_data,
512 char const * routine_name) {
514 exchange, recv_data, 0, routine_name);
515}
516
518 struct yac_interpolation_exchange * exchange, double ** recv_data,
519 char const * routine_name) {
521 exchange, recv_data, 1, routine_name);
522}
523
525 struct yac_interpolation_exchange * exchange,
526 double const ** send_data_, double ** recv_data_,
527 char const * routine_name) {
528
529 // if we have to do an exchange
530 if (exchange->redist != NULL) {
531
532 // if a previous put has not yet been completed
533 if (exchange->state == EXCHANGE_ACTIVE) {
534 xt_request_wait(&(exchange->request));
535 exchange->state = EXCHANGE_IDLE;
536 }
537
538 // ensure that the exchange is in idle state
540 exchange->state == EXCHANGE_IDLE, "ERROR(%s): "
541 "the \"%s\"-exchange is not in idle state, are you missing a get or wait?",
542 routine_name, exchange->name);
543
544 void const ** send_data =
545 exchange->is_source?
546 (void const **)(send_data_):(void const **)(exchange->dummy_buffer);
547 void ** recv_data =
548 exchange->is_target?(void **)(recv_data_):exchange->dummy_buffer;
549
550 xt_redist_s_exchange(
551 exchange->redist, exchange->count, send_data, recv_data);
552
553 exchange->state = EXCHANGE_IDLE;
554 } else {
555
556 // ensure that the exchange is in idle state
558 exchange->state == EXCHANGE_IDLE, "ERROR(%s): "
559 "the \"%s\"-exchange is not in idle state",
560 routine_name, exchange->name);
561 }
562}
563
565 struct yac_interpolation_exchange * exchange) {
566
567 return exchange->with_frac_mask;
568}
569
571 struct yac_interpolation_exchange * exchange, char const * routine_name) {
572
573 if (exchange == NULL) return;
574
575 if(--(exchange->ref_count)) return;
576
577 if (exchange->state != EXCHANGE_IDLE)
578 yac_interpolation_exchange_wait(exchange, routine_name);
579
580 free(exchange->name);
581
582 if (exchange->redist != NULL) {
583 xt_request_wait(&(exchange->request));
584 xt_redist_delete(exchange->redist);
585 }
586 free(exchange->temp_send_buffer);
587 free(exchange->temp_recv_buffer);
588 free(exchange->dummy_buffer);
589 free(exchange);
590}
unsigned num_fields
#define YAC_ASSERT(exp, msg)
int yac_interpolation_exchange_is_target(struct yac_interpolation_exchange *exchange)
Query whether the current process participates as target.
static Xt_redist combine_redists(Xt_redist *redists, size_t num_redists, size_t collection_size)
static void do_empty_exchange(struct yac_interpolation_exchange *exchange, int is_put, char const *routine_name)
static struct yac_interpolation_exchange * yac_interpolation_exchange_new_(Xt_redist redist, size_t count, char const *name, int with_frac_mask)
void yac_interpolation_exchange_execute_get_async(struct yac_interpolation_exchange *exchange, double **recv_data, char const *routine_name)
Execute the get phase asynchronously.
void yac_interpolation_exchange_inc_ref_count(struct yac_interpolation_exchange *exchange)
Increase the reference count of an exchange object.
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.
static void yac_interpolation_exchange_execute_get_(struct yac_interpolation_exchange *exchange, double **recv_data, int is_async, char const *routine_name)
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.
@ EXCHANGE_AT_GET
@ EXCHANGE_AT_PUT
@ EXCHANGE_INVALID
@ EXCHANGE_UNSET
exchange is source and/or target
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.
int yac_interpolation_exchange_with_frac_mask(struct yac_interpolation_exchange *exchange)
Query whether the exchange has fractional mask support.
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)
@ EXCHANGE_WAIT_GET
contains valid put data, but is not yet communicated
@ EXCHANGE_WAIT_PUT
exchange is currently not in use
@ EXCHANGE_ACTIVE
contains valid get data, but is not yet communicated
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_TEST_STATUS
Status returned by test routines.
@ YAC_INTERP_EXCH_INCOMPLETE
Operation still in progress.
@ YAC_INTERP_EXCH_COMPLETE
No ongoing operation.
YAC_INTERP_EXCH_STATUS
Status of an interpolation exchange.
@ YAC_INTERP_EXCH_ACTIVE
Exchange is active.
@ YAC_INTERP_EXCH_WAIT_PUT
Waiting for put phase completion.
@ YAC_INTERP_EXCH_WAIT_GET
Waiting for get phase completion.
@ YAC_INTERP_EXCH_IDLE
No ongoing exchange.
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
enum empty_exchange_state empty_state
int collection_size
char const * name
Definition toy_scrip.c:114
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:30