100 const int * src_positions,
101 const int * dst_positions);
104 const int src_displacements[num_repetitions],
105 const int dst_displacements[num_repetitions]);
115 .get_num_transfer_pos_ext
188 return xmap_intersection->
comm;
196 return xmap_intersection->
n_out;
204 return xmap_intersection->
n_in;
211 = xmap_intersection->
msg + xmap_intersection->
n_in;
212 for (
int i = 0; i < xmap_intersection->
n_out; ++i)
213 ranks[i] = out_msg[i].
rank;
220 for (
int i = 0; i < xmap_intersection->
n_in; ++i)
221 ranks[i] = in_msg[i].
rank;
237 int num_intersections,
238 const struct
Xt_com_list intersections[num_intersections],
241 int *restrict num_indices_to_remove_per_intersection)
244 size_t coverage_size = (size_t)mypart_num_indices;
247 unsigned long *restrict coverage =
xcalloc(coverage_size,
sizeof(*coverage));
250 coverage[coverage_size-1]
253 int new_num_intersections = 0;
254 size_t total_num_indices_to_remove = 0;
255 size_t curr_indices_to_remove_size = 0;
257 int *restrict intersection_pos = NULL;
259 for (
int i = 0; i < num_intersections; ++i) {
261 const Xt_int *restrict intersection_idxvec
263 int max_intersection_size
267 (
size_t)max_intersection_size *
sizeof(*intersection_pos));
273 mypart_idxlist, intersection_idxvec, max_intersection_size,
274 intersection_pos, 1);
280 int intersection_size = 0;
281 int num_indices_to_remove_isect = 0;
285 total_num_indices_to_remove
286 + (
size_t)max_intersection_size);
288 for (
int j = 0; j < max_intersection_size; ++j) {
290 int pos = intersection_pos[j];
300 intersection_pos[intersection_size] = pos;
302 + (size_t)num_indices_to_remove_isect]
303 = intersection_idxvec[j];
304 intersection_size += is_duplicate ^ 1;
305 num_indices_to_remove_isect += is_duplicate;
309 total_num_indices_to_remove += (size_t)num_indices_to_remove_isect;
310 num_indices_to_remove_per_intersection[i] = num_indices_to_remove_isect;
312 if (intersection_size > 0) {
313 resSets[new_num_intersections].transfer_pos = intersection_pos;
314 resSets[new_num_intersections].num_transfer_pos = intersection_size;
315 resSets[new_num_intersections].transfer_pos_ext_cache = NULL;
316 resSets[new_num_intersections].num_transfer_pos_ext
317 = (int)
count_pos_ext((
size_t)intersection_size, intersection_pos);
318 resSets[new_num_intersections].rank = intersections[i].rank;
319 new_num_intersections++;
320 intersection_pos = NULL;
323 free(intersection_pos);
330 unsigned long all_bits_set = ~0UL;
331 for (
size_t i = 0; i < coverage_size; ++i)
332 all_bits_set &= coverage[i];
337 .resCount = new_num_intersections,
338 .all_dst_covered = all_bits_set == ~0UL };
350 intersections[num_intersections],
353 const Xt_int *indices_to_remove,
354 const int *num_indices_to_remove_per_intersection)
356 int new_num_intersections = 0;
359 Xt_int * new_intersection_idxvec = NULL;
360 size_t curr_new_intersection_idxvec_size = 0;
361 int *restrict intersection_pos = NULL;
364 for (
int i = 0; i < num_intersections; ++i) {
366 const Xt_int *restrict intersection_idxvec
368 int intersection_size
370 intersection_pos =
xrealloc(intersection_pos,
371 (
size_t)intersection_size
372 *
sizeof(*intersection_pos));
374 int num_indices_to_remove = num_indices_to_remove_per_intersection[i];
375 if (num_indices_to_remove > 0) {
378 new_intersection_idxvec, curr_new_intersection_idxvec_size,
379 intersection_size - num_indices_to_remove + 1);
380 int new_intersection_size = 0;
382 for (
int j = 0; j < intersection_size; ++j) {
386 Xt_int idx = intersection_idxvec[j];
389 for (
int k = 0; k < num_indices_to_remove; ++k)
390 discard |= (idx == indices_to_remove[offset + k]);
392 new_intersection_idxvec[new_intersection_size] = idx;
393 new_intersection_size += !discard;
396 intersection_idxvec = new_intersection_idxvec;
397 intersection_size = new_intersection_size;
398 offset = offset + num_indices_to_remove;
405 mypart_idxlist, intersection_idxvec, intersection_size,
406 intersection_pos, 0);
409 if (intersection_size > 0) {
410 resSets[new_num_intersections].transfer_pos = intersection_pos;
411 resSets[new_num_intersections].num_transfer_pos = intersection_size;
412 for (
int j = 0; j < intersection_size; ++j)
413 if (intersection_pos[j] > max_pos_) max_pos_ = intersection_pos[j];
414 resSets[new_num_intersections].transfer_pos_ext_cache = NULL;
415 resSets[new_num_intersections].num_transfer_pos_ext
416 = (int)
count_pos_ext((
size_t)intersection_size, intersection_pos);
417 resSets[new_num_intersections].rank = intersections[i].rank;
418 new_num_intersections++;
419 intersection_pos = NULL;
423 free(new_intersection_idxvec);
424 free(intersection_pos);
426 return (
struct tps_result){ .max_pos = max_pos_,
427 .resCount = new_num_intersections };
433 src_com[num_src_intersections],
434 int num_dst_intersections,
436 dst_com[num_dst_intersections],
437 int *restrict num_src_indices_to_remove_per_intersection,
438 Xt_int *dst_indices_to_remove,
440 num_dst_indices_to_remove_per_intersection,
444 MPI_Request * requests
445 =
xmalloc((
size_t)(num_src_intersections + 2 * num_dst_intersections) *
447 MPI_Request *send_header_requests = requests,
448 *recv_requests = requests + num_dst_intersections,
449 *send_data_requests = recv_requests + num_src_intersections;
452 for (
int i = 0; i < num_src_intersections; ++i)
454 num_src_indices_to_remove_per_intersection + i, 1, MPI_INT,
457 comm, recv_requests+i), comm);
462 unsigned num_nonempty_dst_intersections = 0;
463 for (
int i = 0; i < num_dst_intersections; ++i) {
466 num_dst_indices_to_remove_per_intersection + i), 1, MPI_INT,
469 comm, send_header_requests + i), comm);
471 if (num_dst_indices_to_remove_per_intersection[i] > 0) {
474 dst_indices_to_remove + offset,
475 num_dst_indices_to_remove_per_intersection[i],
Xt_int_dt,
478 comm, send_data_requests + num_nonempty_dst_intersections),
480 offset += num_dst_indices_to_remove_per_intersection[i];
481 ++num_nonempty_dst_intersections;
486 xt_mpi_call(MPI_Waitall(num_src_intersections + num_dst_intersections,
487 send_header_requests, MPI_STATUSES_IGNORE), comm);
489 size_t total_num_src_indices_to_recv = 0;
491 for (
int i = 0; i < num_src_intersections; ++i)
492 total_num_src_indices_to_recv
493 += (
size_t)num_src_indices_to_remove_per_intersection[i];
495 unsigned num_nonempty_src_intersections = 0;
496 Xt_int *src_indices_to_remove;
497 if (total_num_src_indices_to_recv > 0) {
499 src_indices_to_remove =
xmalloc(total_num_src_indices_to_recv
500 *
sizeof(*src_indices_to_remove));
504 for (
int i = 0; i < num_src_intersections; ++i)
505 if (num_src_indices_to_remove_per_intersection[i] > 0) {
506 ++num_nonempty_src_intersections;
508 src_indices_to_remove + offset,
509 num_src_indices_to_remove_per_intersection[i],
513 send_data_requests - num_nonempty_src_intersections),
516 offset += num_src_indices_to_remove_per_intersection[i];
520 src_indices_to_remove = NULL;
524 xt_mpi_call(MPI_Waitall((
int)num_nonempty_src_intersections
525 + (
int)num_nonempty_dst_intersections,
526 send_data_requests-num_nonempty_src_intersections,
527 MPI_STATUSES_IGNORE), comm);
529 return src_indices_to_remove;
534 int num_src_intersections,
535 const struct Xt_com_list src_com[num_src_intersections],
536 int num_dst_intersections,
537 const struct Xt_com_list dst_com[num_dst_intersections],
542 int *num_src_indices_to_remove_per_intersection =
543 xmalloc(((
size_t)num_src_intersections + (
size_t)num_dst_intersections)
545 *num_dst_indices_to_remove_per_intersection =
546 num_src_indices_to_remove_per_intersection + num_src_intersections;
550 num_dst_intersections, dst_com, dst_idxlist_local, xmap->
msg,
551 num_dst_indices_to_remove_per_intersection);
556 Xt_int *src_indices_to_remove
558 num_src_intersections, src_com, num_dst_intersections, dst_com,
559 num_src_indices_to_remove_per_intersection,
560 dst_indices_to_remove, num_dst_indices_to_remove_per_intersection,
563 free(dst_indices_to_remove);
564 num_src_indices_to_remove_per_intersection
565 =
xrealloc(num_src_indices_to_remove_per_intersection,
566 (
size_t)num_src_intersections *
sizeof(
int));
570 num_src_intersections, src_com, src_idxlist_local, xmap->
msg + xmap->
n_in,
571 src_indices_to_remove, num_src_indices_to_remove_per_intersection);
575 free(src_indices_to_remove);
576 free(num_src_indices_to_remove_per_intersection);
577 return all_dst_covered;
583 src_com[num_src_intersections],
584 int num_dst_intersections,
586 dst_com[num_dst_intersections],
594 = (size_t)num_dst_intersections + (
size_t)num_src_intersections;
604 num_src_intersections, src_com,
605 num_dst_intersections, dst_com,
606 src_idxlist, dst_idxlist, comm)) {
610 int * found_index_mask =
xcalloc((
size_t)num_dst_indices,
611 sizeof(*found_index_mask));
612 int * index_positions =
xmalloc((
size_t)num_dst_indices
613 *
sizeof(*index_positions));
615 for (
size_t i = 0; i < (size_t)num_dst_intersections; ++i) {
617 num_dst_indices, index_positions, 0);
618 for (
size_t j = 0; j < (size_t)num_dst_indices; ++j)
619 found_index_mask[j] |= index_positions[j] != -1;
622 int first_missing_pos = 0;
623 while ((first_missing_pos < (num_dst_indices - 1)) &&
624 (found_index_mask[first_missing_pos])) ++first_missing_pos;
625 free(found_index_mask);
626 free(index_positions);
628 print_miss_msg(dst_idxlist, first_missing_pos, comm, __FILE__, __LINE__);
631 int n_in = xmap->
n_in, n_out = xmap->
n_out;
632 size_t new_num_isect = (size_t)n_in + (
size_t)n_out;
633 if (new_num_isect != num_isect)
634 xmap =
xrealloc(xmap,
sizeof (*xmap) + (new_num_isect
652 int *pos,
const int *orig_pos,
657 int *pos,
const int *orig_pos,
void *state)
660 memcpy(pos, orig_pos,
sizeof (*pos) * num_pos);
664 typedef void (*
Xt_pos_ncopy)(
size_t num_pos,
int *pos,
const int *orig_pos,
665 void *state,
int num_repetitions,
666 const int displacements[num_repetitions]);
673 int *max_pos_,
int num_repetitions,
675 *nmsg_copy = (int)nmsg;
677 for (
size_t i = 0; i < nmsg; ++i) {
678 size_t num_transfer_pos
679 = (size_t)(msg_copy[i].num_transfer_pos
680 = num_repetitions * msg[i].num_transfer_pos);
681 msg_copy[i].rank = msg[i].rank;
682 msg_copy[i].transfer_pos_ext_cache = NULL;
683 size_t size_transfer_pos
684 = num_transfer_pos *
sizeof (*(msg[i].transfer_pos));
685 msg_copy[i].transfer_pos =
xmalloc(size_transfer_pos);
687 = pos_copy(num_transfer_pos,
688 msg_copy[i].transfer_pos, msg[i].transfer_pos,
693 msg_copy[i].num_transfer_pos_ext = msg[i].num_transfer_pos_ext;
695 msg_copy[i].num_transfer_pos_ext =
696 (int)(
count_pos_ext(num_transfer_pos, msg_copy[i].transfer_pos));
709 size_t n_in = (size_t)xmap_intersection->
n_in,
710 n_out = (
size_t)xmap_intersection->
n_out,
711 num_isect = n_in + n_out;
712 xmap_intersection_new
713 =
xmalloc(
sizeof (*xmap_intersection_new)
715 xmap_intersection_new->vtable = xmap_intersection->
vtable;
716 xmap_intersection_new->n_in = (int)n_in;
717 xmap_intersection_new->n_out = (int)n_out;
718 xmap_intersection_new->max_src_pos = xmap_intersection->
max_src_pos;
719 xmap_intersection_new->max_dst_pos = xmap_intersection->
max_dst_pos;
721 &xmap_intersection_new->n_in,
722 xmap_intersection_new->msg,
723 &xmap_intersection_new->max_dst_pos,
725 pos_copy_in, pci_state);
727 &xmap_intersection_new->n_out,
728 xmap_intersection_new->msg+n_in,
729 &xmap_intersection_new->max_src_pos,
731 pos_copy_out, pco_state);
732 xmap_intersection_new->comm
734 &xmap_intersection_new->tag_offset);
735 return (
Xt_xmap)xmap_intersection_new;
748 for (
int i = 0; i < nmsg; ++i) {
749 free(msg[i].transfer_pos_ext_cache);
750 free(msg[i].transfer_pos);
758 int num_isect = xmap_intersection->
n_in + xmap_intersection->
n_out;
762 free(xmap_intersection);
769 if (xmap_intersection->
n_in == 0)
775 iter->
msg = xmap_intersection->
msg;
785 if (xmap_intersection->
n_out == 0)
791 iter->
msg = xmap_intersection->
msg + xmap_intersection->
n_in;
802 static inline struct a2abuf
805 size_t buffer_size = 0;
806 for (
int i = 0; i < n; ++i)
807 buffer_size += (
size_t)msgs[i].num_transfer_pos;
809 int *restrict
counts =
xmalloc((2 * (
size_t)comm_size + buffer_size)
813 for (
int i = 0; i < comm_size; ++i)
816 for (
int i = 0; i < n; ++i)
817 counts[msgs[i].rank] = msgs[i].num_transfer_pos;
819 for (
int i = 0, accu = 0; i < comm_size; ++i) {
831 xt_mpi_call(MPI_Comm_size(comm, &comm_size), comm);
837 for (
int i = 0; i < n_out; ++i) {
851 in.buffer, in.counts, in.displs, MPI_INT,
854 for (
int i = 0; i < n_in; ++i) {
861 in.buffer + in.displs[curr_msg->
rank], (
size_t)count,
886 int n_out = xmap_intersection_new->
n_out;
887 int n_in = xmap_intersection_new->
n_in;
889 *out_msg = in_msg+n_in;
902 Xt_abort(comm,
"ERROR(xmap_intersection_reorder):invalid reorder type",
906 return (
Xt_xmap)xmap_intersection_new;
911 int *restrict pos,
const int *restrict orig_pos,
void *new_pos_)
913 const int *restrict new_pos = new_pos_;
915 for (
size_t i = 0; i < num_pos; ++i) {
916 int np = new_pos[orig_pos[i]];
926 const int *src_positions,
927 const int *dst_positions) {
942 const int *restrict orig_pos,
void *state)
951 for (
size_t j = 0; j < num_pos; ++j, ++k) {
952 int np = orig_pos[j] + curr_disp;
971 .displacements = src_displacements },
975 .displacements = dst_displacements });
980 const struct Xt_com_pos *restrict com,
int *max_pos) {
983 for (
int i = 0; i < count; ++i) {
984 int num_transfer_pos = com[i].num_transfer_pos;
985 int *restrict transfer_pos =
986 xmalloc((
size_t)num_transfer_pos *
sizeof(*transfer_pos));
987 int rank = com[i].rank;
988 const int *restrict com_transfer_pos = com[i].transfer_pos;
989 for (
int j = 0; j < num_transfer_pos; ++j)
990 if (com_transfer_pos[j] > max_pos_) max_pos_ = com_transfer_pos[j];
991 msgs[i].transfer_pos = transfer_pos;
992 msgs[i].transfer_pos_ext_cache = NULL;
993 msgs[i].num_transfer_pos = num_transfer_pos;
994 msgs[i].num_transfer_pos_ext =
995 (int)(
count_pos_ext((
size_t)num_transfer_pos, transfer_pos));
997 memcpy(transfer_pos, com_transfer_pos,
998 (
size_t)num_transfer_pos *
sizeof(*transfer_pos));
1000 *max_pos = max_pos_;
1005 int num_src_msg,
const struct Xt_com_pos src_com[num_src_msg],
1006 int num_dst_msg,
const struct Xt_com_pos dst_com[num_dst_msg],
1012 size_t num_msg = (size_t)num_src_msg + (
size_t)num_dst_msg;
1017 xmap->
n_in = num_dst_msg;
1018 xmap->
n_out = num_src_msg;
1023 num_src_msg, xmap->
msg + num_dst_msg, src_com, &xmap->
max_src_pos);
1032 if (iter_intersection == NULL || iter_intersection->
msgs_left == 0)
1035 iter_intersection->
msg++;
1043 assert(iter != NULL);
1050 assert(iter != NULL);
1057 assert(iter != NULL);
1058 if (!
xmii(iter)->msg->transfer_pos_ext_cache) {
1062 xmalloc(num_transfer_pos_ext *
sizeof(*transfer_pos_ext)));
1064 xmii(iter)->msg->transfer_pos,
1065 num_transfer_pos_ext, transfer_pos_ext);
1072 assert(iter != NULL);
1079 assert(iter != NULL);
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
integer, parameter, public sp
add versions of standard API functions not returning on error
#define xrealloc(ptr, size)
#define xcalloc(nmemb, size)
void xt_quicksort_int(int a[], size_t n)
void xt_quicksort_int_permutation(int a[], size_t n, int permutation[])
const struct Xt_xmap_vtable * vtable
struct exchange_data msg[]
const struct Xt_xmap_iter_vtable * vtable
struct exchange_data * msg
int(* next)(Xt_xmap_iter iter)
MPI_Comm(* get_communicator)(Xt_xmap)
struct Xt_pos_ext * transfer_pos_ext_cache
const int *restrict displacements
Xt_int * indices_to_remove
int xt_idxlist_get_num_indices(Xt_idxlist idxlist)
int xt_idxlist_get_positions_of_indices(Xt_idxlist idxlist, const Xt_int *indices, int num_indices, int *positions, int single_match_only)
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
MPI_Comm xt_mpi_comm_smart_dup(MPI_Comm comm, int *tag_offset)
void xt_mpi_comm_smart_dedup(MPI_Comm *comm, int tag_offset)
#define xt_mpi_call(call, comm)
@ xt_mpi_tag_xmap_intersection_data_exchange
@ xt_mpi_tag_xmap_intersection_header_exchange
exchange map declarations
@ XT_REORDER_RECV_UP
optimise data access on receiver side
@ XT_REORDER_NONE
no reordering
@ XT_REORDER_SEND_UP
optimise data access on sender side
contains declaration for the exchange map data structure
static const struct Xt_xmap_vtable xmap_intersection_vtable
static Xt_xmap xmap_intersection_update_positions(Xt_xmap xmap, const int *src_positions, const int *dst_positions)
static Xt_xmap_iter xmap_intersection_get_in_iterator(Xt_xmap xmap)
struct Xt_xmap_iter_intersection_ * Xt_xmap_iter_intersection
static Xt_xmap xmap_intersection_spread(Xt_xmap xmap, int num_repetitions, const int src_displacements[num_repetitions], const int dst_displacements[num_repetitions])
static const struct Xt_xmap_iter_vtable xmap_iterator_intersection_vtable
void(* Xt_pos_ncopy)(size_t num_pos, int *pos, const int *orig_pos, void *state, int num_repetitions, const int displacements[num_repetitions])
static int xmap_intersection_iterator_get_rank(Xt_xmap_iter iter)
static struct a2abuf setup_buffer(int comm_size, int n, const struct exchange_data *msgs)
static Xt_xmap_intersection xmi(void *xmap)
int(* Xt_pos_copy)(size_t num_pos, int *pos, const int *orig_pos, void *state)
static void xmap_intersection_msg_delete(int nmsg, struct exchange_data *msg)
static Xt_xmap xmap_intersection_copy_(Xt_xmap xmap, int num_repetitions, Xt_pos_copy pos_copy_in, void *pci_state, Xt_pos_copy pos_copy_out, void *pco_state)
struct Xt_xmap_intersection_ * Xt_xmap_intersection
static void xmap_intersection_get_source_ranks(Xt_xmap xmap, int *ranks)
static void init_exchange_data_from_com_pos(int count, struct exchange_data *restrict msgs, const struct Xt_com_pos *restrict com, int *max_pos)
static int xmap_intersection_get_max_dst_pos(Xt_xmap xmap)
static void reorder_transfer_pos(int n_out, int n_in, struct exchange_data *out_msg, struct exchange_data *in_msg, MPI_Comm comm)
static int subst_positions(size_t num_pos, int *restrict pos, const int *restrict orig_pos, void *new_pos_)
static void xmap_intersection_get_destination_ranks(Xt_xmap xmap, int *ranks)
static void xmap_intersection_msg_copy(size_t nmsg, const struct exchange_data *restrict msg, int *nmsg_copy, struct exchange_data *restrict msg_copy, int *max_pos_, int num_repetitions, Xt_pos_copy pos_copy, void *pos_copy_state)
Xt_xmap xt_xmap_intersection_pos_new(int num_src_msg, const struct Xt_com_pos src_com[num_src_msg], int num_dst_msg, const struct Xt_com_pos dst_com[num_dst_msg], MPI_Comm comm)
static int pos_copy_spread(size_t num_pos, int *restrict pos, const int *restrict orig_pos, void *state)
static int xmap_intersection_get_num_sources(Xt_xmap xmap)
Xt_xmap xt_xmap_intersection_new(int num_src_intersections, const struct Xt_com_list src_com[num_src_intersections], int num_dst_intersections, const struct Xt_com_list dst_com[num_dst_intersections], Xt_idxlist src_idxlist, Xt_idxlist dst_idxlist, MPI_Comm comm)
static Xt_xmap xmap_intersection_copy(Xt_xmap xmap)
static struct tps_result generate_dir_transfer_pos_src(int num_intersections, const struct Xt_com_list intersections[num_intersections], Xt_idxlist mypart_idxlist, struct exchange_data *restrict resSets, const Xt_int *indices_to_remove, const int *num_indices_to_remove_per_intersection)
static MPI_Comm xmap_intersection_get_communicator(Xt_xmap xmap)
static void xmap_intersection_delete(Xt_xmap xmap)
static void xmap_intersection_iterator_delete(Xt_xmap_iter iter)
static Xt_xmap_iter_intersection xmii(void *iter)
static int xmap_intersection_iterator_next(Xt_xmap_iter iter)
static Xt_xmap_iter xmap_intersection_get_out_iterator(Xt_xmap xmap)
static int pos_copy_verbatim(size_t num_pos, int *pos, const int *orig_pos, void *state)
static int const * xmap_intersection_iterator_get_transfer_pos(Xt_xmap_iter iter)
static int xmap_intersection_iterator_get_num_transfer_pos_ext(Xt_xmap_iter iter)
static int xmap_intersection_get_num_destinations(Xt_xmap xmap)
static const struct Xt_pos_ext * xmap_intersection_iterator_get_transfer_pos_ext(Xt_xmap_iter iter)
static int xmap_intersection_iterator_get_num_transfer_pos(Xt_xmap_iter iter)
static int xmap_intersection_get_max_src_pos(Xt_xmap xmap)
static struct tpd_result generate_dir_transfer_pos_dst(int num_intersections, const struct Xt_com_list intersections[num_intersections], Xt_idxlist mypart_idxlist, struct exchange_data *restrict resSets, int *restrict num_indices_to_remove_per_intersection)
static int generate_transfer_pos(struct Xt_xmap_intersection_ *xmap, int num_src_intersections, const struct Xt_com_list src_com[num_src_intersections], int num_dst_intersections, const struct Xt_com_list dst_com[num_dst_intersections], Xt_idxlist src_idxlist_local, Xt_idxlist dst_idxlist_local, MPI_Comm comm)
static Xt_xmap xmap_intersection_reorder(Xt_xmap xmap, enum xt_reorder_type type)
static Xt_int * exchange_points_to_remove(int num_src_intersections, const struct Xt_com_list src_com[num_src_intersections], int num_dst_intersections, const struct Xt_com_list dst_com[num_dst_intersections], int *restrict num_src_indices_to_remove_per_intersection, Xt_int *dst_indices_to_remove, const int *restrict num_dst_indices_to_remove_per_intersection, int tag_offset, MPI_Comm comm)
Utility functions shared by xt_xmap_intersection and xt_xmap_intersection_ext.
static void print_miss_msg(Xt_idxlist dst_idxlist, int missing_pos, MPI_Comm comm, const char *source, int line) __attribute__((noreturn))
static size_t count_pos_ext(size_t num_pos, const int *restrict pos)
static void generate_pos_ext(size_t num_pos, const int *restrict pos, size_t num_pos_ext, struct Xt_pos_ext *restrict pos_ext)