YetAnotherCoupler 3.5.2
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 "utils_core.h"
9
16
26
42
43static Xt_redist combine_redists(
44 Xt_redist * redists, size_t num_redists, size_t collection_size) {
45
46 // check redists
47 if (redists != NULL) {
48 int redists_are_null = redists[0] == NULL;
49 for (size_t i = 1; i < num_redists; ++i)
51 redists_are_null == (redists[i] == NULL),
52 "ERROR(combine_redists): invalid argument")
53 if (redists_are_null) return NULL;
54 } else {
55 return NULL;
56 }
57
58 if (collection_size == 1) {
59 if (num_redists == 1) return xt_redist_copy(redists[0]);
60 else
61 return
62 xt_redist_collection_new(
63 redists, (int)(num_redists * collection_size), -1,
64 xt_redist_get_MPI_Comm(redists[0]));
65
66 } else {
67 Xt_redist * redists_buffer =
68 xmalloc(collection_size * num_redists * sizeof(*redists_buffer));
69 for (size_t i = 0; i < collection_size; ++i)
70 for (size_t j = 0; j < num_redists; ++j)
71 redists_buffer[i * num_redists + j] = redists[j];
72 Xt_redist redist =
73 xt_redist_collection_new(
74 redists_buffer, (int)(num_redists * collection_size), -1,
75 xt_redist_get_MPI_Comm(redists[0]));
76 free(redists_buffer);
77 return redist;
78 }
79}
80
82 struct yac_interpolation_exchange * exchange, int is_put,
83 char const * routine_name) {
84
86 exchange->empty_state != EXCHANGE_INVALID,
87 "ERROR(%s): state of exchange \"%s\" is inconsistent",
88 routine_name, exchange->name);
89
90 if (exchange->empty_state == EXCHANGE_UNSET)
91 exchange->empty_state =
93
94 if ((is_put && (exchange->empty_state == EXCHANGE_AT_PUT)) ||
95 (!is_put && (exchange->empty_state == EXCHANGE_AT_GET)))
96 xt_redist_s_exchange(
97 exchange->redist, exchange->count,
98 (const void **)(exchange->dummy_buffer),
99 (void **)(exchange->dummy_buffer));
100}
101
103 Xt_redist redist, size_t count, char const * name) {
104
105 struct yac_interpolation_exchange * exchange = xmalloc(1 * sizeof(*exchange));
106
107 exchange->name = strdup(name);
108
109 exchange->redist = redist;
110 exchange->request = XT_REQUEST_NULL;
111 exchange->state = EXCHANGE_IDLE;
112 exchange->count = count;
113
114 exchange->is_source =
115 (redist != NULL) && (xt_redist_get_num_send_msg(redist) > 0);
116 exchange->is_target =
117 (redist != NULL) && (xt_redist_get_num_recv_msg(redist) > 0);
118 exchange->temp_send_buffer =
119 xmalloc(exchange->count * sizeof(*(exchange->temp_send_buffer)));
120 exchange->temp_recv_buffer =
121 xmalloc(exchange->count * sizeof(*(exchange->temp_recv_buffer)));
122 exchange->dummy_buffer =
123 xcalloc(exchange->count, sizeof(*(exchange->dummy_buffer)));
124
125 exchange->empty_state =
126 (exchange->is_source || exchange->is_target)?
128
129 return exchange;
130}
131
133 Xt_redist * redists, size_t num_fields, size_t collection_size,
134 int with_frac_mask, char const * name) {
135
136 if (with_frac_mask) collection_size *= 2;
137
138 Xt_redist redist =
139 combine_redists(redists, num_fields, collection_size);
140
141 return
143 redist, num_fields * collection_size, name);
144}
145
147 struct yac_interpolation_exchange * exchange) {
148
150 (exchange->redist == NULL)?NULL:xt_redist_copy(exchange->redist),
151 exchange->count, exchange->name);
152}
153
155 struct yac_interpolation_exchange * exchange) {
156
157 return exchange->is_source;
158}
159
161 struct yac_interpolation_exchange * exchange) {
162
163 return exchange->is_target;
164}
165
167 struct yac_interpolation_exchange * exchange, char const * routine_name) {
168
169 // ensure that the exchange is not in waiting state
171 exchange->state != EXCHANGE_WAIT_PUT, "ERROR(%s): "
172 "the \"%s\"-exchange is currently in wait state (are you missing a get?)",
173 routine_name, exchange->name);
175 exchange->state != EXCHANGE_WAIT_GET, "ERROR(%s): "
176 "the \"%s\"-exchange is currently in wait state (are you missing a put?)",
177 routine_name, exchange->name);
178
179 // if a previous put has not yet been completed
180 if (exchange->state == EXCHANGE_ACTIVE) {
181 xt_request_wait(&(exchange->request));
182 exchange->state = EXCHANGE_IDLE;
183 }
184}
185
187 struct yac_interpolation_exchange * exchange, char const * routine_name) {
188
190 (exchange->state == EXCHANGE_IDLE) ||
191 (exchange->state == EXCHANGE_WAIT_PUT) ||
192 (exchange->state == EXCHANGE_WAIT_GET) ||
193 (exchange->state == EXCHANGE_ACTIVE),
194 "ERROR(%s): invalid exchange state", routine_name);
195
196 switch (exchange->state) {
197 default:
198 case (EXCHANGE_IDLE):
199 case (EXCHANGE_WAIT_GET):
200 return 1;
201 case (EXCHANGE_WAIT_PUT):
202 return 0;
203 case (EXCHANGE_ACTIVE): {
204 int flag;
205 xt_request_test(&(exchange->request), &flag);
206 if (flag) exchange->state = EXCHANGE_IDLE;
207 return flag;
208 }
209 }
210}
211
213 struct yac_interpolation_exchange * exchange, char const * routine_name) {
214
216 (exchange->state == EXCHANGE_IDLE) ||
217 (exchange->state == EXCHANGE_WAIT_PUT) ||
218 (exchange->state == EXCHANGE_WAIT_GET) ||
219 (exchange->state == EXCHANGE_ACTIVE),
220 "ERROR(%s): invalid exchange state", routine_name);
221
222 switch (exchange->state) {
223 default:
224 case (EXCHANGE_IDLE):
225 case (EXCHANGE_WAIT_PUT):
226 return 1;
227 case (EXCHANGE_WAIT_GET):
228 return 0;
229 case (EXCHANGE_ACTIVE): {
230 int flag;
231 xt_request_test(&(exchange->request), &flag);
232 if (flag) exchange->state = EXCHANGE_IDLE;
233 return flag;
234 }
235 }
236}
237
239 struct yac_interpolation_exchange * exchange, char const * routine_name) {
240
242 (exchange->state == EXCHANGE_IDLE) ||
243 (exchange->state == EXCHANGE_WAIT_PUT) ||
244 (exchange->state == EXCHANGE_WAIT_GET) ||
245 (exchange->state == EXCHANGE_ACTIVE),
246 "ERROR(%s): invalid exchange state", routine_name);
247
248 switch (exchange->state) {
249 default:
250 case (EXCHANGE_IDLE):
252 case (EXCHANGE_WAIT_PUT):
254 case (EXCHANGE_WAIT_GET):
256 case (EXCHANGE_ACTIVE):
258 }
259}
260
262 struct yac_interpolation_exchange * exchange, double const ** send_data,
263 char const * routine_name) {
264
265 // if we have to do an exchange
266 if (exchange->redist != NULL) {
267
268 switch ((exchange->is_source << 1) +
269 (exchange->is_target)) {
270
271 // neither source nor target
272 default:
273 case(0): {
274
275 // we should be in idle state
277 exchange->state == EXCHANGE_IDLE,
278 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
279 "internal error?", routine_name, exchange->name);
280 do_empty_exchange(exchange, 1, routine_name);
281 break;
282 }
283 // only target
284 case(1): {
285
286 // we should be either in idle or active state
288 (exchange->state == EXCHANGE_IDLE) ||
289 (exchange->state == EXCHANGE_ACTIVE),
290 "ERROR(%s): the \"%s\"-exchange is invalid state, "
291 "internal error?", routine_name, exchange->name);
292 yac_interpolation_exchange_get_test(exchange, routine_name);
293 break;
294 }
295 // only source
296 case(2): {
297
298 // if a previous exchange operation has not yet been completed
299 if (exchange->state == EXCHANGE_ACTIVE) {
300 xt_request_wait(&(exchange->request));
301 exchange->state = EXCHANGE_IDLE;
302 }
303
304 // ensure that we are in idle state
306 exchange->state == EXCHANGE_IDLE,
307 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
308 "are you missing a get or wait?", routine_name, exchange->name);
309
310 // do the actual exchange
311 xt_redist_a_exchange(
312 exchange->redist, exchange->count,
313 (void const **)send_data, exchange->dummy_buffer,
314 &(exchange->request));
315 exchange->state = EXCHANGE_ACTIVE;
316 break;
317 }
318 // both source and target
319 case(3): {
320
321 // if a previous exchange operation has not yet been completed
322 if (exchange->state == EXCHANGE_ACTIVE) {
323 xt_request_wait(&(exchange->request));
324 exchange->state = EXCHANGE_IDLE;
325 }
326
328 (exchange->state == EXCHANGE_IDLE) ||
329 (exchange->state == EXCHANGE_WAIT_GET),
330 "ERROR(%s): the \"%s\"-exchange is in an invalid state",
331 routine_name, exchange->name);
332
333 switch (exchange->state) {
334
335 default:
336 case (EXCHANGE_WAIT_GET): {
337
338 // do the actual exchange
339 xt_redist_a_exchange(
340 exchange->redist, exchange->count, (void const **)send_data,
341 exchange->temp_recv_buffer, &(exchange->request));
342 exchange->state = EXCHANGE_ACTIVE;
343
344 break;
345 }
346 case (EXCHANGE_IDLE): {
347
348 // we have to wait for the receive array before we can start the
349 // actual exchange, therefore we just buffer the send array
350 for (size_t i = 0; i < exchange->count; ++i)
351 exchange->temp_send_buffer[i] =
352 (void const *)(send_data[i]);
353 exchange->state = EXCHANGE_WAIT_PUT;
354 }
355 }
356 break;
357 }
358 }
359 }
360}
361
363 struct yac_interpolation_exchange * exchange, double ** recv_data,
364 int is_async, char const * routine_name) {
365
366 // if we have to do an exchange
367 if (exchange->redist != NULL) {
368
369 switch ((exchange->is_source << 1) +
370 (exchange->is_target)) {
371
372 // neither source nor target
373 default:
374 case(0): {
375
376 // we should be in idle state
378 exchange->state == EXCHANGE_IDLE,
379 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
380 "internal error?", routine_name, exchange->name);
381 do_empty_exchange(exchange, 0, routine_name);
382 break;
383 }
384 // only target
385 case(1): {
386
387 // if a previous exchange operation has not yet been completed
388 if (exchange->state == EXCHANGE_ACTIVE) {
389 xt_request_wait(&(exchange->request));
390 exchange->state = EXCHANGE_IDLE;
391 }
392
393 // we should be in idle state
395 exchange->state == EXCHANGE_IDLE,
396 "ERROR(%s): the \"%s\"-exchange is not in idle state, "
397 "internal error?", routine_name, exchange->name);
398
399 // if we have to send data
400 void const ** send_data =
401 (void const **)(exchange->dummy_buffer);
402
403 // do the actual exchange
404 if (is_async) {
405 xt_redist_a_exchange(
406 exchange->redist, exchange->count, send_data, (void **)recv_data,
407 &(exchange->request));
408 exchange->state = EXCHANGE_ACTIVE;
409 } else {
410 xt_redist_s_exchange(
411 exchange->redist, exchange->count, send_data, (void **)recv_data);
412 exchange->state = EXCHANGE_IDLE;
413 }
414 break;
415 }
416 // only source
417 case(2): {
418
419 // if this exchange is currently active
420 if (exchange->state == EXCHANGE_ACTIVE) {
421
422 if (is_async) {
423
424 yac_interpolation_exchange_get_test(exchange, routine_name);
425
426 } else {
427
428 xt_request_wait(&(exchange->request));
429 exchange->state = EXCHANGE_IDLE;
430 }
431 }
432 break;
433 }
434 // both source and target
435 case(3): {
436
437 // if a previous exchange operation has not yet been completed
438 if (exchange->state == EXCHANGE_ACTIVE) {
439 xt_request_wait(&(exchange->request));
440 exchange->state = EXCHANGE_IDLE;
441 }
442
444 (exchange->state == EXCHANGE_IDLE) ||
445 (exchange->state == EXCHANGE_WAIT_PUT),
446 "ERROR(%s): the \"%s\"-exchange is in an invalid state",
447 routine_name, exchange->name);
448
449 switch (exchange->state) {
450
451 default:
452 case (EXCHANGE_WAIT_PUT): {
453
454 void const ** send_data =
455 exchange->temp_send_buffer;
456
457 // do the actual exchange
458 if (is_async) {
459 xt_redist_a_exchange(
460 exchange->redist, exchange->count, send_data,
461 (void **)recv_data, &(exchange->request));
462 exchange->state = EXCHANGE_ACTIVE;
463 } else {
464 xt_redist_s_exchange(
465 exchange->redist, exchange->count, send_data,
466 (void **)recv_data);
467 exchange->state = EXCHANGE_IDLE;
468 }
469 break;
470 };
471
472 case (EXCHANGE_IDLE): {
473
475 is_async,
476 "ERROR(%s): the \"%s\"-exchange is in an invalid state, "
477 "is there a put missing?", routine_name, exchange->name);
478
479 // we have to wait for the send array before we can start the
480 // actual exchange, therefore we just buffer the recv array
481 for (size_t i = 0; i < exchange->count; ++i)
482 exchange->temp_recv_buffer[i] = (void **)(recv_data[i]);
483 exchange->state = EXCHANGE_WAIT_GET;
484
485 break;
486 };
487 }
488 break;
489 }
490 }
491 }
492}
493
495 struct yac_interpolation_exchange * exchange, double ** recv_data,
496 char const * routine_name) {
498 exchange, recv_data, 0, routine_name);
499}
500
502 struct yac_interpolation_exchange * exchange, double ** recv_data,
503 char const * routine_name) {
505 exchange, recv_data, 1, routine_name);
506}
507
509 struct yac_interpolation_exchange * exchange,
510 double const ** send_data_, double ** recv_data_,
511 char const * routine_name) {
512
513 // if we have to do an exchange
514 if (exchange->redist != NULL) {
515
516 // if a previous put has not yet been completed
517 if (exchange->state == EXCHANGE_ACTIVE) {
518 xt_request_wait(&(exchange->request));
519 exchange->state = EXCHANGE_IDLE;
520 }
521
522 // ensure that the exchange is in idle state
524 exchange->state == EXCHANGE_IDLE, "ERROR(%s): "
525 "the \"%s\"-exchange is not in idle state, are you missing a get or wait?",
526 routine_name, exchange->name);
527
528 void const ** send_data =
529 exchange->is_source?
530 (void const **)(send_data_):(void const **)(exchange->dummy_buffer);
531 void ** recv_data =
532 exchange->is_target?(void **)(recv_data_):exchange->dummy_buffer;
533
534 xt_redist_s_exchange(
535 exchange->redist, exchange->count, send_data, recv_data);
536
537 exchange->state = EXCHANGE_IDLE;
538 } else {
539
540 // ensure that the exchange is in idle state
542 exchange->state == EXCHANGE_IDLE, "ERROR(%s): "
543 "the \"%s\"-exchange is not in idle state",
544 routine_name, exchange->name);
545 }
546}
547
549 struct yac_interpolation_exchange * exchange, char const * routine_name) {
550
551 if (exchange->state != EXCHANGE_IDLE)
552 yac_interpolation_exchange_wait(exchange, routine_name);
553
554 free(exchange->name);
555
556 if (exchange->redist != NULL) {
557 xt_request_wait(&(exchange->request));
558 xt_redist_delete(exchange->redist);
559 }
560 free(exchange->temp_send_buffer);
561 free(exchange->temp_recv_buffer);
562 free(exchange->dummy_buffer);
563 free(exchange);
564}
int yac_interpolation_exchange_put_test(struct yac_interpolation_exchange *exchange, char const *routine_name)
int yac_interpolation_exchange_is_target(struct yac_interpolation_exchange *exchange)
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)
void yac_interpolation_exchange_execute_get_async(struct yac_interpolation_exchange *exchange, double **recv_data, char const *routine_name)
struct yac_interpolation_exchange * yac_interpolation_exchange_copy(struct yac_interpolation_exchange *exchange)
void yac_interpolation_exchange_delete(struct yac_interpolation_exchange *exchange, char const *routine_name)
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)
void yac_interpolation_exchange_wait(struct yac_interpolation_exchange *exchange, char const *routine_name)
void yac_interpolation_exchange_execute_put(struct yac_interpolation_exchange *exchange, double const **send_data, char const *routine_name)
@ 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)
void yac_interpolation_exchange_execute(struct yac_interpolation_exchange *exchange, double const **send_data_, double **recv_data_, char const *routine_name)
static struct yac_interpolation_exchange * yac_interpolation_exchange_new_(Xt_redist redist, size_t count, char const *name)
enum YAC_INTERP_EXCH_STATUS yac_interpolation_exchange_status(struct yac_interpolation_exchange *exchange, char const *routine_name)
int yac_interpolation_exchange_get_test(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)
YAC_INTERP_EXCH_STATUS
@ YAC_INTERP_EXCH_ACTIVE
@ YAC_INTERP_EXCH_WAIT_PUT
@ YAC_INTERP_EXCH_WAIT_GET
@ YAC_INTERP_EXCH_IDLE
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
enum empty_exchange_state empty_state
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:19
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:16