103 .get_num_transfer_pos_ext
117 static inline Xt_xmap_iter_intersection
120 return (Xt_xmap_iter_intersection)iter;
163 static inline Xt_xmap_intersection
166 return (Xt_xmap_intersection)xmap;
171 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
173 return xmap_intersection->
comm;
178 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
181 return xmap_intersection->
n_out;
186 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
189 return xmap_intersection->
n_in;
194 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
196 for (
int i = 0; i < xmap_intersection->
n_out; ++i)
202 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
204 for (
int i = 0; i < xmap_intersection->
n_in; ++i)
228 && pos[j] == start + (~direction & (
int)(j - i)) + (direction & -(
int)(j - i)))
230 direction = direction & ((j == 1) - 1);
232 return (
struct pos_run){ .start =
start, .len = j, .direction = direction };
240 const int *restrict intersection_pos)
242 size_t i = 0, num_transfer_pos_ext = 0;
243 while (i < intersection_size) {
245 ++num_transfer_pos_ext;
247 return num_transfer_pos_ext;
254 intersections[num_intersections],
258 Xt_int ** indices_to_remove,
259 int *num_indices_to_remove_per_intersection)
262 = *resSets =
xmalloc((
size_t)num_intersections *
sizeof(**resSets));
265 size_t coverage_size = (size_t)mypart_num_indices;
268 unsigned long *restrict coverage =
xcalloc(coverage_size,
sizeof(*coverage));
271 coverage[coverage_size-1]
274 int new_num_intersections = 0;
275 size_t total_num_indices_to_remove = 0;
276 size_t curr_indices_to_remove_size = 0;
277 Xt_int *restrict indices_to_remove_ = *indices_to_remove;
278 int *restrict intersection_pos = NULL;
280 for (
int i = 0; i < num_intersections; ++i) {
282 const Xt_int *restrict intersection_idxvec
284 int max_intersection_size
288 (
size_t)max_intersection_size *
sizeof(*intersection_pos));
291 mypart_idxlist, intersection_idxvec, max_intersection_size,
292 intersection_pos, 1);
298 int intersection_size = 0;
299 int num_indices_to_remove_isect = 0;
303 total_num_indices_to_remove
304 + (
size_t)max_intersection_size);
306 for (
int j = 0; j < max_intersection_size; ++j) {
308 int pos = intersection_pos[j];
318 intersection_pos[intersection_size] = pos;
319 indices_to_remove_[total_num_indices_to_remove
320 + (size_t)num_indices_to_remove_isect]
321 = intersection_idxvec[j];
322 intersection_size += predicate ^ 1;
323 num_indices_to_remove_isect += predicate;
327 total_num_indices_to_remove += (size_t)num_indices_to_remove_isect;
328 num_indices_to_remove_per_intersection[i] = num_indices_to_remove_isect;
330 if (intersection_size > 0) {
331 resSets_[new_num_intersections].transfer_pos = intersection_pos;
332 resSets_[new_num_intersections].num_transfer_pos = intersection_size;
333 resSets_[new_num_intersections].transfer_pos_ext_cache = NULL;
334 resSets_[new_num_intersections].num_transfer_pos_ext
337 resSets_[new_num_intersections].rank = intersections[i].rank;
338 new_num_intersections++;
339 intersection_pos = NULL;
342 free(intersection_pos);
344 *indices_to_remove =
xrealloc(indices_to_remove_,
345 (
size_t)total_num_indices_to_remove
346 *
sizeof (**indices_to_remove));
347 *resCount = new_num_intersections;
348 if (num_intersections != new_num_intersections)
350 (
size_t)new_num_intersections *
sizeof(**resSets));
353 unsigned long all_bits_set = ~0UL;
354 for (
size_t i = 0; i < coverage_size; ++i)
355 all_bits_set &= coverage[i];
358 return all_bits_set == ~0UL;
365 intersections[num_intersections],
369 Xt_int * indices_to_remove,
370 int * num_indices_to_remove_per_intersection)
374 =
xmalloc((
size_t)num_intersections *
sizeof(**resSets));
376 int new_num_intersections = 0;
379 Xt_int * new_intersection_idxvec = NULL;
380 size_t curr_new_intersection_idxvec_size = 0;
381 int *restrict intersection_pos = NULL;
383 for (
int i = 0; i < num_intersections; ++i) {
385 const Xt_int *restrict intersection_idxvec
387 int intersection_size
389 intersection_pos =
xrealloc(intersection_pos,
390 (
size_t)intersection_size
391 *
sizeof(*intersection_pos));
393 int num_indices_to_remove = num_indices_to_remove_per_intersection[i];
394 if (num_indices_to_remove > 0) {
397 new_intersection_idxvec, curr_new_intersection_idxvec_size,
398 intersection_size - num_indices_to_remove + 1);
399 int new_intersection_size = 0;
401 for (
int j = 0; j < intersection_size; ++j) {
405 Xt_int idx = intersection_idxvec[j];
408 for (
int k = 0; k < num_indices_to_remove; ++k)
409 discard |= (idx == indices_to_remove[offset + k]);
411 new_intersection_idxvec[new_intersection_size] = idx;
412 new_intersection_size += !discard;
415 intersection_idxvec = new_intersection_idxvec;
416 intersection_size = new_intersection_size;
417 offset = offset + num_indices_to_remove;
422 mypart_idxlist, intersection_idxvec, intersection_size,
423 intersection_pos, 0);
426 if (intersection_size > 0) {
427 resSets_[new_num_intersections].transfer_pos = intersection_pos;
428 resSets_[new_num_intersections].num_transfer_pos = intersection_size;
429 resSets_[new_num_intersections].transfer_pos_ext_cache = NULL;
430 resSets_[new_num_intersections].num_transfer_pos_ext
433 resSets_[new_num_intersections].rank = intersections[i].rank;
434 new_num_intersections++;
435 intersection_pos = NULL;
439 free(new_intersection_idxvec);
440 free(intersection_pos);
442 *resCount = new_num_intersections;
443 if (num_intersections != new_num_intersections)
445 (
size_t)new_num_intersections *
sizeof(**resSets));
451 src_com[num_src_intersections],
452 int num_dst_intersections,
454 dst_com[num_dst_intersections],
455 Xt_int ** src_indices_to_remove,
456 int *restrict num_src_indices_to_remove_per_intersection,
457 Xt_int * dst_indices_to_remove,
458 int *restrict num_dst_indices_to_remove_per_intersection,
462 MPI_Request * requests
463 =
xmalloc((
size_t)(num_src_intersections + 2 * num_dst_intersections) *
465 MPI_Request *restrict recv_requests = requests,
466 *restrict send_header_requests = requests + num_src_intersections,
467 *restrict send_data_requests = send_header_requests + num_dst_intersections;
470 for (
int i = 0; i < num_src_intersections; ++i)
472 num_src_indices_to_remove_per_intersection + i, 1, MPI_INT,
475 comm, recv_requests+i), comm);
480 unsigned num_nonempty_dst_intersections = 0;
481 for (
int i = 0; i < num_dst_intersections; ++i) {
483 num_dst_indices_to_remove_per_intersection + i, 1, MPI_INT,
486 comm, send_header_requests + i), comm);
488 if (num_dst_indices_to_remove_per_intersection[i] > 0) {
491 dst_indices_to_remove + offset,
492 num_dst_indices_to_remove_per_intersection[i],
Xt_int_dt,
495 comm, send_data_requests + num_nonempty_dst_intersections),
497 offset += num_dst_indices_to_remove_per_intersection[i];
498 ++num_nonempty_dst_intersections;
503 xt_mpi_call(MPI_Waitall(num_src_intersections + num_dst_intersections,
504 recv_requests, MPI_STATUSES_IGNORE), comm);
506 size_t total_num_src_indices_to_recv = 0;
508 for (
int i = 0; i < num_src_intersections; ++i)
509 total_num_src_indices_to_recv
510 += (
size_t)num_src_indices_to_remove_per_intersection[i];
512 unsigned num_nonempty_src_intersections = 0;
513 if (total_num_src_indices_to_recv > 0) {
515 *src_indices_to_remove =
xmalloc(total_num_src_indices_to_recv
516 *
sizeof(**src_indices_to_remove));
520 for (
int i = 0; i < num_src_intersections; ++i)
521 if (num_src_indices_to_remove_per_intersection[i] > 0) {
523 (*src_indices_to_remove) + offset,
524 num_src_indices_to_remove_per_intersection[i],
528 recv_requests + num_nonempty_src_intersections), comm);
531 + num_src_indices_to_remove_per_intersection[i];
532 ++num_nonempty_src_intersections;
536 *src_indices_to_remove = NULL;
540 memcpy(recv_requests + num_nonempty_src_intersections, send_data_requests,
541 num_nonempty_dst_intersections *
sizeof (recv_requests[0]));
544 xt_mpi_call(MPI_Waitall((
int)num_nonempty_src_intersections
545 + (
int)num_nonempty_dst_intersections,
546 requests, MPI_STATUSES_IGNORE), comm);
553 int num_src_intersections,
554 const struct Xt_com_list src_com[num_src_intersections],
555 int num_dst_intersections,
556 const struct Xt_com_list dst_com[num_dst_intersections],
561 int * num_src_indices_to_remove_per_intersection =
562 xmalloc((
size_t)num_src_intersections
563 *
sizeof(*num_src_indices_to_remove_per_intersection));
564 int * num_dst_indices_to_remove_per_intersection =
565 xmalloc((
size_t)num_dst_intersections
566 *
sizeof(*num_dst_indices_to_remove_per_intersection));
567 Xt_int * src_indices_to_remove = NULL, * dst_indices_to_remove = NULL;
570 num_dst_intersections, dst_com, dst_idxlist_local,
571 &(xmap->
n_in), &(xmap->
in_msg), &dst_indices_to_remove,
572 num_dst_indices_to_remove_per_intersection);
576 num_src_intersections, src_com, num_dst_intersections, dst_com,
577 &src_indices_to_remove, num_src_indices_to_remove_per_intersection,
578 dst_indices_to_remove, num_dst_indices_to_remove_per_intersection,
581 free(dst_indices_to_remove);
582 free(num_dst_indices_to_remove_per_intersection);
585 num_src_intersections, src_com, src_idxlist_local,
587 src_indices_to_remove, num_src_indices_to_remove_per_intersection);
589 free(src_indices_to_remove);
590 free(num_src_indices_to_remove_per_intersection);
591 return all_dst_covered;
597 src_com[num_src_intersections],
598 int num_dst_intersections,
600 dst_com[num_dst_intersections],
604 Xt_xmap_intersection xmap =
xmalloc(
sizeof (*xmap));
612 num_src_intersections, src_com,
613 num_dst_intersections, dst_com,
614 src_idxlist, dst_idxlist, comm)) {
618 int * found_index_mask =
xcalloc((
size_t)num_dst_indices,
619 sizeof(*found_index_mask));
620 int * index_positions =
xmalloc((
size_t)num_dst_indices
621 *
sizeof(*index_positions));
623 for (
size_t i = 0; i < (size_t)num_dst_intersections; ++i) {
625 num_dst_indices, index_positions, 0);
626 for (
size_t j = 0; j < (size_t)num_dst_indices; ++j)
627 found_index_mask[j] |= index_positions[j] != -1;
630 int first_missing_pos = 0;
631 while ((first_missing_pos < (num_dst_indices - 1)) &&
632 (found_index_mask[first_missing_pos])) ++first_missing_pos;
638 char error_message[1024];
639 sprintf(error_message,
"ERROR: destination intersections do not match " 640 "with destination index list (first missing index %lld " 641 "at position %d)", (
long long)missing_index, first_missing_pos);
642 Xt_abort(comm, error_message, __FILE__, __LINE__);
665 *nmsg_copy = (int)nmsg;
667 = *msg_copy =
xmalloc(
sizeof (*msg_copy_) * nmsg);
668 for (
size_t i = 0; i < nmsg; ++i) {
670 = (size_t)(msg_copy_[i].num_transfer_pos = msg[i].num_transfer_pos);
671 msg_copy_[i].num_transfer_pos_ext = msg[i].num_transfer_pos_ext;
672 msg_copy_[i].rank = msg[i].rank;
673 msg_copy_[i].transfer_pos_ext_cache = NULL;
674 size_t size_transfer_pos
675 = num_transfer_pos *
sizeof (*(msg[i].transfer_pos));
676 msg_copy_[i].transfer_pos =
xmalloc(size_transfer_pos);
677 memcpy(msg_copy_[i].
transfer_pos, msg[i].transfer_pos, size_transfer_pos);
684 Xt_xmap_intersection xmap_intersection =
xmi(xmap),
685 xmap_intersection_new =
xmalloc(
sizeof (*xmap_intersection_new));
686 xmap_intersection_new->vtable = xmap_intersection->
vtable;
687 size_t n_in = (size_t)(xmap_intersection_new->n_in = xmap_intersection->
n_in),
688 n_out = (size_t)(xmap_intersection_new->n_out = xmap_intersection->
n_out);
689 xmap_intersection_new->max_src_pos = xmap_intersection->
max_src_pos;
690 xmap_intersection_new->max_dst_pos = xmap_intersection->
max_dst_pos;
692 &xmap_intersection_new->n_in,
693 &xmap_intersection_new->in_msg);
695 &xmap_intersection_new->n_out,
696 &xmap_intersection_new->out_msg);
697 xmap_intersection_new->comm
699 &xmap_intersection_new->tag_offset);
700 return (
Xt_xmap)xmap_intersection_new;
706 for (
int i = 0; i < nmsg; ++i)
716 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
719 xmap_intersection->
in_msg);
724 free(xmap_intersection);
729 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
731 if (xmap_intersection->
n_in == 0)
734 Xt_xmap_iter_intersection iter =
xmalloc(
sizeof (*iter));
745 Xt_xmap_intersection xmap_intersection =
xmi(xmap);
747 if (xmap_intersection->
n_out == 0)
750 Xt_xmap_iter_intersection iter =
xmalloc(
sizeof (*iter));
761 Xt_xmap_iter_intersection iter_intersection =
xmii(iter);
763 if (iter_intersection == NULL || iter_intersection->
msgs_left == 0)
766 iter_intersection->
msg++;
774 assert(iter != NULL);
781 assert(iter != NULL);
788 assert(iter != NULL);
792 num_transfer_pos_ext = 0;
796 * sizeof (transfer_pos_ext[0]));
800 transfer_pos_ext[num_transfer_pos_ext]
803 ++num_transfer_pos_ext;
814 assert(iter != NULL);
821 assert(iter != NULL);
static int generate_dir_transfer_pos_dst(int num_intersections, const struct Xt_com_list intersections[num_intersections], Xt_idxlist mypart_idxlist, int *resCount, struct exchange_data **resSets, Xt_int **indices_to_remove, int *num_indices_to_remove_per_intersection)
static int xmap_intersection_get_max_src_pos(Xt_xmap xmap)
int xt_idxlist_get_num_indices(Xt_idxlist idxlist)
static void xmap_intersection_get_destination_ranks(Xt_xmap xmap, int *ranks)
static const struct Xt_xmap_iter_vtable xmap_iterator_intersection_vtable
struct exchange_data * in_msg
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)
int(* next)(Xt_xmap_iter iter)
static void xmap_intersection_get_source_ranks(Xt_xmap xmap, int *ranks)
add versions of standard API functions not returning on error
static int xmap_intersection_iterator_next(Xt_xmap_iter iter)
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_copy(Xt_xmap xmap)
contains declaration for the exchange map data structure
static Xt_xmap_iter xmap_intersection_get_in_iterator(Xt_xmap xmap)
static void xmap_intersection_iterator_delete(Xt_xmap_iter iter)
static void 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], Xt_int **src_indices_to_remove, int *restrict num_src_indices_to_remove_per_intersection, Xt_int *dst_indices_to_remove, int *restrict num_dst_indices_to_remove_per_intersection, int tag_offset, MPI_Comm comm)
struct exchange_data * msg
static struct pos_run get_pos_run_len(size_t num_pos, const int *restrict pos)
int xt_idxlist_get_positions_of_indices(Xt_idxlist idxlist, const Xt_int *indices, int num_indices, int *positions, int single_match_only)
#define xrealloc(ptr, size)
static size_t count_transfer_pos_ext(size_t intersection_size, const int *restrict intersection_pos)
exchange map declarations
int xt_idxlist_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
MPI_Comm(* get_communicator)(Xt_xmap)
static Xt_xmap_intersection xmi(void *xmap)
static int const * xmap_intersection_iterator_get_transfer_pos(Xt_xmap_iter iter)
#define xcalloc(nmemb, size)
static int isign_mask(int x)
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
static void xmap_intersection_msg_copy(size_t nmsg, struct exchange_data *restrict msg, int *nmsg_copy, struct exchange_data **msg_copy)
static void generate_dir_transfer_pos_src(int num_intersections, const struct Xt_com_list intersections[num_intersections], Xt_idxlist mypart_idxlist, int *resCount, struct exchange_data **resSets, Xt_int *indices_to_remove, int *num_indices_to_remove_per_intersection)
static const struct Xt_pos_ext * xmap_intersection_iterator_get_transfer_pos_ext(Xt_xmap_iter iter)
static void xmap_intersection_msg_delete(int nmsg, struct exchange_data *msg)
static int xmap_intersection_iterator_get_num_transfer_pos_ext(Xt_xmap_iter iter)
static int xmap_intersection_iterator_get_num_transfer_pos(Xt_xmap_iter iter)
struct Xt_xmap_intersection_ * Xt_xmap_intersection
static int xmap_intersection_get_num_destinations(Xt_xmap xmap)
MPI_Comm xt_mpi_comm_smart_dup(MPI_Comm comm, int *tag_offset)
struct Xt_pos_ext * transfer_pos_ext_cache
static int xmap_intersection_iterator_get_rank(Xt_xmap_iter iter)
void xt_mpi_comm_smart_dedup(MPI_Comm *comm, int tag_offset)
struct Xt_xmap_iter_intersection_ * Xt_xmap_iter_intersection
static int xmap_intersection_get_max_dst_pos(Xt_xmap xmap)
struct exchange_data * out_msg
#define xt_mpi_call(call, comm)
static Xt_xmap_iter_intersection xmii(void *iter)
const struct Xt_xmap_vtable * vtable
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
const struct Xt_xmap_iter_vtable * vtable
static const struct Xt_xmap_vtable xmap_intersection_vtable
static void xmap_intersection_delete(Xt_xmap xmap)
static Xt_xmap_iter xmap_intersection_get_out_iterator(Xt_xmap xmap)
static MPI_Comm xmap_intersection_get_communicator(Xt_xmap xmap)
static int xmap_intersection_get_num_sources(Xt_xmap xmap)