14#define WEIGHT_TOL (1e-9)
27#ifdef YAC_NETCDF_ENABLED
31#define YAC_YAXT_EXCHANGER_STR "YAC_YAXT_EXCHANGER"
72 size_t * field_indices;
169 weights->stencils = NULL;
170 weights->stencils_array_size = 0;
171 weights->stencils_size = 0;
182 xmalloc((
size_t)count *
sizeof(*point_infos));
183 memcpy(point_infos, point.data.data.multi,
184 (
size_t)count *
sizeof(*point_infos));
185 point.data.data.multi = point_infos;
191 char const * routine,
struct remote_point point,
int * rank_is_target) {
195 count > 0, routine,
"owner count has to be > 0 (got %d)", count)
200 for (
int i = 0; i < count; ++i)
201 is_valid |= rank_is_target[point_infos[i].
rank];
207 char const * routine,
struct remote_point point, int * rank_is_target) {
211 count > 0, routine,
"owner count has to be > 0 (got %d)", count)
213 (count == 1)?&(point.data.data.single):point.
data.
data.
multi;
216 for (
int i = 0; i < count; ++i) {
221 {.
global_id = point.global_id, .data.count = valid_count};
223 if (valid_count > 1) {
224 remote_point_infos_copy =
225 xmalloc((
size_t)valid_count *
sizeof(*remote_point_infos_copy));
231 for (
int i = 0, j = 0; i < count; ++i) {
237 return remote_point_copy;
246 for (
size_t i = 0; i < count; ++i) {
247 int curr_count = points_from[i].
data.
count;
248 points_to[i] = points_from[i];
249 if (curr_count > 1) {
252 point_info_buffer, points_from[i].
data.data.multi,
253 (
size_t)curr_count *
sizeof(*point_info_buffer));
254 point_info_buffer += curr_count;
257 *point_info_buffer_ = point_info_buffer;
263 size_t point_info_buffer_size = 0;
264 for (
size_t i = 0; i <
count; ++i)
265 if (points[i].
data.count > 1)
266 point_info_buffer_size += (size_t)(points[i].
data.count);
270 sizeof(*points_copy));
276 points_copy->
data, points, count, &point_info_buffer);
284 size_t point_info_buffer_size = 0;
285 size_t total_count = 0;
287 total_count += counts[i];
288 for (
size_t j = 0; j < counts[i]; ++j) {
289 if (points[i][j].
data.count > 1)
290 point_info_buffer_size += (size_t)(points[i][j].
data.count);
296 sizeof(*points_copy));
297 points_copy->
data =
xmalloc(total_count *
sizeof(*(points_copy->
data)));
298 points_copy->
count = total_count;
301 for (
size_t i = 0, k = 0; i <
num_fields; ++i) {
302 for (
size_t j = 0; j < counts[i]; ++j, ++k) {
303 int curr_count = points[i][j].data.count;
304 points_copy->
data[k] = points[i][j];
305 if (curr_count > 1) {
308 point_info_buffer, points[i][j].
data.data.multi,
309 (
size_t)curr_count *
sizeof(*point_info_buffer));
310 point_info_buffer += curr_count;
322 size_t stencils_array_size =
weights->stencils_array_size;
323 size_t stencils_size =
weights->stencils_size;
327 for (
size_t i = 0; i < tgts->
count; ++i, ++stencils_size) {
335 weights->stencils_array_size = stencils_array_size;
336 weights->stencils_size = stencils_size;
343 if (tgts->
count == 0)
return;
347 for (
size_t tgt_idx = 0, old_weight_offset = 0, new_weight_offset = 0;
348 tgt_idx < tgts->
count; tgt_idx++) {
350 size_t curr_count = num_src_per_tgt[tgt_idx];
353 double max_weight = 0.0;
354 double min_weight = DBL_MAX;
355 for (
size_t weight_idx = 0; weight_idx < curr_count; weight_idx++) {
356 double abs_weight = fabs(w[old_weight_offset + weight_idx]);
357 if (abs_weight > max_weight) max_weight = abs_weight;
358 if (abs_weight < min_weight) min_weight = abs_weight;
362 double const weight_threshold = max_weight *
WEIGHT_TOL;
365 if (min_weight < weight_threshold) {
368 for (
size_t weight_idx = 0; weight_idx < curr_count;
369 weight_idx++, old_weight_offset++) {
372 if (fabs(w[old_weight_offset]) < weight_threshold) {
374 num_src_per_tgt[tgt_idx]--;
376 if (new_weight_offset != old_weight_offset) {
377 srcs[new_weight_offset] =
srcs[old_weight_offset];
378 w[new_weight_offset] = w[old_weight_offset];
385 (curr_count == 0) || (num_src_per_tgt[tgt_idx] > 0),
386 "internal error; no weights left after removing near-zero weights "
387 "for target with id %" YAC_INT_FMT,
392 if (new_weight_offset != old_weight_offset) {
394 srcs + new_weight_offset,
srcs + old_weight_offset,
395 curr_count *
sizeof(*
srcs));
397 w + new_weight_offset, w + old_weight_offset,
398 curr_count *
sizeof(*w));
400 new_weight_offset += curr_count;
401 old_weight_offset += curr_count;
407 int flag_weight_one = 1;
408 int flag_count_one = 1;
409 for (
size_t i = 0, j = 0;
410 (i < tgts->
count) && (flag_weight_one || flag_count_one); ++i) {
412 size_t curr_count = num_src_per_tgt[i];
413 flag_count_one &= curr_count == 1;
415 for (
size_t k = 0; (k < curr_count) && flag_weight_one; ++k, ++j)
416 flag_weight_one &= fabs(w[j] - 1.0) <
WEIGHT_TOL;
420 if (flag_weight_one) {
431 size_t stencils_array_size =
weights->stencils_array_size;
432 size_t stencils_size =
weights->stencils_size;
436 for (
size_t i = 0; i < tgts->
count; ++i, ++stencils_size) {
438 size_t curr_num_src = num_src_per_tgt[i];
441 if (curr_num_src == 0) {
446 double * curr_weights =
447 xmalloc(curr_num_src *
sizeof(*curr_weights));
454 memcpy(curr_weights, w, curr_num_src *
sizeof(*curr_weights));
456 srcs += curr_num_src;
461 weights->stencils_array_size = stencils_array_size;
462 weights->stencils_size = stencils_size;
470 if (tgts->
count == 0)
return;
474 int flag_count_one = 1;
475 for (
size_t i = 0; i < tgts->
count; ++i) {
476 if (num_src_per_tgt[i] != 1) {
482 if (flag_count_one) {
489 size_t stencils_array_size =
weights->stencils_array_size;
490 size_t stencils_size =
weights->stencils_size;
494 for (
size_t i = 0; i < tgts->
count; ++i, ++stencils_size) {
496 size_t curr_num_src = num_src_per_tgt[i];
498 stencils[stencils_size].
type =
SUM;
504 srcs += curr_num_src;
508 weights->stencils_array_size = stencils_array_size;
509 weights->stencils_size = stencils_size;
517 if (tgts->
count == 0)
return;
520 size_t stencils_array_size =
weights->stencils_array_size;
521 size_t stencils_size =
weights->stencils_size;
525 for (
size_t i = 0; i < tgts->
count; ++i, ++stencils_size) {
533 weights->stencils_array_size = stencils_array_size;
534 weights->stencils_size = stencils_size;
539 size_t * src_field_indices,
struct remote_point ** srcs_per_field,
540 size_t num_src_fields) {
542 if (tgts->
count == 0)
return;
544 if (num_src_fields == 1) {
550 size_t stencils_array_size =
weights->stencils_array_size;
551 size_t stencils_size =
weights->stencils_size;
554 stencils, stencils_array_size, stencils_size + tgts->
count);
555 stencils += stencils_size;
557 size_t srcs_offsets[num_src_fields];
558 memset(srcs_offsets, 0, num_src_fields *
sizeof(srcs_offsets[0]));
560 for (
size_t i = 0; i < tgts->
count; ++i) {
562 size_t src_field_idx = src_field_indices[i];
567 srcs_per_field[src_field_idx][srcs_offsets[src_field_idx]++]);
572 weights->stencils_array_size = stencils_array_size;
578 size_t * num_src_per_field_per_tgt,
struct remote_point ** srcs_per_field,
579 size_t num_src_fields) {
581 if (tgts->
count == 0)
return;
583 if (num_src_fields == 1) {
585 weights, tgts, num_src_per_field_per_tgt, srcs_per_field[0]);
591 int flag_count_one = 1;
592 for (
size_t i = 0, k = 0; i < tgts->
count; ++i) {
594 for (
size_t j = 0; j < num_src_fields; ++j, ++k)
595 count += num_src_per_field_per_tgt[k];
602 if (flag_count_one) {
604 size_t * src_field_indices =
607 for (
size_t i = 0, k = 0; i < tgts->
count; ++i)
608 for (
size_t j = 0; j < num_src_fields; ++j, ++k)
609 if (num_src_per_field_per_tgt[k])
610 src_field_indices[i] = j;
613 weights, tgts, src_field_indices, srcs_per_field, num_src_fields);
615 free(src_field_indices);
618 struct remote_point * curr_srcs_per_field[num_src_fields];
619 memcpy(curr_srcs_per_field, srcs_per_field,
620 num_src_fields *
sizeof(*srcs_per_field));
623 size_t stencils_array_size =
weights->stencils_array_size;
624 size_t stencils_size =
weights->stencils_size;
627 stencils, stencils_array_size, stencils_size + tgts->
count);
629 for (
size_t i = 0; i < tgts->
count; ++i, ++stencils_size) {
631 size_t * curr_num_src_per_src_field =
632 num_src_per_field_per_tgt + i * num_src_fields;
633 size_t curr_num_src = 0;
634 for (
size_t j = 0; j < num_src_fields; ++j)
635 curr_num_src += curr_num_src_per_src_field[j];
642 sizeof(*(stencils[stencils_size].
data.sum_mf.field_indices)));
643 for (
size_t j = 0, l = 0; j < num_src_fields; ++j) {
644 size_t curr_num_src = curr_num_src_per_src_field[j];
645 for (
size_t k = 0; k < curr_num_src; ++k, ++l) {
651 curr_srcs_per_field, curr_num_src_per_src_field, num_src_fields);
653 for (
size_t j = 0; j < num_src_fields; ++j)
654 curr_srcs_per_field[j] += curr_num_src_per_src_field[j];
658 weights->stencils_array_size = stencils_array_size;
659 weights->stencils_size = stencils_size;
665 size_t * num_src_per_field_per_tgt,
struct remote_point ** srcs_per_field,
666 double * w,
size_t num_src_fields) {
668 if (tgts->
count == 0)
return;
670 if (num_src_fields == 1) {
672 weights, tgts, num_src_per_field_per_tgt, srcs_per_field[0], w);
678 int flag_weight_one = 1;
679 for (
size_t i = 0, j = 0;
680 (i < tgts->
count) && flag_weight_one; ++i) {
682 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
686 num_src_per_field_per_tgt[i * num_src_fields + src_field_idx];
688 for (
size_t k = 0; (k < curr_count) && flag_weight_one; ++k, ++j)
689 flag_weight_one &= fabs(w[j] - 1.0) <
WEIGHT_TOL;
694 if (flag_weight_one) {
697 weights, tgts, num_src_per_field_per_tgt, srcs_per_field, num_src_fields);
701 struct remote_point * curr_srcs_per_field[num_src_fields];
702 memcpy(curr_srcs_per_field, srcs_per_field,
703 num_src_fields *
sizeof(*srcs_per_field));
706 size_t stencils_array_size =
weights->stencils_array_size;
707 size_t stencils_size =
weights->stencils_size;
710 stencils, stencils_array_size, stencils_size + tgts->
count);
712 for (
size_t i = 0; i < tgts->
count; ++i, ++stencils_size) {
714 size_t * curr_num_src_per_src_field =
715 num_src_per_field_per_tgt + i * num_src_fields;
716 size_t curr_num_weights = 0;
717 for (
size_t j = 0; j < num_src_fields; ++j)
718 curr_num_weights += curr_num_src_per_src_field[j];
719 double * curr_weights =
720 xmalloc(curr_num_weights *
sizeof(*curr_weights));
727 for (
size_t j = 0, l = 0; j < num_src_fields; ++j) {
728 size_t curr_num_src = curr_num_src_per_src_field[j];
729 for (
size_t k = 0; k < curr_num_src; ++k, ++l)
field_indices[l] = j;
734 memcpy(curr_weights, w, curr_num_weights *
sizeof(*curr_weights));
736 for (
size_t j = 0; j < num_src_fields; ++j)
737 curr_srcs_per_field[j] += curr_num_src_per_src_field[j];
738 w += curr_num_weights;
742 weights->stencils_array_size = stencils_array_size;
743 weights->stencils_size = stencils_size;
765 MPI_Datatype fixed_stencil_dt;
766 enum {NUM_MEMBERS = 2};
767 int array_of_blocklengths[NUM_MEMBERS] = {1, 1};
768 MPI_Aint array_of_displacements[NUM_MEMBERS];
771 yac_mpi_call(MPI_Get_address(&dummy, &base_addr), comm);
774 &(dummy.
value), &array_of_displacements[0]), comm);
775 array_of_displacements[0] -= base_addr;
778 &(dummy.
orig_pos), &array_of_displacements[1]), comm);
779 array_of_displacements[1] -= base_addr;
781 const MPI_Datatype array_of_types[NUM_MEMBERS] =
784 MPI_Type_create_struct(
785 NUM_MEMBERS, array_of_blocklengths, array_of_displacements,
786 array_of_types, &fixed_stencil_dt), comm);
791 void * interp,
double fixed_value,
size_t count,
size_t * tgt_pos) {
798 void * interp,
double fixed_value,
size_t count,
size_t * tgt_pos) {
819 size_t total_num_fixed_tgt = 0;
825 (total_num_fixed_tgt + count) *
829 tgt_pos, count *
sizeof(*tgt_pos));
835 MPI_Comm comm,
size_t count,
838 int * rank_is_target) {
848 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
850 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
853 for (
size_t i = 0; i < count; ++i) {
857 (&(fixed_stencils[i].tgt.data.data.single)):
859 for (
int j = 0; j < curr_count; ++j)
860 sendcounts[curr_point_infos[j].
rank]++;
865 for (
int i = 0; i < comm_size; ++i)
866 if (!rank_is_target[i]) sendcounts[i] = 0;
869 1, sendcounts, recvcounts, sdispls, rdispls, comm);
871 size_t send_buffer_size =
872 sdispls[comm_size] + sendcounts[comm_size - 1];
873 size_t recv_buffer_size =
874 rdispls[comm_size - 1] + recvcounts[comm_size - 1];
877 xmalloc((send_buffer_size + recv_buffer_size) *
sizeof(*
buffer));
882 for (
size_t i = 0; i < count; ++i) {
886 (&(fixed_stencils[i].tgt.data.data.single)):
889 for (
int j = 0; j < curr_count; ++j) {
890 int tgt_rank = curr_point_infos[j].
rank;
891 if (rank_is_target[tgt_rank]) {
892 size_t pos = sdispls[tgt_rank + 1]++;
906 "yac_interp_weights_redist_fixed", __LINE__);
911 if (recv_buffer_size == 0) {
924 size_t * tgt_pos =
xmalloc(recv_buffer_size *
sizeof(*tgt_pos));
925 for (
size_t i = 0; i < recv_buffer_size; ++i)
928 size_t offset = 0, i = 0;
929 while (offset < recv_buffer_size) {
932 while ((i < recv_buffer_size) &&
937 size_t curr_count = i - offset;
939 interp,
fixed_value, curr_count, tgt_pos + offset);
952 src.count > 0, routine,
"owner count has to be > 0 (got %d)",
src.count)
956 if (
src.count == 1) {
958 src_point_info =
src.data.single;
962 int min_rank = INT_MAX;
963 size_t min_rank_idx = SIZE_MAX;
964 for (
int i = 0; i <
src.count; ++i) {
965 if ((
src.data.multi[i].rank < min_rank) &&
966 (rank_is_source[
src.data.multi[i].rank])) {
967 min_rank =
src.data.multi[i].rank;
973 src.data.multi[(min_rank_idx != SIZE_MAX)?min_rank_idx:0];
977 rank_is_source[src_point_info.
rank], routine,
978 "missing source field data from rank %d", src_point_info.
rank);
980 return src_point_info;
984 struct Xt_redist_msg * msgs,
size_t count, MPI_Comm comm) {
985 for (
size_t i = 0; i < count; ++i) {
986 MPI_Datatype * dt = &(msgs[i].datatype);
987 if (*dt != MPI_DATATYPE_NULL)
yac_mpi_call(MPI_Type_free(dt), comm);
1006 size_t * src_orig_poses,
size_t * sendcounts,
1008 size_t * recvcounts, MPI_Comm comm, Xt_config redist_config) {
1013 size_t nsend = 0, nrecv = 0;
1014 size_t max_buffer_size = 0;
1015 for (
int i = 0; i < comm_size; ++i) {
1016 nsend += sendcounts[i] > 0;
1017 nrecv += recvcounts[i] > 0;
1018 if (max_buffer_size < sendcounts[i]) max_buffer_size = sendcounts[i];
1019 if (max_buffer_size < recvcounts[i]) max_buffer_size = recvcounts[i];
1022 size_t total_num_msg = nsend + nrecv;
1024 struct Xt_redist_msg * msgs_buffer =
1025 xmalloc(total_num_msg *
sizeof(*msgs_buffer));
1026 struct Xt_redist_msg * send_msgs = msgs_buffer;
1027 struct Xt_redist_msg * recv_msgs = msgs_buffer + nsend;
1029 int * pos_buffer =
xmalloc((
size_t)max_buffer_size *
sizeof(*pos_buffer));
1034 for (
int i = 0; i < comm_size; ++i) {
1035 if (recvcounts[i] > 0) {
1036 for (
size_t j = 0; j < recvcounts[i]; ++j)
1037 pos_buffer[j] = (
int)tgt_stencils[j].
orig_pos;
1038 tgt_stencils += recvcounts[i];
1039 recv_msgs[nrecv].rank = i;
1040 recv_msgs[nrecv].datatype =
1041 xt_mpi_generate_datatype(pos_buffer, recvcounts[i], MPI_DOUBLE, comm);
1044 if (sendcounts[i] > 0) {
1045 for (
size_t j = 0; j < sendcounts[i]; ++j)
1046 pos_buffer[j] = (
int)src_orig_poses[j];
1047 src_orig_poses += sendcounts[i];
1048 send_msgs[nsend].rank = i;
1049 send_msgs[nsend].datatype =
1050 xt_mpi_generate_datatype(pos_buffer, sendcounts[i], MPI_DOUBLE, comm);
1062 if (total_num_msg > 0) {
1069 xmalloc(2 * total_num_msg *
sizeof(*rank_buffer));
1070 int * orig_ranks = rank_buffer;
1071 int * split_ranks = rank_buffer + total_num_msg;
1073 for (
size_t i = 0; i < total_num_msg; ++i)
1074 orig_ranks[i] = msgs_buffer[i].rank;
1076 MPI_Group orig_group, split_group;
1083 MPI_Group_translate_ranks(orig_group, total_num_msg, orig_ranks,
1086 for (
size_t i = 0; i < total_num_msg; ++i)
1087 msgs_buffer[i].rank = split_ranks[i];
1096 xt_redist_single_array_base_custom_new(
1097 nsend, nrecv, send_msgs, recv_msgs,
split_comm, redist_config);
1126 size_t * src_orig_poses,
size_t * sendcounts,
1128 size_t * recvcounts,
size_t num_src_fields, MPI_Comm comm,
1129 Xt_config redist_config) {
1134 size_t nsends[num_src_fields], nrecvs[num_src_fields];
1135 size_t max_buffer_size = 0;
1136 memset(nsends, 0, num_src_fields *
sizeof(nsends[0]));
1137 memset(nrecvs, 0, num_src_fields *
sizeof(nrecvs[0]));
1138 for (
int i = 0; i < comm_size; ++i) {
1139 for (
size_t j = 0; j < num_src_fields; ++j) {
1140 size_t idx = (size_t)i * num_src_fields + j;
1141 if (sendcounts[idx] > 0) nsends[j]++;
1142 if (recvcounts[idx] > 0) nrecvs[j]++;
1143 if (max_buffer_size < sendcounts[idx]) max_buffer_size = sendcounts[idx];
1144 if (max_buffer_size < recvcounts[idx]) max_buffer_size = recvcounts[idx];
1148 size_t nsend = 0, nrecv = 0;
1149 size_t send_offsets[num_src_fields];
1150 size_t recv_offsets[num_src_fields];
1151 for (
size_t i = 0; i < num_src_fields; ++i) {
1152 send_offsets[i] = nsend;
1153 recv_offsets[i] = nrecv;
1158 size_t total_num_msg = nsend + nrecv;
1160 struct Xt_redist_msg * msgs_buffer =
1161 xmalloc(total_num_msg *
sizeof(*msgs_buffer));
1162 struct Xt_redist_msg * send_msgs = msgs_buffer;
1163 struct Xt_redist_msg * recv_msgs = msgs_buffer + nsend;
1165 int * pos_buffer =
xmalloc(max_buffer_size *
sizeof(*pos_buffer));
1168 for (
int i = 0; i < comm_size; ++i) {
1169 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
1171 size_t idx = (size_t)i * num_src_fields + src_field_idx;
1172 if (recvcounts[idx] > 0) {
1173 for (
size_t j = 0; j < recvcounts[idx]; ++j)
1174 pos_buffer[j] = (
int)tgt_stencils[j].
orig_pos;
1175 tgt_stencils += recvcounts[idx];
1176 recv_msgs[recv_offsets[src_field_idx]].rank = i;
1177 recv_msgs[recv_offsets[src_field_idx]].datatype =
1178 xt_mpi_generate_datatype(
1179 pos_buffer, recvcounts[idx], MPI_DOUBLE, comm);
1180 recv_offsets[src_field_idx]++;
1182 if (sendcounts[idx] > 0) {
1183 for (
size_t j = 0; j < sendcounts[idx]; ++j)
1184 pos_buffer[j] = (
int)src_orig_poses[j];
1185 src_orig_poses += sendcounts[idx];
1186 send_msgs[send_offsets[src_field_idx]].rank = i;
1187 send_msgs[send_offsets[src_field_idx]].datatype =
1188 xt_mpi_generate_datatype(
1189 pos_buffer, sendcounts[idx], MPI_DOUBLE, comm);
1190 send_offsets[src_field_idx]++;
1202 if (total_num_msg > 0) {
1209 xmalloc(2 * total_num_msg *
sizeof(*rank_buffer));
1210 int * orig_ranks = rank_buffer;
1211 int * split_ranks = rank_buffer + total_num_msg;
1213 for (
size_t i = 0; i < total_num_msg; ++i)
1214 orig_ranks[i] = msgs_buffer[i].rank;
1216 MPI_Group orig_group, split_group;
1223 MPI_Group_translate_ranks(orig_group, total_num_msg, orig_ranks,
1226 for (
size_t i = 0; i < total_num_msg; ++i)
1227 msgs_buffer[i].rank = split_ranks[i];
1235 redists =
xmalloc(num_src_fields *
sizeof(*redists));
1236 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
1238 redists[src_field_idx] =
1239 xt_redist_single_array_base_custom_new(
1240 nsends[src_field_idx], nrecvs[src_field_idx],
1241 send_msgs, recv_msgs,
split_comm, redist_config);
1242 send_msgs += nsends[src_field_idx];
1243 recv_msgs += nrecvs[src_field_idx];
1260 MPI_Datatype direct_stencil_dt;
1261 enum {NUM_MEMBERS = 2};
1262 int array_of_blocklengths[NUM_MEMBERS] = {1, 1};
1263 MPI_Aint array_of_displacements[NUM_MEMBERS];
1266 yac_mpi_call(MPI_Get_address(&dummy, &base_addr), comm);
1269 &(dummy.
src), &array_of_displacements[0]), comm);
1270 array_of_displacements[0] -= base_addr;
1273 &(dummy.
orig_pos), &array_of_displacements[1]), comm);
1274 array_of_displacements[1] -= base_addr;
1276 MPI_Datatype array_of_types[NUM_MEMBERS] =
1279 MPI_Type_create_struct(
1280 NUM_MEMBERS, array_of_blocklengths, array_of_displacements,
1281 array_of_types, &direct_stencil_dt), comm);
1282 yac_mpi_call(MPI_Type_free(&(array_of_types[0])), comm);
1291 if (ret)
return ret;
1300 void * interp,
size_t * src_orig_poses,
size_t * sendcounts,
1302 size_t * recvcounts, MPI_Comm comm, Xt_config redist_config) {
1307 src_orig_poses, sendcounts, tgt_stencils, recvcounts,
1308 comm, redist_config);
1312 if (redist != NULL) xt_redist_delete(redist);
1316 MPI_Comm comm,
size_t count,
1321 size_t *, MPI_Comm, Xt_config), Xt_config redist_config,
1322 int * rank_is_source,
int * rank_is_target) {
1324 char const * routine =
"yac_interp_weights_redist_direct";
1334 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
1336 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1339 for (
size_t i = 0; i < count; ++i) {
1343 (&(direct_stencils[i].tgt.data.data.single)):
1345 for (
int j = 0; j < curr_count; ++j)
1346 sendcounts[curr_point_info[j].
rank]++;
1351 for (
int i = 0; i < comm_size; ++i)
1352 if (!rank_is_target[i]) sendcounts[i] = 0;
1355 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1357 size_t send_buffer_size =
1358 sdispls[comm_size] + sendcounts[comm_size - 1];
1359 size_t recv_buffer_size =
1360 rdispls[comm_size - 1] + recvcounts[comm_size - 1];
1361 size_t tgt_count = recv_buffer_size;
1364 xmalloc((send_buffer_size + recv_buffer_size) *
sizeof(*stencil_buffer));
1366 stencil_buffer + recv_buffer_size;
1370 for (
size_t i = 0; i < count; ++i) {
1374 (&(direct_stencils[i].tgt.data.data.single)):
1378 routine, direct_stencils[i].
data.direct.src.data, rank_is_source);
1379 for (
int j = 0; j < curr_count; ++j) {
1380 int tgt_rank = curr_point_infos[j].
rank;
1381 if (rank_is_target[tgt_rank]) {
1382 size_t pos = sdispls[tgt_rank + 1]++;
1383 send_stencil_buffer[pos].
src =
src;
1394 send_stencil_buffer, sendcounts, sdispls,
1395 recv_stencil_buffer, recvcounts, rdispls,
1396 sizeof(*stencil_buffer), stencil_direct_dt, comm,
1402 qsort(recv_stencil_buffer, tgt_count,
sizeof(*recv_stencil_buffer),
1409 memset(sendcounts, 0, (
size_t)comm_size *
sizeof(*sendcounts));
1411 for (
size_t i = 0; i < tgt_count; ++i)
1412 sendcounts[recv_stencil_buffer[i].
src.rank]++;
1415 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1417 send_buffer_size = sdispls[comm_size] + sendcounts[comm_size - 1];
1418 recv_buffer_size = rdispls[comm_size - 1] + recvcounts[comm_size - 1];
1420 size_t * orig_pos_buffer =
1421 xmalloc((send_buffer_size + recv_buffer_size) *
sizeof(*orig_pos_buffer));
1422 size_t * send_orig_pos_buffer = orig_pos_buffer + recv_buffer_size;
1423 size_t * recv_orig_pos_buffer = orig_pos_buffer;
1425 for (
size_t i = 0; i < tgt_count; ++i)
1426 send_orig_pos_buffer[sdispls[recv_stencil_buffer[i].
src.rank + 1]++] =
1430 send_orig_pos_buffer, sendcounts, sdispls,
1431 recv_orig_pos_buffer, recvcounts, rdispls,
1440 interp, recv_orig_pos_buffer, recvcounts, recv_stencil_buffer, sendcounts,
1441 comm, redist_config);
1444 free(orig_pos_buffer);
1445 free(stencil_buffer);
1451 MPI_Datatype direct_stencil_mf_dt;
1452 enum {NUM_MEMBERS = 3};
1453 int array_of_blocklengths[NUM_MEMBERS] = {1, 1, 1};
1454 MPI_Aint array_of_displacements[NUM_MEMBERS];
1457 yac_mpi_call(MPI_Get_address(&dummy, &base_addr), comm);
1460 &(dummy.
src), &array_of_displacements[0]), comm);
1461 array_of_displacements[0] -= base_addr;
1465 array_of_displacements[1] -= base_addr;
1468 &(dummy.
orig_pos), &array_of_displacements[2]), comm);
1469 array_of_displacements[2] -= base_addr;
1471 MPI_Datatype array_of_types[NUM_MEMBERS] =
1475 MPI_Type_create_struct(
1476 NUM_MEMBERS, array_of_blocklengths, array_of_displacements,
1477 array_of_types, &direct_stencil_mf_dt), comm);
1478 yac_mpi_call(MPI_Type_free(&(array_of_types[0])), comm);
1487 if (ret)
return ret;
1494 if (ret)
return ret;
1503 void * interp,
size_t num_src_fields,
size_t * src_orig_poses,
1505 size_t * recvcounts, MPI_Comm comm, Xt_config redist_config) {
1510 src_orig_poses, sendcounts, tgt_stencils, recvcounts,
1511 (
size_t)num_src_fields, comm, redist_config);
1516 if (redists != NULL) {
1517 for (
size_t i = 0; i < (size_t)num_src_fields; ++i)
1518 xt_redist_delete(redists[i]);
1524 struct yac_src_field_exchange_data * src_field_exchange_data) {
1526 src_field_exchange_data->send.msg = NULL;
1527 src_field_exchange_data->send.num_msg = 0;
1528 src_field_exchange_data->recv.msg = NULL;
1529 src_field_exchange_data->recv.num_msg = 0;
1549 i < num_src_fields; ++i) {
1578 size_t num_src_fields,
size_t tgt_count,
size_t * tgt_idx,
1579 size_t * num_src_per_tgt,
double * weights,
size_t *
src_field_idx,
1580 size_t * src_idx,
size_t * src_field_buffer_size) {
1583 size_t num_weights = 0;
1584 if (num_src_per_tgt) {
1585 for (
size_t i = 0; i < tgt_count; ++i) num_weights += num_src_per_tgt[i];
1587 num_weights = tgt_count;
1591 size_t weights_offset = 0;
1603 tgt_idx, tgt_count *
sizeof(*tgt_idx));
1611 if (num_src_per_tgt) {
1614 num_src_per_tgt, tgt_count *
sizeof(*num_src_per_tgt));
1629 weights, num_weights *
sizeof(*weights));
1631 for (
size_t i = 0, j = weights_offset; i < num_weights; ++i, ++j)
1645 for (
size_t i = 0, j = weights_offset; i < num_weights;
1661 for (
size_t i = 0, j = weights_offset; i < num_weights; ++i, ++j)
1666 for (
size_t i = 0; i < num_src_fields; ++i)
1673static struct yac_src_field_exchange_data_msg *
1675 struct yac_src_field_exchange_data_msgs * msgs,
int rank) {
1679 for (; msg_idx < msgs->num_msg; ++msg_idx)
1680 if (msgs->msg[msg_idx].rank == rank)
break;
1683 if (msg_idx == msgs->num_msg) {
1685 msgs->msg =
xrealloc(msgs->msg, msgs->num_msg *
sizeof(*msgs->msg));
1686 msgs->msg[msg_idx] =
1687 (
struct yac_src_field_exchange_data_msg)
1688 {.rank = rank, .pos = NULL, .count = 0};
1691 return msgs->msg + msg_idx;
1704 struct yac_src_field_exchange_data_msgs * msgs,
1705 int rank,
size_t count,
size_t * pos,
size_t offset) {
1709 struct yac_src_field_exchange_data_msg * msg =
1714 xrealloc(msg->pos, ((
size_t)msg->count + count) *
sizeof(*msg->pos));
1715 for (
size_t i = 0; i < count; ++i, ++msg->count)
1716 msg->pos[msg->count] = pos[i] + offset;
1738 struct yac_src_field_exchange_data * src_field_exchange_data,
1739 size_t num_src_fields, MPI_Comm comm,
1740 size_t * send_msg_sizes,
size_t * send_pos,
1741 size_t * recv_msg_sizes,
size_t * recv_pos,
1742 size_t * recv_offsets) {
1748 for (
int rank = 0; rank < comm_size; ++rank) {
1750 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
1751 ++src_field_idx, ++msg_idx) {
1753 struct yac_src_field_exchange_data * curr_src_field_exchange_data =
1754 src_field_exchange_data + src_field_idx;
1757 size_t send_msg_size = send_msg_sizes[msg_idx];
1758 if (send_msg_sizes[msg_idx] > 0) {
1761 &curr_src_field_exchange_data->send, rank, send_msg_size,
1763 send_pos += send_msg_size;
1767 size_t recv_msg_size = recv_msg_sizes[msg_idx];
1768 if (recv_msg_size > 0) {
1771 &curr_src_field_exchange_data->recv, rank, recv_msg_size,
1772 recv_pos, recv_offsets[src_field_idx]);
1773 recv_pos += recv_msg_size;
1780 void * interp,
size_t * src_orig_poses,
size_t * sendcounts,
1782 size_t * recvcounts, MPI_Comm comm, Xt_config redist_config) {
1792 size_t num_src_fields = 1;
1795 size_t total_sendcounts = 0, total_recvcounts = 0;
1796 for (
int i = 0; i < comm_size; ++i) {
1797 total_sendcounts += sendcounts[i];
1798 total_recvcounts += recvcounts[i];
1801 size_t * size_t_buffer =
1803 (
MAX(total_sendcounts, total_recvcounts) + total_recvcounts) *
1804 sizeof(*size_t_buffer));
1805 size_t * send_pos = size_t_buffer;
1806 size_t * recv_pos = size_t_buffer + total_sendcounts;
1808 for (
size_t i = 0; i < total_sendcounts; ++i)
1809 send_pos[i] = (
size_t)src_orig_poses[i];
1810 for (
size_t i = 0; i < total_recvcounts; ++i)
1816 sendcounts, send_pos, recvcounts, recv_pos,
1819 size_t * tgt_idx = size_t_buffer;
1820 size_t * src_idx = size_t_buffer + total_recvcounts;
1822 for (
size_t i = 0; i < total_recvcounts; ++i) {
1823 tgt_idx[i] = (size_t)(tgt_stencils[i].orig_pos);
1829 size_t * num_src_per_tgt = NULL;
1830 double * weights = NULL;
1831 size_t * src_field_idx = NULL;
1832 size_t src_field_buffer_size = total_recvcounts;
1835 tgt_idx, num_src_per_tgt, weights, src_field_idx, src_idx,
1836 &src_field_buffer_size);
1838 free(size_t_buffer);
1842 void * interp,
size_t num_src_fields,
size_t * src_orig_poses,
1844 size_t * recvcounts, MPI_Comm comm, Xt_config redist_config) {
1856 size_t total_sendcounts = 0, total_recvcounts = 0;
1857 for (
size_t rank = 0, idx = 0; rank < (size_t)comm_size; ++rank) {
1858 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
1859 ++src_field_idx, ++idx) {
1860 total_sendcounts += sendcounts[idx];
1861 total_recvcounts += recvcounts[idx];
1865 size_t * size_t_buffer =
1867 (
MAX(total_sendcounts, total_recvcounts) + 2 * total_recvcounts) *
1868 sizeof(*size_t_buffer));
1869 size_t * send_pos = size_t_buffer;
1870 size_t * recv_pos = size_t_buffer + total_sendcounts;
1871 size_t src_field_buffer_size[num_src_fields];
1874 src_field_buffer_size, 0,
1875 num_src_fields *
sizeof(src_field_buffer_size[0]));
1877 for (
size_t i = 0; i < total_sendcounts; ++i)
1878 send_pos[i] = (
size_t)src_orig_poses[i];
1879 for (
size_t rank = 0, idx = 0, recv_pos_idx = 0; rank < (size_t)comm_size;
1881 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
1882 ++src_field_idx, ++idx) {
1883 if (recvcounts[idx] > 0) {
1884 for (
size_t i = 0; i < recvcounts[idx]; ++i, ++recv_pos_idx)
1885 recv_pos[recv_pos_idx] = src_field_buffer_size[src_field_idx]++;
1893 sendcounts, send_pos, recvcounts, recv_pos,
1896 size_t * tgt_idx = size_t_buffer;
1897 size_t * src_idx = size_t_buffer + total_recvcounts;
1898 size_t * src_field_idx = size_t_buffer + 2 * total_recvcounts;
1900 src_field_buffer_size, 0,
1901 num_src_fields *
sizeof(src_field_buffer_size[0]));
1903 for (
size_t rank = 0, idx = 0, k = 0; rank < (size_t)comm_size; ++rank) {
1904 for (
size_t j = 0; j < num_src_fields; ++j, ++idx) {
1906 if (recvcounts[idx] > 0) {
1907 for (
size_t i = 0; i < recvcounts[idx]; ++i, ++k) {
1908 tgt_idx[k] = (size_t)(tgt_stencils[k].orig_pos);
1909 src_idx[k] = src_field_buffer_size[j]++;
1910 src_field_idx[k] = j;
1918 size_t * num_src_per_tgt = NULL;
1919 double * weights = NULL;
1922 tgt_idx, num_src_per_tgt, weights, src_field_idx, src_idx,
1923 src_field_buffer_size);
1925 free(size_t_buffer);
1929 MPI_Comm comm,
size_t count,
1933 void *,
size_t,
size_t *,
size_t *,
1935 Xt_config redist_config,
int * rank_is_source,
int * rank_is_target) {
1937 char const * routine =
"yac_interp_weights_redist_direct_mf";
1945 size_t num_src_fields = 0;
1946 for (
size_t i = 0; i < count; ++i) {
1948 if (src_field_idx >= num_src_fields) num_src_fields = src_field_idx + 1;
1952 MPI_IN_PLACE, &num_src_fields, 1,
YAC_MPI_SIZE_T, MPI_MAX, comm), comm);
1957 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
1959 num_src_fields, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1960 size_t * size_t_buffer =
1961 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
1962 size_t * total_sendcounts = size_t_buffer + 0 * comm_size;
1963 size_t * total_recvcounts = size_t_buffer + 1 * comm_size;
1964 size_t * total_sdispls = size_t_buffer + 2 * comm_size;
1965 size_t * total_rdispls = size_t_buffer + 3 * comm_size;
1969 for (
size_t i = 0; i < count; ++i) {
1973 (&(direct_mf_stencils[i].tgt.data.data.single)):
1976 for (
int j = 0; j < curr_count; ++j)
1978 (
size_t)(curr_point_info[j].
rank) * num_src_fields + src_field_idx]++;
1984 for (
int i = 0; i < comm_size; ++i) {
1985 if (!rank_is_target[i]) {
1986 for (
size_t j = 0; j < num_src_fields; ++j)
1987 sendcounts[(
size_t)i * num_src_fields + j] = 0;
1992 (
size_t)num_src_fields, sendcounts, recvcounts, sdispls, rdispls, comm);
1994 size_t saccu = 0, raccu = 0;
1995 for (
int i = 0; i < comm_size; ++i) {
1996 total_sdispls[i] = saccu;
1997 total_rdispls[i] = raccu;
1998 total_sendcounts[i] = 0;
1999 total_recvcounts[i] = 0;
2000 for (
size_t j = 0; j < num_src_fields; ++j) {
2001 total_sendcounts[i] += sendcounts[num_src_fields * i + j];
2002 total_recvcounts[i] += recvcounts[num_src_fields * i + j];
2004 saccu += total_sendcounts[i];
2005 raccu += total_recvcounts[i];
2008 size_t send_buffer_size = total_sdispls[comm_size - 1] +
2009 total_sendcounts[comm_size - 1];
2010 size_t recv_buffer_size = total_rdispls[comm_size - 1] +
2011 total_recvcounts[comm_size - 1];
2012 size_t tgt_count = recv_buffer_size;
2015 xmalloc((send_buffer_size + recv_buffer_size) *
sizeof(*stencil_buffer));
2017 stencil_buffer + recv_buffer_size;
2021 for (
size_t i = 0; i < count; ++i) {
2025 (&(direct_mf_stencils[i].tgt.data.data.single)):
2029 routine, direct_mf_stencils[i].
data.direct_mf.src.data,
2032 for (
int j = 0; j < curr_count; ++j) {
2033 int tgt_rank = curr_point_infos[j].
rank;
2034 if (rank_is_target[tgt_rank]) {
2036 sdispls[(size_t)tgt_rank * num_src_fields +
2037 src_field_idx + 1]++;
2038 send_stencil_buffer[pos].
src =
src;
2050 send_stencil_buffer, total_sendcounts, total_sdispls,
2051 recv_stencil_buffer, total_recvcounts, total_rdispls,
2052 sizeof(*stencil_buffer), stencil_direct_mf_dt, comm,
2053 "yac_interp_weights_redist_direct_mf", __LINE__);
2055 yac_mpi_call(MPI_Type_free(&stencil_direct_mf_dt), comm);
2059 qsort(recv_stencil_buffer, tgt_count,
sizeof(*recv_stencil_buffer),
2066 memset(sendcounts, 0,
2067 (
size_t)comm_size * (
size_t)num_src_fields *
sizeof(*sendcounts));
2069 for (
size_t i = 0; i < tgt_count; ++i)
2070 sendcounts[(
size_t)(recv_stencil_buffer[i].
src.
rank) * num_src_fields +
2071 recv_stencil_buffer[i].src_field_idx]++;
2074 (
size_t)num_src_fields, sendcounts, recvcounts, sdispls, rdispls, comm);
2076 saccu = 0, raccu = 0;
2077 for (
int i = 0; i < comm_size; ++i) {
2078 total_sdispls[i] = saccu;
2079 total_rdispls[i] = raccu;
2080 total_sendcounts[i] = 0;
2081 total_recvcounts[i] = 0;
2082 for (
size_t j = 0; j < num_src_fields; ++j) {
2083 total_sendcounts[i] += sendcounts[num_src_fields * i + j];
2084 total_recvcounts[i] += recvcounts[num_src_fields * i + j];
2086 saccu += total_sendcounts[i];
2087 raccu += total_recvcounts[i];
2090 send_buffer_size = total_sdispls[comm_size - 1] +
2091 total_sendcounts[comm_size - 1];
2092 recv_buffer_size = total_rdispls[comm_size - 1] +
2093 total_recvcounts[comm_size - 1];
2095 size_t * orig_pos_buffer =
2096 xmalloc((send_buffer_size + recv_buffer_size) *
sizeof(*orig_pos_buffer));
2097 size_t * send_orig_pos_buffer = orig_pos_buffer + recv_buffer_size;
2098 size_t * recv_orig_pos_buffer = orig_pos_buffer;
2100 for (
size_t i = 0; i < tgt_count; ++i)
2101 send_orig_pos_buffer[
2102 sdispls[(
size_t)(recv_stencil_buffer[i].
src.
rank) * num_src_fields +
2103 recv_stencil_buffer[i].src_field_idx + 1]++] =
2104 recv_stencil_buffer[i].
src.orig_pos;
2108 send_orig_pos_buffer, total_sendcounts, total_sdispls,
2109 recv_orig_pos_buffer, total_recvcounts, total_rdispls,
2111 "yac_interp_weights_redist_direct_mf", __LINE__);
2112 free(size_t_buffer);
2119 interp, num_src_fields,
2120 recv_orig_pos_buffer, recvcounts, recv_stencil_buffer, sendcounts,
2121 comm, redist_config);
2124 free(orig_pos_buffer);
2125 free(stencil_buffer);
2135 int pack_size_value;
2137 yac_mpi_call(MPI_Pack_size(1, MPI_DOUBLE, comm, &pack_size_value), comm);
2139 return pack_size_value;
2164 int pack_size_weights;
2168 MPI_DOUBLE, comm, &pack_size_weights), comm);
2180 int pack_size_src_field_idx;
2188 pack_size_src_field_idx;
2195 int pack_size_weights, pack_size_field_indices;
2199 count, MPI_DOUBLE, comm, &pack_size_weights), comm);
2207 pack_size_weights + pack_size_field_indices;
2214 int pack_size_field_indices;
2223 pack_size_field_indices;
2241 switch (stencil->
type) {
2260 size_t weight_size =
2279 size_t field_indices_size =
2293 size_t weight_size =
2299 size_t field_indices_size =
2309 return stencil_copy;
2328 switch (stencil->
type) {
2353 double * new_weights =
xmalloc(src_count *
sizeof(*new_weights));
2354 if (weights == NULL)
2355 for (
size_t i = 0; i < src_count; ++i) new_weights[i] = weight;
2357 for (
size_t i = 0; i < src_count; ++i) new_weights[i] = weights[i] * weight;
2365 return stencil_wcopy;
2375 if (ret)
return ret;
2393 size_t count = srcs->
count;
2396 xmalloc(count *
sizeof(*w_global_id));
2399 for (
size_t i = 0; i < count; ++i) {
2401 w_global_id[i].
weight = (*w)[i];
2410 size_t new_count = 0;
2413 for (
size_t i = 0; i < count;) {
2418 double curr_weight = w_global_id[i].
weight;
2422 while((i < count) && (curr_global_id == w_global_id[i].
global_id)) {
2424 curr_weight += w_global_id[i].
weight;
2428 (*w)[new_count] = curr_weight;
2435 srcs->
count = new_count;
2436 *w =
xrealloc(*w, new_count *
sizeof(**w));
2442 size_t src_count = 0;
2443 size_t point_info_buffer_size = 0;
2445 for (
size_t i = 0; i < num_stencils; ++i) {
2446 size_t curr_src_count;
2448 switch (stencils[i]->
type) {
2463 src_count += curr_src_count;
2464 for (
size_t j = 0, curr_src_data_count; j < curr_src_count; ++j)
2465 if (((curr_src_data_count = srcs[j].
data.count)) > 1)
2466 point_info_buffer_size += curr_src_data_count;
2473 srcs->
count = src_count;
2475 double * new_w =
xmalloc(src_count *
sizeof(*new_w));
2477 for (
size_t i = 0, offset = 0; i < num_stencils; ++i) {
2478 size_t curr_src_count;
2481 switch (stencils[i]->
type) {
2500 srcs->
data + offset, curr_srcs, curr_src_count, &point_info_buffer);
2501 if (stencil_w == NULL)
2502 for (
size_t j = 0; j < curr_src_count; ++j, ++offset)
2503 new_w[offset] = w[i];
2505 for (
size_t j = 0; j < curr_src_count; ++j, ++offset)
2506 new_w[offset] = w[i] * stencil_w[j];
2516 return merge_stencil;
2522 for (
size_t i = 0; i < num_stencils; ++i)
2526 size_t src_count = 0;
2527 size_t point_info_buffer_size = 0;
2529 for (
size_t i = 0; i < num_stencils; ++i) {
2530 size_t curr_src_count;
2533 switch (stencils[i]->
type) {
2544 src_count += curr_src_count;
2545 for (
size_t j = 0, curr_src_data_count; j < curr_src_count; ++j)
2546 if (((curr_src_data_count = srcs[j].
data.count)) > 1)
2547 point_info_buffer_size += curr_src_data_count;
2554 srcs->
count = src_count;
2557 for (
size_t i = 0, offset = 0; i < num_stencils; ++i) {
2558 size_t curr_src_count;
2560 switch (stencils[i]->
type) {
2572 srcs->
data + offset, curr_srcs, curr_src_count, &point_info_buffer);
2573 offset += curr_src_count;
2582 return merge_stencil;
2589 if (num_stencils == 1)
2592 int fixed_count = 0;
2593 int direct_count = 0;
2598 for (
size_t i = 0; i < num_stencils; ++i) {
2603 "multiple source fields not yet supported")
2604 switch (stencils[i]->
type) {
2608 !isnan(stencils[i]->
data.fixed.value),
2609 "fixed_value == NaN is not yet supported by this routine "
2610 "(please contact the developers of YAC if you see this message");
2629 (fixed_count > 0) || (wsum_count > 0) ||
2630 (sum_count > 0) || (direct_count > 0),
"unknown error")
2631 if (fixed_count > 0) {
2634 (direct_count + sum_count + wsum_count) <= 0,
2635 "invalid stencil combination")
2637 merge_stencil = **stencils;
2639 }
else if (wsum_count > 0)
2642 else if ((sum_count > 0) || (direct_count > 0))
2648 return merge_stencil;
2653 int * pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm) {
2656 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &pack_size_type), comm);
2658 for (
size_t i = 0; i < count; ++i) {
2661 int (*func_pack_size)(
2667 (curr_stencil->
type ==
SUM) ||
2672 switch (curr_stencil->
type) {
2696 pack_sizes[i] = pack_size_type +
2698 &(curr_stencil->
tgt), point_info_dt, comm) +
2699 func_pack_size(curr_stencil, point_info_dt, comm);
2705 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2712 position, comm), comm);
2717 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2727 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2736 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2741 point_info_dt, comm);
2746 buffer, buffer_size, position, comm), comm);
2751 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2756 point_info_dt, comm);
2762 buffer, buffer_size, position, comm), comm);
2767 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2772 point_info_dt, comm);
2776 size_t * temp_field_indices =
xmalloc(count *
sizeof(*temp_field_indices));
2777 for (
size_t i = 0; i < count; ++i)
2781 buffer, buffer_size, position, comm), comm);
2782 free(temp_field_indices);
2787 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2792 point_info_dt, comm);
2798 buffer, buffer_size, position, comm), comm);
2800 size_t * temp_field_indices =
xmalloc(count *
sizeof(*temp_field_indices));
2801 for (
size_t i = 0; i < count; ++i)
2805 buffer, buffer_size, position, comm), comm);
2806 free(temp_field_indices);
2811 void ** pack_data,
int * pack_sizes, MPI_Datatype point_info_dt,
2815 stencils, count, pack_order, pack_sizes, point_info_dt, comm);
2817 size_t pack_buffer_size = 0;
2818 for (
size_t i = 0; i < count; ++i)
2819 pack_buffer_size += (
size_t)(pack_sizes[i]);
2821 void * pack_data_ =
xmalloc(pack_buffer_size);
2822 size_t total_pack_size = 0;
2824 for (
size_t i = 0; i < count; ++i) {
2829 int * position, MPI_Datatype point_info_dt, MPI_Comm comm);
2834 (curr_stencil->
type ==
SUM) ||
2839 switch (curr_stencil->
type) {
2865 int type = (int)curr_stencil->
type;
2866 void *
buffer = (
void*)((
char*)pack_data_ + total_pack_size);
2867 int buffer_size = pack_sizes[i];
2871 MPI_Pack(&
type, 1, MPI_INT,
buffer, buffer_size, &position, comm), comm);
2874 &position, point_info_dt, comm);
2876 func_pack(curr_stencil,
buffer, buffer_size, &position, point_info_dt, comm);
2879 pack_sizes[i] >= position,
2880 "actual pack size is bigger then computed one (%d > %d)",
2881 position, pack_sizes[i]);
2883 pack_sizes[i] = position;
2884 total_pack_size += (size_t)position;
2887 *pack_data =
xrealloc(pack_data_, total_pack_size);
2892 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2899 MPI_DOUBLE, comm), comm);
2904 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2909 point_info_dt, comm);
2914 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2925 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2930 point_info_dt, comm);
2940 (
int)count, MPI_DOUBLE, comm), comm);
2945 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2950 point_info_dt, comm);
2953 size_t temp_field_idx;
2956 buffer, buffer_size, position, &temp_field_idx,
2963 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2968 point_info_dt, comm);
2972 size_t * temp_field_indices =
xmalloc(count *
sizeof(*temp_field_indices));
2979 buffer, buffer_size, position, temp_field_indices,
2981 for (
size_t i = 0; i < count; ++i)
2983 free(temp_field_indices);
2988 int * position, MPI_Datatype point_info_dt, MPI_Comm comm) {
2993 point_info_dt, comm);
3004 (
int)count, MPI_DOUBLE, comm), comm);
3006 size_t * temp_field_indices =
xmalloc(count *
sizeof(*temp_field_indices));
3013 buffer, buffer_size, position, temp_field_indices,
3015 for (
size_t i = 0; i < count; ++i)
3017 (
size_t)(temp_field_indices[i]);
3018 free(temp_field_indices);
3023 void * packed_data,
size_t packed_data_size,
3024 MPI_Datatype point_info_dt, MPI_Comm comm) {
3026 for (
size_t i = 0, offset = 0; i < count; ++i) {
3028 YAC_ASSERT(packed_data_size >= offset,
"invalid offset");
3031 void * curr_buffer = (
void*)((
unsigned char*)packed_data + offset);
3032 int buffer_size = (int)(
MIN(packed_data_size - offset, INT_MAX));
3038 curr_buffer, buffer_size, &position, &
type, 1, MPI_INT, comm), comm);
3040 void (*func_unpack)(
3042 int * position, MPI_Datatype point_info_dt, MPI_Comm comm);
3048 "invalid stencil type")
3074 curr_stencil->
type =
3077 curr_buffer, buffer_size, &position, &(curr_stencil->
tgt),
3078 point_info_dt, comm);
3080 curr_stencil, curr_buffer, buffer_size, &position, point_info_dt, comm);
3081 offset += (size_t)position;
3087 size_t * stencil_indices,
3088 size_t * stencil_sendcounts,
size_t * stencil_recvcounts) {
3090 int comm_rank, comm_size;
3095 stencil_sendcounts[comm_rank] == stencil_recvcounts[comm_rank],
3096 "error in arguments")
3098 size_t send_count = 0, recv_count = 0;
3099 size_t local_send_offset = 0;
3100 size_t local_recv_offset = 0;
3101 size_t local_count = (size_t)(stencil_sendcounts[comm_rank]);
3102 for (
int i = 0; i < comm_rank; ++i) {
3103 send_count += stencil_sendcounts[i];
3104 recv_count += stencil_recvcounts[i];
3105 local_send_offset += stencil_sendcounts[i];
3106 local_recv_offset += stencil_recvcounts[i];
3108 local_send_offset = send_count;
3109 local_recv_offset = recv_count;
3110 stencil_sendcounts[comm_rank] = 0;
3111 stencil_recvcounts[comm_rank] = 0;
3112 for (
int i = comm_rank + 1; i < comm_size; ++i) {
3113 send_count += stencil_sendcounts[i];
3114 recv_count += stencil_recvcounts[i];
3118 xmalloc((recv_count + local_count) *
sizeof(*new_stencils));
3119 size_t * local_stencil_indices =
3120 xmalloc(local_count *
sizeof(*local_stencil_indices));
3121 memcpy(local_stencil_indices, stencil_indices + local_send_offset,
3122 local_count *
sizeof(*local_stencil_indices));
3126 stencil_indices + local_send_offset,
3127 stencil_indices + local_send_offset + local_count,
3128 (send_count - local_send_offset) *
sizeof(*stencil_indices));
3132 int * pack_sizes =
xmalloc(send_count *
sizeof(*pack_sizes));
3135 stencils, send_count, stencil_indices, &
send_buffer, pack_sizes,
3136 point_info_dt, comm);
3138 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
3140 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3143 for (
int rank = 0; rank < comm_size; ++rank) {
3144 size_t sendcount = 0;
3145 int curr_num_stencils = stencil_sendcounts[rank];
3146 for (
int j = 0; j < curr_num_stencils; ++j, ++send_count)
3147 sendcount += (
size_t)(pack_sizes[send_count]);
3148 sendcounts[rank] = sendcount;
3153 1, sendcounts, recvcounts, sdispls, rdispls, comm);
3155 size_t recv_size = recvcounts[comm_size - 1] + rdispls[comm_size - 1];
3160 yac_alltoallv_packed_p2p(
3162 recv_buffer, recvcounts, rdispls, comm,
"exchange_stencils", __LINE__);
3168 new_stencils, recv_count,
3173 memmove(new_stencils + local_recv_offset + local_count,
3174 new_stencils + local_recv_offset ,
3175 (recv_count - local_recv_offset ) *
sizeof(*new_stencils));
3176 for (
size_t i = 0; i < local_count; ++i, ++local_recv_offset )
3177 new_stencils[local_recv_offset] =
3179 stencils + local_stencil_indices[i],
3180 stencils[local_stencil_indices[i]].
tgt);
3181 free(local_stencil_indices);
3183 return new_stencils;
3188 int * stencil_ranks,
size_t count) {
3190 char const * routine =
"yac_interp_weights_get_stencils";
3192 MPI_Comm comm =
weights->comm;
3196 YAC_ASSERT(count <= INT_MAX,
"count exceeds INT_MAX");
3198 size_t * reorder_idx =
xmalloc(count *
sizeof(*reorder_idx));
3199 for (
size_t i = 0; i < count; ++i) reorder_idx[i] = i;
3202 stencil_ranks, count, stencil_indices, reorder_idx);
3205 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
3207 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3208 for (
size_t i = 0; i < count; ++i) sendcounts[stencil_ranks[i]]++;
3210 1, sendcounts, recvcounts, sdispls, rdispls, comm);
3212 rdispls[comm_size - 1] + recvcounts[comm_size - 1];
3213 size_t * size_t_buffer =
3214 xmalloc((count + recv_count) *
sizeof(*size_t_buffer));
3215 size_t * send_stencil_indices = size_t_buffer;
3216 size_t * recv_stencil_indices = size_t_buffer + count;
3217 for (
size_t i = 0; i < count; ++i)
3218 send_stencil_indices[i] = stencil_indices[i];
3219 yac_alltoallv_size_t_p2p(
3220 send_stencil_indices, sendcounts, sdispls+1,
3221 recv_stencil_indices, recvcounts, rdispls, comm, routine, __LINE__);
3224 size_t * exchange_stencil_indices =
3225 xmalloc(recv_count *
sizeof(*exchange_stencil_indices));
3226 for (
size_t i = 0; i < recv_count; ++i) {
3228 (
size_t)(recv_stencil_indices[i]) <
weights->stencils_size,
3229 "invalid stencil index");
3230 exchange_stencil_indices[i] = (size_t)(recv_stencil_indices[i]);
3232 free(size_t_buffer);
3235 recvcounts, sendcounts);
3236 free(exchange_stencil_indices);
3241 xmalloc(count *
sizeof(*sorted_stencils));
3242 for (
size_t i = 0; i < count; ++i)
3243 sorted_stencils[reorder_idx[i]] = stencils[i];
3247 return sorted_stencils;
3255 size_t * num_stencils_per_tgt,
size_t * stencil_indices,
3256 int * stencil_ranks,
double * w) {
3258 size_t count = (tgts != NULL)?tgts->
count:0;
3259 MPI_Comm comm =
weights->comm;
3260 int comm_rank, comm_size;
3265 size_t total_num_stencils = 0;
3266 size_t max_num_stencils_per_tgt = 0;
3267 for (
size_t i = 0; i < count; ++i) {
3268 size_t curr_num_stencils_per_tgt = num_stencils_per_tgt[i];
3269 if (curr_num_stencils_per_tgt > max_num_stencils_per_tgt)
3270 max_num_stencils_per_tgt = curr_num_stencils_per_tgt;
3271 total_num_stencils += num_stencils_per_tgt[i];
3273 size_t num_missing_stencils = 0;
3274 for (
size_t i = 0; i < total_num_stencils; ++i)
3275 if (stencil_ranks[i] != comm_rank) num_missing_stencils++;
3278 size_t * missing_stencil_indices =
3279 xmalloc(num_missing_stencils *
sizeof(*missing_stencil_indices));
3280 int * missing_stencil_ranks =
3281 xmalloc(num_missing_stencils *
sizeof(*missing_stencil_ranks));
3282 for (
size_t i = 0, j = 0; i < total_num_stencils; ++i) {
3283 if (stencil_ranks[i] != comm_rank) {
3284 missing_stencil_indices[j] = stencil_indices[i];
3285 missing_stencil_ranks[j] = stencil_ranks[i];
3291 weights, missing_stencil_indices, missing_stencil_ranks,
3292 num_missing_stencils);
3293 free(missing_stencil_ranks);
3294 free(missing_stencil_indices);
3299 size_t stencils_array_size =
weights->stencils_array_size;
3300 size_t stencils_size =
weights->stencils_size;
3303 xmalloc(max_num_stencils_per_tgt *
sizeof(*stencils_buffer));
3306 stencils, stencils_array_size, stencils_size + count);
3308 for (
size_t i = 0, j = 0; i < count;
3309 ++i, ++stencils_size) {
3311 size_t curr_num_stencils = num_stencils_per_tgt[i];
3312 for (
size_t k = 0; k < curr_num_stencils; ++k)
3313 stencils_buffer[k] =
3314 (stencil_ranks[k] == comm_rank)?
3315 (stencils + stencil_indices[k]):(missing_stencils + (j++));
3317 stencils[stencils_size] =
3319 w += curr_num_stencils;
3320 stencil_indices += curr_num_stencils;
3321 stencil_ranks += curr_num_stencils;
3325 weights->stencils_array_size = stencils_array_size;
3326 weights->stencils_size = stencils_size;
3328 free(stencils_buffer);
3341 size_t best_rank_count = 0;
3343 size_t curr_rank_count = 1;
3344 int prev_rank = ranks[0];
3346 for (
size_t i = 1; i < count; ++i, ++curr_rank_count) {
3347 int curr_rank = ranks[i];
3348 if (prev_rank != curr_rank) {
3349 if (curr_rank_count > best_rank_count) {
3350 best_rank = prev_rank;
3351 best_rank_count = curr_rank_count;
3353 prev_rank = curr_rank;
3354 curr_rank_count = 0;
3358 return (curr_rank_count > best_rank_count)?prev_rank:best_rank;
3364 int * rank_is_source,
int * rank_is_target) {
3367 size_t total_num_links = 0;
3369 size_t valid_count = 0;
3370 for (
size_t i = 0; i <
count; ++i) {
3372 YAC_ASSERT(stencils[i].
type == stencil_type,
"wrong stencil type")
3380 xmalloc(
sizeof(*temp) + total_num_links *
sizeof(temp->
buffer[0]));
3383 wsum_stencils->
data =
xmalloc(valid_count *
sizeof(*(wsum_stencils->
data)));
3384 wsum_stencils->
count = valid_count;
3387 for (
size_t i = 0, j = 0, k = 0; i <
count; ++i) {
3394 wsum_stencils->
data + j;
3400 curr_wsum_stencil->
tgt =
3402 curr_wsum_stencil->
count = curr_stencil_size;
3403 curr_wsum_stencil->
data = curr_links;
3404 for (
size_t l = 0; l < curr_stencil_size; ++l) {
3405 int curr_count = curr_srcs[l].
data.
count;
3406 YAC_ASSERT(curr_count >= 1,
"global src id no found")
3410 switch(stencil_type) {
3413 curr_links[l].
weight = 1.0;
3421 curr_links[l].
weight = 1.0;
3432 k += curr_stencil_size;
3437 return wsum_stencils;
3444 enum {NUM_MEMBERS = 4};
3445 int array_of_blocklengths[NUM_MEMBERS] = {1, 1, 1, 1};
3446 MPI_Aint array_of_displacements[NUM_MEMBERS];
3449 yac_mpi_call(MPI_Get_address(&dummy, &base_addr), comm);
3452 &(dummy.
src.
rank), &array_of_displacements[0]), comm);
3453 array_of_displacements[0] -= base_addr;
3456 &(dummy.
src.
orig_pos), &array_of_displacements[1]), comm);
3457 array_of_displacements[1] -= base_addr;
3461 array_of_displacements[2] -= base_addr;
3464 &(dummy.
weight), &array_of_displacements[3]), comm);
3465 array_of_displacements[3] -= base_addr;
3467 const MPI_Datatype array_of_types[NUM_MEMBERS] =
3470 MPI_Type_create_struct(
3471 NUM_MEMBERS, array_of_blocklengths, array_of_displacements,
3472 array_of_types, &dt), comm);
3478 MPI_Datatype wsum_mf_weight_dt, MPI_Datatype point_info_dt, MPI_Comm comm) {
3480 int pack_size_count,
3484 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &pack_size_count), comm);
3487 (
int)(stencil->
count), wsum_mf_weight_dt, comm, &pack_size_weights), comm);
3491 return pack_size_count + pack_size_weights + pack_size_tgt;
3496 size_t * pack_order,
void ** pack_data,
int * pack_sizes,
3497 int * weight_counts, MPI_Comm comm) {
3503 size_t temp_total_pack_size = 0;
3504 for (
size_t i = 0; i < count; ++i) {
3505 temp_total_pack_size +=
3508 wsum_stencils + pack_order[i],
3509 wsum_mf_weight_dt, point_info_dt, comm));
3512 void * pack_data_ =
xmalloc(temp_total_pack_size);
3513 size_t total_pack_size = 0;
3516 for (
size_t i = 0; i < count; ++i) {
3518 size_t idx = pack_order[i];
3521 void *
buffer = (
void*)((
unsigned char*)pack_data_ + total_pack_size);
3522 int buffer_size = pack_sizes[i];
3523 int curr_count = wsum_stencils[idx].
count;
3527 &(wsum_stencils[idx].tgt),
buffer, buffer_size, &position,
3528 point_info_dt, comm);
3531 MPI_Pack(&curr_count, 1, MPI_INT,
buffer, buffer_size, &position, comm), comm);
3534 MPI_Pack(wsum_stencils[idx].
data, curr_count, wsum_mf_weight_dt,
3535 buffer, buffer_size, &position, comm), comm);
3537 pack_sizes[i] = position;
3538 weight_counts[i] = curr_count;
3539 total_pack_size += (size_t)position;
3545 *pack_data =
xrealloc(pack_data_, total_pack_size);
3551 void * packed_data,
size_t packed_data_size, MPI_Comm comm) {
3556 size_t weight_offset = 0;
3557 for (
size_t i = 0, offset = 0; i < count; ++i) {
3560 void * curr_buffer = (
void*)((
char*)packed_data + offset);
3561 int buffer_size = (int)(packed_data_size - offset);
3567 weight_buffer + weight_offset;
3570 curr_buffer, buffer_size, &position, &tgt, point_info_dt, comm);
3572 MPI_Unpack(curr_buffer, buffer_size, &position,
3573 &weight_count, 1, MPI_INT, comm),
3576 MPI_Unpack(curr_buffer, buffer_size, &position,
3577 curr_weights, weight_count, wsum_mf_weight_dt, comm), comm);
3579 curr_wsum_stencil->
tgt = tgt;
3580 curr_wsum_stencil->
data = curr_weights;
3581 curr_wsum_stencil->
count = (size_t)weight_count;
3583 weight_offset += (size_t)weight_count;
3584 offset += (size_t)position;
3590 return weight_offset;
3595 int * stencil_owner,
size_t * reorder_idx,
size_t num_owners) {
3598 wsum_stencils_data->
data;
3600 int comm_rank, comm_size;
3604 size_t local_weight_count = 0;
3605 size_t local_count = 0;
3606 for (
size_t i = 0; i < num_owners; ++i) {
3607 if (stencil_owner[i] == comm_rank) {
3608 local_weight_count += wsum_stencils[reorder_idx[i]].
count;
3609 stencil_owner[i] = INT_MAX;
3615 size_t send_count = num_owners - local_count;
3619 int * pack_sizes =
xmalloc(2 * send_count *
sizeof(*pack_sizes));
3620 int * weight_counts = pack_sizes + send_count;
3622 pack_sizes, weight_counts, comm);
3624 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
3626 3, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3628 for (
size_t i = 0; i < send_count; ++i) {
3629 int curr_rank = stencil_owner[i];
3630 sendcounts[3 * curr_rank + 0]++;
3631 sendcounts[3 * curr_rank + 1] += (size_t)(pack_sizes[i]);
3632 sendcounts[3 * curr_rank + 2] += (size_t)(weight_counts[i]);
3640 size_t recv_count = 0;
3641 size_t recv_size = 0;
3642 size_t recv_weight_count = 0;
3643 size_t saccu = 0, raccu = 0;
3644 for (
int i = 0; i < comm_size; ++i) {
3647 recv_count += recvcounts[3 * i + 0];
3648 recv_size += recvcounts[3 * i + 1];
3649 recv_weight_count += recvcounts[3 * i + 2];
3650 saccu += sendcounts[3 * i + 1];
3651 raccu += recvcounts[3 * i + 1];
3652 sendcounts[i] = sendcounts[3 * i + 1];
3653 recvcounts[i] = recvcounts[3 * i + 1];
3659 yac_alltoallv_packed_p2p(
3661 "redist_wsum_mf_stencils", __LINE__);
3667 (local_weight_count + recv_weight_count) *
sizeof(temp->
buffer[0]));
3671 ((new_wsum_stencils_data->
data =
3672 xmalloc((local_count + recv_count) *
3673 sizeof(*(new_wsum_stencils_data->
data)))));
3674 new_wsum_stencils_data->
count = local_count + recv_count;
3677 size_t weight_offset =
3679 new_wsum_stencils, &(temp->
buffer[0]), recv_count,
3682 new_wsum_stencils += recv_count;
3684 &(temp->
buffer[weight_offset]);
3688 for (
size_t i = 0, weight_offset = 0; i < local_count; ++i) {
3690 wsum_stencils + reorder_idx[i + send_count];
3692 new_wsum_stencils + i;
3694 weight_buffer + weight_offset;
3695 size_t curr_stencil_size = curr_wsum_stencil->
count;
3697 curr_new_wsum_stencil->
count = curr_stencil_size;
3698 curr_new_wsum_stencil->
data = curr_new_weights;
3699 memcpy(curr_new_weights, curr_wsum_stencil->
data,
3700 curr_stencil_size *
sizeof(*curr_new_weights));
3701 weight_offset += curr_stencil_size;
3704 return new_wsum_stencils_data;
3711 wsum_stencils_data->
data;
3715 size_t max_stencil_size = 0;
3716 for (
size_t i = 0; i <
count; ++i) {
3717 size_t curr_stencil_size = wsum_stencils[i].
count;
3718 if (curr_stencil_size > max_stencil_size)
3719 max_stencil_size = curr_stencil_size;
3724 xmalloc((
count + max_stencil_size) *
sizeof(*rank_buffer));
3725 int * stencil_owner = rank_buffer;
3726 int * stencil_owners = rank_buffer +
count;
3727 size_t * reorder_idx =
xmalloc(
count *
sizeof(*reorder_idx));
3728 for (
size_t i = 0; i <
count; ++i) {
3729 size_t curr_stencil_size = wsum_stencils[i].
count;
3731 wsum_stencils[i].
data;
3732 for (
size_t j = 0; j < curr_stencil_size; ++j)
3733 stencil_owners[j] = curr_weights[j].
src.rank;
3734 stencil_owner[i] =
compute_owner(stencil_owners, curr_stencil_size);
3740 comm, wsum_stencils_data, stencil_owner, reorder_idx,
count);
3745 return new_wsum_stencils_data;
3753 if (ret)
return ret;
3765 wsum_stencils_data->
data;
3770 size_t total_owner_count = 0;
3771 for (
size_t i = 0; i <
count; ++i) {
3773 if (stencil_size == 1) {
3774 total_owner_count++;
3779 tgt_point_infos, stencil_size,
sizeof(*tgt_point_infos),
3781 int prev_rank = INT_MAX;
3782 for (
int j = 0; j < stencil_size; ++j) {
3783 int curr_rank = tgt_point_infos[j].
rank;
3784 if (curr_rank != prev_rank) {
3785 ++total_owner_count;
3786 prev_rank = curr_rank;
3792 int * stencil_owner =
xmalloc(total_owner_count *
sizeof(*stencil_owner));
3793 size_t * reorder_idx =
xmalloc(total_owner_count *
sizeof(*reorder_idx));
3794 for (
size_t i = 0, k = 0; i < count; ++i) {
3796 if (stencil_size == 1) {
3803 int prev_rank = INT_MAX;
3804 for (
int j = 0; j < stencil_size; ++j) {
3805 int curr_rank = tgt_point_infos[j].
rank;
3806 if (curr_rank != prev_rank) {
3807 stencil_owner[k] = tgt_point_infos[j].
rank;
3810 prev_rank = curr_rank;
3818 comm, wsum_stencils_data, stencil_owner, reorder_idx, total_owner_count);
3820 wsum_stencils = new_wsum_stencils_data->
data;
3824 free(stencil_owner);
3826 if (
count == 0)
return new_wsum_stencils_data;
3832 size_t total_num_tgt_pos = 0;
3833 for (
size_t i = 0; i <
count; ++i) {
3835 if (curr_count == 1) {
3836 ++total_num_tgt_pos;
3840 for (
size_t j = 0; j < curr_count; ++j)
3841 if (curr_point_infos[j].
rank == comm_rank)
3842 ++total_num_tgt_pos;
3846 if (total_num_tgt_pos != count) {
3847 new_wsum_stencils_data->
data =
3849 xrealloc(wsum_stencils, total_num_tgt_pos *
sizeof(*wsum_stencils))));
3850 new_wsum_stencils_data->
count = total_num_tgt_pos;
3854 for (
size_t i = 0, offset = count; i < count; ++i) {
3856 if (curr_count > 1) {
3861 for (j = 0; j < curr_count; ++j) {
3862 if (curr_point_infos[j].
rank == comm_rank) {
3871 for (j = j + 1; j < curr_count; ++j) {
3872 if (curr_point_infos[j].
rank == comm_rank) {
3873 wsum_stencils[offset] = wsum_stencils[i];
3879 free(curr_point_infos);
3883 return new_wsum_stencils_data;
3888 size_t num_src_fields, MPI_Comm comm, Xt_config redist_config) {
3893 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
3895 num_src_fields, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3896 size_t * size_t_buffer =
3897 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
3898 size_t * total_sendcounts = size_t_buffer + 0 * comm_size;
3899 size_t * total_recvcounts = size_t_buffer + 1 * comm_size;
3900 size_t * total_sdispls = size_t_buffer + 2 * comm_size;
3901 size_t * total_rdispls = size_t_buffer + 3 * comm_size;
3903 for (
size_t i = 0; i < count; ++i)
3904 sendcounts[halo_points[i].
data.rank * num_src_fields +
3908 num_src_fields, sendcounts, recvcounts, sdispls, rdispls, comm);
3910 size_t saccu = 0, raccu = 0;
3911 for (
int i = 0; i < comm_size; ++i) {
3912 total_sdispls[i] = saccu;
3913 total_rdispls[i] = raccu;
3914 total_sendcounts[i] = 0;
3915 total_recvcounts[i] = 0;
3916 for (
size_t j = 0; j < num_src_fields; ++j) {
3917 total_sendcounts[i] += sendcounts[num_src_fields * i + j];
3918 total_recvcounts[i] += recvcounts[num_src_fields * i + j];
3920 saccu += total_sendcounts[i];
3921 raccu += total_recvcounts[i];
3924 size_t recv_count = total_recvcounts[comm_size - 1] +
3925 total_rdispls[comm_size - 1];
3927 int * exchange_buffer =
3928 xmalloc((2 * count + recv_count) *
sizeof(*exchange_buffer));
3930 int * reorder_idx = exchange_buffer + count;
3934 size_t num_halo_per_src_field[num_src_fields];
3936 num_halo_per_src_field, 0,
3937 num_src_fields *
sizeof(num_halo_per_src_field[0]));
3938 for (
size_t i = 0; i < count; ++i) {
3939 size_t curr_src_field_idx = (size_t)(halo_points[i].field_idx);
3940 size_t pos = sdispls[(size_t)(halo_points[i].
data.rank) * num_src_fields +
3941 curr_src_field_idx + 1]++;
3945 reorder_idx[pos] = num_halo_per_src_field[curr_src_field_idx]++;
3949 yac_alltoallv_int_p2p(
3951 recv_buffer, total_recvcounts, total_rdispls, comm,
3952 "generate_halo_redists", __LINE__);
3954 free(size_t_buffer);
3956 size_t nsend = 0, nsends[num_src_fields];
3957 size_t nrecv = 0, nrecvs[num_src_fields];
3958 memset(nsends, 0, num_src_fields *
sizeof(nsends[0]));
3959 memset(nrecvs, 0, num_src_fields *
sizeof(nrecvs[0]));
3960 for (
int i = 0; i < comm_size; ++i) {
3961 for (
size_t field_idx = 0; field_idx < num_src_fields; ++field_idx) {
3962 if (sendcounts[i * num_src_fields + field_idx] > 0) {
3964 nrecvs[field_idx]++;
3966 if (recvcounts[i * num_src_fields + field_idx] > 0) {
3968 nsends[field_idx]++;
3973 size_t total_num_msg = nsend + nrecv;
3975 struct Xt_redist_msg * msgs_buffer =
3976 xmalloc(total_num_msg *
sizeof(*msgs_buffer));
3977 struct Xt_redist_msg * send_msgs = msgs_buffer;
3978 struct Xt_redist_msg * recv_msgs = msgs_buffer + nsend;
3980 for (
size_t field_idx = 0, nsend = 0, nrecv = 0;
3981 field_idx < num_src_fields; ++field_idx) {
3982 for (
int rank = 0; rank < comm_size; ++rank) {
3983 size_t idx = (size_t)rank * num_src_fields + field_idx;
3984 if (sendcounts[idx] > 0) {
3985 recv_msgs[nrecv].rank = rank;
3986 recv_msgs[nrecv].datatype =
3987 xt_mpi_generate_datatype(
3988 reorder_idx + sdispls[idx], sendcounts[idx], MPI_DOUBLE, comm);
3991 if (recvcounts[idx] > 0) {
3992 send_msgs[nsend].rank = rank;
3993 send_msgs[nsend].datatype =
3994 xt_mpi_generate_datatype(
3995 recv_buffer + rdispls[idx], recvcounts[idx], MPI_DOUBLE, comm);
4004 if (total_num_msg > 0) {
4006 yac_mpi_call(MPI_Comm_split(comm, 1, 0, &halo_comm), comm);
4008 int * rank_buffer =
xmalloc(2 * total_num_msg *
sizeof(*rank_buffer));
4009 int * orig_ranks = rank_buffer;
4010 int * split_ranks = rank_buffer + total_num_msg;
4012 for (
size_t i = 0; i < total_num_msg; ++i)
4013 orig_ranks[i] = msgs_buffer[i].rank;
4015 MPI_Group orig_group, split_group;
4017 yac_mpi_call(MPI_Comm_group(halo_comm, &split_group), comm);
4020 MPI_Group_translate_ranks(orig_group, (
int)total_num_msg, orig_ranks,
4021 split_group, split_ranks), halo_comm);
4023 for (
size_t i = 0; i < total_num_msg; ++i)
4024 msgs_buffer[i].rank = split_ranks[i];
4032 redist =
xmalloc(num_src_fields *
sizeof(*redist));
4033 if (num_src_fields == 1) {
4035 xt_redist_single_array_base_custom_new(
4036 nsend, nrecv, send_msgs, recv_msgs, halo_comm,
4039 for (
size_t field_idx = 0; field_idx < num_src_fields; ++field_idx) {
4041 xt_redist_single_array_base_custom_new(
4042 nsends[field_idx], nrecvs[field_idx],
4043 send_msgs, recv_msgs, halo_comm,
4045 send_msgs += nsends[field_idx];
4046 recv_msgs += nrecvs[field_idx];
4051 yac_mpi_call(MPI_Comm_split(comm, 0, 0, &halo_comm), comm);
4056 free(exchange_buffer);
4071 if (ret)
return ret;
4076 if (ret)
return ret;
4085 const void * a,
const void * b) {
4094 for (
size_t i = 0; i <
count; ++i) {
4097 if (ret)
return ret;
4100 if (ret)
return ret;
4106 const void * a,
const void * b) {
4119 return (a_orig_pos > b_orig_pos) - (a_orig_pos < b_orig_pos);
4129 Xt_config redist_config) {
4134 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4136 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
4138 for (
size_t i = 0; i <
count; ++i) {
4139 int curr_count = point_infos[i].
count;
4142 (&(point_infos[i].
data.single)):(point_infos[i].
data.
multi);
4143 YAC_ASSERT(curr_count >= 1,
"no owner found for global id")
4144 for (
int j = 0; j < curr_count; ++j)
4145 sendcounts[curr_point_infos[j].
rank]++;
4149 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4152 sdispls[comm_size] + sendcounts[comm_size - 1];
4154 rdispls[comm_size - 1] + recvcounts[comm_size - 1];
4156 int * exchange_buffer =
4157 xmalloc((2 * send_count + recv_count) *
sizeof(*exchange_buffer));
4159 int * reorder_idx = exchange_buffer + send_count;
4160 int *
recv_buffer = exchange_buffer + 2 * send_count;
4163 for (
size_t i = 0; i < count; ++i) {
4164 int curr_count = point_infos[i].
count;
4167 (&(point_infos[i].
data.single)):(point_infos[i].
data.
multi);
4168 for (
int j = 0; j < curr_count; ++j) {
4169 size_t pos = sdispls[curr_point_infos[j].
rank + 1]++;
4170 size_t orig_pos = curr_point_infos[j].orig_pos;
4173 reorder_idx[pos] = i;
4178 yac_alltoallv_int_p2p(
4180 __func__, __LINE__);
4184 for (
int i = 0; i < comm_size; ++i) {
4185 if (sendcounts[i] > 0) nsend++;
4186 if (recvcounts[i] > 0) nrecv++;
4189 struct Xt_redist_msg * send_msgs =
xmalloc(nsend *
sizeof(*send_msgs));
4190 struct Xt_redist_msg * recv_msgs =
xmalloc(nrecv *
sizeof(*send_msgs));
4192 for (
int i = 0, nsend = 0, nrecv = 0; i < comm_size; ++i) {
4193 if (sendcounts[i] > 0) {
4194 send_msgs[nsend].rank = i;
4195 send_msgs[nsend].datatype =
4196 xt_mpi_generate_datatype(
4197 reorder_idx + sdispls[i], sendcounts[i], MPI_DOUBLE, comm);
4200 if (recvcounts[i] > 0) {
4201 recv_msgs[nrecv].rank = i;
4202 recv_msgs[nrecv].datatype =
4203 xt_mpi_generate_datatype(
4204 recv_buffer + rdispls[i], recvcounts[i], MPI_DOUBLE, comm);
4211 xt_redist_single_array_base_custom_new(
4212 nsend, nrecv, send_msgs, recv_msgs, comm, redist_config);
4214 free(exchange_buffer);
4225 size_t num_src_fields,
size_t tgt_count,
4227 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
4230 void (*interp_add_wsum_mf_at_src)(
4233 void (*interp_add_wsum_mf_at_tgt)(
4235 size_t *,
size_t *,
size_t), Xt_config redist_config) {
4240 remote_src_points, halo_size, num_src_fields, comm, redist_config);
4247 xmalloc(tgt_count *
sizeof(*tgt_infos));
4248 for (
size_t i = 0; i < tgt_count; ++i)
4249 tgt_infos[i] = tgt_stencils[i].tgt.data;
4252 tgt_infos, tgt_count, comm, redist_config);
4255 interp_add_wsum_mf_at_src(
4256 interp, halo_redists, tgt_count, num_src_per_tgt, weights,
4257 src_field_idx, src_idx, num_src_fields, result_redist);
4259 if (result_redist != NULL) xt_redist_delete(result_redist);
4263 size_t * tgt_orig_pos =
xmalloc(tgt_count *
sizeof(*tgt_orig_pos));
4264 for (
size_t i = 0; i < tgt_count; ++i) {
4266 tgt_stencils[i].tgt.data.count == 1,
4267 "currently unsupported target point distribution")
4269 (size_t)(tgt_stencils[i].tgt.data.data.single.orig_pos);
4272 interp_add_wsum_mf_at_tgt(
4273 interp, halo_redists, tgt_orig_pos, tgt_count,
4274 num_src_per_tgt, weights, src_field_idx, src_idx, num_src_fields);
4279 if (halo_redists != NULL) {
4280 for (
size_t i = 0; i < num_src_fields; ++i)
4281 xt_redist_delete(halo_redists[i]);
4288 size_t tgt_count,
size_t * num_src_per_tgt,
double * weights,
4289 size_t * src_field_idx,
size_t * src_idx,
4290 size_t num_src_fields,
Xt_redist result_redist) {
4295 interp, halo_redists, tgt_count, num_src_per_tgt, src_field_idx,
4296 src_idx, num_src_fields, result_redist);
4301 size_t * tgt_pos,
size_t tgt_count,
size_t * num_src_per_tgt,
4302 double * weights,
size_t * src_field_idx,
size_t * src_idx,
4303 size_t num_src_fields) {
4308 interp, src_redists, tgt_pos, tgt_count, num_src_per_tgt,
4309 src_field_idx, src_idx, num_src_fields);
4314 size_t num_src_fields,
size_t tgt_count,
4316 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
4318 Xt_config redist_config) {
4321 remote_src_points, halo_size, num_src_fields, tgt_count, tgt_stencils,
4322 num_src_per_tgt, weights, src_idx, src_field_idx, comm, reorder,
4330 size_t num_src_fields,
size_t tgt_count,
4332 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
4334 Xt_config redist_config) {
4339 remote_src_points, halo_size, 1, tgt_count, tgt_stencils, num_src_per_tgt,
4340 weights, src_idx, src_field_idx, comm, reorder, interp, redist_config);
4345 size_t num_src_fields,
size_t tgt_count,
4347 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
4349 Xt_config redist_config) {
4352 remote_src_points, halo_size, num_src_fields, tgt_count, tgt_stencils,
4353 num_src_per_tgt, weights, src_idx, src_field_idx, comm, reorder,
4361 size_t num_src_fields,
size_t tgt_count,
4363 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
4365 Xt_config redist_config) {
4370 remote_src_points, halo_size, 1, tgt_count, tgt_stencils, num_src_per_tgt,
4371 weights, src_idx, src_field_idx, comm, reorder, interp, redist_config);
4378 void (*interp_add_w_sum_mf)(
4382 Xt_config), Xt_config redist_config) {
4392 "invalid reorder type")
4399 size_t wsum_mf_count = new_wsum_mf_stencils_data->
count;
4401 new_wsum_mf_stencils_data->
data;
4404 size_t total_num_links = 0, total_num_remote_weights = 0;
4405 for (
size_t i = 0; i < wsum_mf_count; ++i) {
4406 size_t curr_stencil_size = wsum_mf_stencils[i].
count;
4407 total_num_links += curr_stencil_size;
4408 for (
size_t j = 0; j < curr_stencil_size; ++j)
4409 if (wsum_mf_stencils[i].
data[j].
src.rank != comm_rank)
4410 ++total_num_remote_weights;
4415 xmalloc(total_num_remote_weights *
sizeof(*remote_src_points));
4416 size_t num_src_fields = 0;
4417 for (
size_t i = 0, k = 0; i < wsum_mf_count; ++i) {
4418 size_t curr_stencil_size = wsum_mf_stencils[i].
count;
4420 wsum_mf_stencils[i].
data;
4421 for (
size_t j = 0; j < curr_stencil_size; ++j) {
4423 if (curr_src_field_idx >= num_src_fields)
4424 num_src_fields = curr_src_field_idx + 1;
4425 if (curr_weights[j].
src.rank != comm_rank) {
4426 remote_src_points[k].
data = curr_weights[j].
src;
4427 remote_src_points[k].
field_idx = curr_src_field_idx;
4435 MPI_IN_PLACE, &num_src_fields, 1,
YAC_MPI_SIZE_T, MPI_MAX, comm), comm);
4439 qsort(remote_src_points, total_num_remote_weights,
sizeof(*remote_src_points),
4446 size_t prev_field_idx;
4448 if (total_num_remote_weights > 0) {
4449 prev_remote_src_point = &(remote_src_points[0].
data);
4450 prev_field_idx = remote_src_points[0].
field_idx;
4453 prev_field_idx = SIZE_MAX;
4456 for (
size_t i = 0; i < total_num_remote_weights; ++i) {
4458 &(remote_src_points[i].
data);
4459 size_t curr_field_idx = remote_src_points[i].
field_idx;
4461 prev_remote_src_point, curr_remote_src_point) ||
4462 (prev_field_idx != curr_field_idx)) {
4463 prev_remote_src_point = curr_remote_src_point;
4464 prev_field_idx = curr_field_idx;
4465 remote_src_points[halo_size].
data = *curr_remote_src_point;
4466 remote_src_points[halo_size].
field_idx = curr_field_idx;
4470 wsum_mf_stencils + remote_src_points[i].
reorder_idx;
4471 size_t curr_stencil_size = curr_stencil->
count;
4472 for (
size_t j = 0; j < curr_stencil_size; ++j) {
4474 &(curr_stencil->
data[j].
src), curr_remote_src_point)) &&
4484 qsort(wsum_mf_stencils, wsum_mf_count,
sizeof(*wsum_mf_stencils),
4489 size_t * num_src_per_tgt =
xmalloc(wsum_mf_count *
sizeof(*num_src_per_tgt));
4490 double * weights =
xmalloc(total_num_links *
sizeof(*weights));
4491 size_t * src_idx =
xmalloc(total_num_links *
sizeof(*src_idx));
4492 size_t * src_field_idx =
xmalloc(total_num_links *
sizeof(*src_field_idx));
4495 for (
size_t i = 0, k = 0; i < wsum_mf_count; ++i) {
4496 size_t curr_stencil_size = wsum_mf_stencils[i].
count;
4498 wsum_mf_stencils[i].
data;
4499 num_src_per_tgt[i] = curr_stencil_size;
4500 for (
size_t j = 0; j < curr_stencil_size; ++j, ++k){
4501 weights[k] = curr_weights[j].
weight;
4508 interp_add_w_sum_mf(
4509 remote_src_points, halo_size, num_src_fields, wsum_mf_count,
4510 wsum_mf_stencils, num_src_per_tgt, weights, src_idx,
src_field_idx,
4511 comm, reorder, interp, redist_config);
4513 for (
size_t i = 0; i < new_wsum_mf_stencils_data->
count; ++i)
4515 free(new_wsum_mf_stencils_data->
data);
4516 free(new_wsum_mf_stencils_data);
4518 free(remote_src_points);
4522 free(num_src_per_tgt);
4528 void (*interp_add_w_sum_mf)(
4531 size_t *, MPI_Comm,
void *,
4532 Xt_config), Xt_config redist_config) {
4541 size_t wsum_mf_count = new_wsum_mf_stencils_data->
count;
4543 new_wsum_mf_stencils_data->
data;
4546 size_t total_num_links = 0;
4547 for (
size_t i = 0; i < wsum_mf_count; ++i)
4548 total_num_links += wsum_mf_stencils[i].
count;
4552 xmalloc(total_num_links *
sizeof(*src_points));
4553 size_t num_src_fields = 0;
4554 for (
size_t i = 0, k = 0; i < wsum_mf_count; ++i) {
4555 size_t curr_stencil_size = wsum_mf_stencils[i].
count;
4557 wsum_mf_stencils[i].
data;
4558 for (
size_t j = 0; j < curr_stencil_size; ++j, ++k) {
4560 if (curr_src_field_idx >= num_src_fields)
4561 num_src_fields = curr_src_field_idx + 1;
4562 src_points[k].data = curr_weights[j].
src;
4563 src_points[k].field_idx = curr_src_field_idx;
4564 src_points[k].reorder_idx = i;
4569 MPI_IN_PLACE, &num_src_fields, 1,
YAC_MPI_SIZE_T, MPI_MAX, comm), comm);
4573 qsort(src_points, total_num_links,
sizeof(*src_points),
4580 size_t prev_field_idx;
4581 size_t num_src_points = 0;
4582 size_t src_field_buffer_size[num_src_fields];
4584 src_field_buffer_size, 0,
4585 num_src_fields *
sizeof(src_field_buffer_size[0]));
4587 if (total_num_links > 0) {
4588 prev_src_point = &(src_points[0].data);
4589 prev_field_idx = src_points[0].field_idx;
4590 src_field_buffer_size[src_points[0].field_idx] = 1;
4593 for (
size_t i = 0; i < total_num_links; ++i) {
4595 size_t curr_field_idx = src_points[i].field_idx;
4597 (prev_field_idx != curr_field_idx)) {
4598 prev_src_point = curr_src_point;
4599 prev_field_idx = curr_field_idx;
4600 if (num_src_points != i) {
4601 src_points[num_src_points].data = *curr_src_point;
4602 src_points[num_src_points].field_idx = curr_field_idx;
4604 src_field_buffer_size[curr_field_idx]++;
4608 wsum_mf_stencils + src_points[i].reorder_idx;
4609 size_t curr_stencil_size = curr_stencil->
count;
4610 for (
size_t j = 0; j < curr_stencil_size; ++j) {
4612 &(curr_stencil->
data[j].
src), curr_src_point)) &&
4616 src_field_buffer_size[curr_field_idx] - 1;
4622 qsort(wsum_mf_stencils, wsum_mf_count,
sizeof(*wsum_mf_stencils),
4625 size_t * num_src_per_tgt =
xmalloc(wsum_mf_count *
sizeof(*num_src_per_tgt));
4626 double * weights =
xmalloc(total_num_links *
sizeof(*weights));
4627 size_t * src_idx =
xmalloc(total_num_links *
sizeof(*src_idx));
4628 size_t * src_field_idx =
xmalloc(total_num_links *
sizeof(*src_field_idx));
4631 for (
size_t i = 0, k = 0; i < wsum_mf_count; ++i) {
4632 size_t curr_stencil_size = wsum_mf_stencils[i].
count;
4634 wsum_mf_stencils[i].
data;
4635 num_src_per_tgt[i] = curr_stencil_size;
4636 for (
size_t j = 0; j < curr_stencil_size; ++j, ++k){
4637 weights[k] = curr_weights[j].
weight;
4644 interp_add_w_sum_mf(
4645 src_points, num_src_points, num_src_fields, wsum_mf_count,
4646 wsum_mf_stencils, num_src_per_tgt, weights, src_idx,
src_field_idx,
4647 comm, interp, redist_config);
4649 for (
size_t i = 0; i < new_wsum_mf_stencils_data->
count; ++i)
4651 free(new_wsum_mf_stencils_data->
data);
4652 free(new_wsum_mf_stencils_data);
4658 free(num_src_per_tgt);
4668 char const * yaxt_exchanger_name, MPI_Comm comm) {
4670 Xt_config redist_config = xt_config_new();
4673 char * env_exchanger_name = NULL;
4674 if (yaxt_exchanger_name == NULL) {
4681 size_t exchanger_name_len = 0;
4686 exchanger_name_len =
4687 ((env_exchanger_name != NULL) && (env_exchanger_name[0] !=
'\0'))?
4688 strlen(env_exchanger_name):0;
4694 MPI_Bcast(&exchanger_name_len, 1,
YAC_MPI_SIZE_T, 0, comm), comm);
4696 if (exchanger_name_len > 0) {
4699 env_exchanger_name =
xstrdup(env_exchanger_name);
4701 env_exchanger_name =
4702 xmalloc((exchanger_name_len + 1) *
sizeof(*env_exchanger_name));
4707 env_exchanger_name, (
int)(exchanger_name_len + 1), MPI_CHAR, 0, comm),
4710 yaxt_exchanger_name = env_exchanger_name;
4714 if (yaxt_exchanger_name != NULL) {
4717 int exchanger_id = xt_exchanger_id_by_name(yaxt_exchanger_name);
4719 exchanger_id >= 0,
"invalid yaxt exchanger name \"%s\"",
4720 yaxt_exchanger_name);
4721 xt_config_set_exchange_method(redist_config, exchanger_id);
4724 free(env_exchanger_name);
4726 return redist_config;
4734 double scaling_factor,
double scaling_summand,
4740 scaling_factor, scaling_summand);
4742 MPI_Comm comm = weights->comm;
4745 int * flag_buffer =
xmalloc(2 * (
size_t)comm_size *
sizeof(*flag_buffer));
4746 int * rank_is_source = flag_buffer;
4747 int * rank_is_target = flag_buffer + comm_size;
4749 MPI_Allgather(&
is_source, 1, MPI_INT, rank_is_source, 1, MPI_INT, comm),
4752 MPI_Allgather(&
is_target, 1, MPI_INT, rank_is_target, 1, MPI_INT, comm),
4758 qsort(weights->stencils, weights->stencils_size,
sizeof(*(weights->stencils)),
4765 memset(&(local_stencil_counts[0]), 0,
sizeof(local_stencil_counts));
4766 for (
size_t i = 0; i < weights->stencils_size; ++i)
4767 local_stencil_counts[(
int)(weights->stencils[i].type)]++;
4770 stencils_offsets[i] = accu;
4771 accu += local_stencil_counts[i];
4779 local_stencil_counts, global_stencil_counts,
4783 size_t local_collection_size =
4785 size_t max_collection_size;
4789 MPI_MAX, comm), comm);
4791 (
size_t)max_collection_size == local_collection_size,
4792 "mismatching collection sizes")
4795 if (global_stencil_counts[
FIXED] > 0)
4797 weights->comm, local_stencil_counts[
FIXED],
4798 weights->stencils + stencils_offsets[
FIXED],
4801 if (global_stencil_counts[
DIRECT] > 0)
4803 weights->comm, local_stencil_counts[
DIRECT],
4805 redist_config, rank_is_source, rank_is_target);
4807 if (global_stencil_counts[
SUM] > 0) {
4811 weights->stencils + stencils_offsets[
SUM],
4812 (
size_t)(local_stencil_counts[
SUM]),
SUM,
4813 rank_is_source, rank_is_target);
4815 weights->comm, wsum_stencils, interp, reorder,
4817 for (
size_t i = 0; i < wsum_stencils->
count; ++i)
4819 free(wsum_stencils->
data);
4820 free(wsum_stencils);
4827 weights->stencils + stencils_offsets[
WEIGHT_SUM],
4829 rank_is_source, rank_is_target);
4831 weights->comm, wsum_stencils, interp, reorder,
4833 for (
size_t i = 0; i < wsum_stencils->
count; ++i)
4835 free(wsum_stencils->
data);
4836 free(wsum_stencils);
4839 if (global_stencil_counts[
DIRECT_MF] > 0)
4841 weights->comm, local_stencil_counts[
DIRECT_MF],
4842 weights->stencils + stencils_offsets[
DIRECT_MF],
4844 rank_is_source, rank_is_target);
4846 if (global_stencil_counts[
SUM_MF] > 0) {
4850 weights->stencils + stencils_offsets[
SUM_MF],
4852 rank_is_source, rank_is_target);
4854 weights->comm, sum_mf_stencils, interp, reorder,
4856 for (
size_t i = 0; i < sum_mf_stencils->
count; ++i)
4858 free(sum_mf_stencils->
data);
4859 free(sum_mf_stencils);
4868 rank_is_source, rank_is_target);
4870 weights->comm, wsum_mf_stencils, interp, reorder,
4872 for (
size_t i = 0; i < wsum_mf_stencils->
count; ++i)
4874 free(wsum_mf_stencils->
data);
4875 free(wsum_mf_stencils);
4880 xt_config_delete(redist_config);
4889 double scaling_factor,
double scaling_summand,
4898 scaling_factor, scaling_summand, yaxt_exchanger_name,
4903 return interpolation;
4924 struct yac_src_field_exchange_data * src_field_exchange_data,
4925 size_t num_src_fields, MPI_Comm comm,
4926 Xt_config redist_config) {
4931 size_t nsends[num_src_fields], nrecvs[num_src_fields];
4932 int max_recv_buffer_size = 0;
4933 for (
size_t i = 0; i < num_src_fields; ++i) {
4934 nsends[i] = src_field_exchange_data[i].send.num_msg;
4935 nrecvs[i] = src_field_exchange_data[i].recv.num_msg;
4936 for (
size_t j = 0; j < src_field_exchange_data[i].recv.num_msg; ++j) {
4937 if (max_recv_buffer_size < src_field_exchange_data[i].recv.msg[j].count)
4938 max_recv_buffer_size = src_field_exchange_data[i].recv.msg[j].count;
4942 size_t nsend = 0, nrecv = 0;
4943 size_t send_offsets[num_src_fields];
4944 size_t recv_offsets[num_src_fields];
4945 for (
size_t i = 0; i < num_src_fields; ++i) {
4946 send_offsets[i] = nsend;
4947 recv_offsets[i] = nrecv;
4952 size_t total_num_msg = nsend + nrecv;
4954 struct Xt_redist_msg * msgs_buffer =
4955 xmalloc(total_num_msg *
sizeof(*msgs_buffer));
4956 struct Xt_redist_msg * send_msgs = msgs_buffer;
4957 struct Xt_redist_msg * recv_msgs = msgs_buffer + nsend;
4960 xmalloc((
size_t)max_recv_buffer_size *
sizeof(*pos_buffer));
4963 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
4966 for (
size_t send_idx = 0;
4967 send_idx < src_field_exchange_data[src_field_idx].send.num_msg;
4969 send_msgs[send_offsets[src_field_idx]].rank =
4970 src_field_exchange_data[src_field_idx].send.msg[send_idx].rank;
4971 send_msgs[send_offsets[src_field_idx]].datatype =
4972 xt_mpi_generate_datatype(
4973 src_field_exchange_data[src_field_idx].send.msg[send_idx].pos,
4974 src_field_exchange_data[src_field_idx].send.msg[send_idx].count,
4976 send_offsets[src_field_idx]++;
4979 for (
size_t recv_idx = 0;
4980 recv_idx < src_field_exchange_data[src_field_idx].recv.num_msg;
4984 i < src_field_exchange_data[src_field_idx].recv.msg[recv_idx].count;
4987 src_field_exchange_data[src_field_idx].recv.msg[recv_idx].pos[i];
4989 recv_msgs[recv_offsets[src_field_idx]].rank =
4990 src_field_exchange_data[src_field_idx].recv.msg[recv_idx].rank;
4991 recv_msgs[recv_offsets[src_field_idx]].datatype =
4992 xt_mpi_generate_datatype(pos_buffer, count, MPI_DOUBLE, comm);
4993 recv_offsets[src_field_idx]++;
5004 if (total_num_msg > 0) {
5011 xmalloc(2 * total_num_msg *
sizeof(*rank_buffer));
5012 int * orig_ranks = rank_buffer;
5013 int * split_ranks = rank_buffer + total_num_msg;
5015 for (
size_t i = 0; i < total_num_msg; ++i)
5016 orig_ranks[i] = msgs_buffer[i].rank;
5018 MPI_Group orig_group, split_group;
5025 MPI_Group_translate_ranks(orig_group, total_num_msg, orig_ranks,
5028 for (
size_t i = 0; i < total_num_msg; ++i)
5029 msgs_buffer[i].rank = split_ranks[i];
5037 redists =
xmalloc(num_src_fields *
sizeof(*redists));
5038 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields;
5040 redists[src_field_idx] =
5041 xt_redist_single_array_base_custom_new(
5042 nsends[src_field_idx], nrecvs[src_field_idx],
5043 send_msgs, recv_msgs,
split_comm, redist_config);
5044 send_msgs += nsends[src_field_idx];
5045 recv_msgs += nrecvs[src_field_idx];
5060 double frac_mask_fallback_value,
double scaling_factor,
5061 double scaling_summand,
5084 struct yac_src_field_exchange_data * src_field_exchange_data,
5085 size_t num_src_fields) {
5087 for (
size_t i = 0; i < num_src_fields; ++i) {
5088 for (
size_t j = 0; j < src_field_exchange_data[i].send.num_msg; ++j)
5089 free(src_field_exchange_data[i].send.msg[j].pos);
5090 free(src_field_exchange_data[i].send.msg);
5091 for (
size_t j = 0; j < src_field_exchange_data[i].recv.num_msg; ++j)
5092 free(src_field_exchange_data[i].recv.msg[j].pos);
5093 free(src_field_exchange_data[i].recv.msg);
5096 free(src_field_exchange_data);
5101 size_t num_src_fields,
size_t tgt_count,
5103 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
5115 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
5117 num_src_fields, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
5118 size_t * size_t_buffer =
5119 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
5120 size_t * total_sendcounts = size_t_buffer + 0 * comm_size;
5121 size_t * total_recvcounts = size_t_buffer + 1 * comm_size;
5122 size_t * total_sdispls = size_t_buffer + 2 * comm_size;
5123 size_t * total_rdispls = size_t_buffer + 3 * comm_size;
5125 for (
size_t i = 0; i < num_src_points; ++i)
5126 sendcounts[remote_src_points[i].
data.rank * num_src_fields +
5130 num_src_fields, sendcounts, recvcounts, sdispls, rdispls, comm);
5132 size_t total_sendcount = 0, total_recvcount = 0;
5133 for (
int i = 0; i < comm_size; ++i) {
5134 total_sdispls[i] = total_sendcount;
5135 total_rdispls[i] = total_recvcount;
5136 total_sendcounts[i] = 0;
5137 total_recvcounts[i] = 0;
5138 for (
size_t j = 0; j < num_src_fields; ++j) {
5139 total_sendcounts[i] += sendcounts[num_src_fields * i + j];
5140 total_recvcounts[i] += recvcounts[num_src_fields * i + j];
5142 total_sendcount += total_sendcounts[i];
5143 total_recvcount += total_recvcounts[i];
5146 size_t recv_count = total_recvcounts[comm_size - 1] +
5147 total_rdispls[comm_size - 1];
5149 size_t * exchange_buffer =
5150 xmalloc((2 * num_src_points + recv_count) *
sizeof(*exchange_buffer));
5152 size_t * reorder_idx = exchange_buffer + num_src_points;
5153 size_t *
recv_buffer = exchange_buffer + 2 * num_src_points;
5156 size_t src_field_buffer_size[num_src_fields];
5158 src_field_buffer_size, 0,
5159 num_src_fields *
sizeof(src_field_buffer_size[0]));
5160 for (
size_t i = 0; i < num_src_points; ++i) {
5161 size_t curr_src_field_idx = (size_t)(remote_src_points[i].field_idx);
5162 size_t pos = sdispls[(size_t)(remote_src_points[i].
data.rank) * num_src_fields +
5163 curr_src_field_idx + 1]++;
5165 reorder_idx[pos] = src_field_buffer_size[curr_src_field_idx]++;
5169 yac_alltoallv_size_t_p2p(
5171 recv_buffer, total_recvcounts, total_rdispls, comm,
5172 "interpolation_raw_add_w_sum_mf", __LINE__);
5174 free(size_t_buffer);
5182 free(exchange_buffer);
5184 size_t * tgt_idx =
xmalloc(tgt_count *
sizeof(*tgt_idx));
5186 for (
size_t i = 0; i < tgt_count; ++i) {
5188 tgt_stencils[i].tgt.data.count == 1,
5189 "currently unsupported target point distribution")
5190 tgt_idx[i] = (size_t)(tgt_stencils[i].tgt.data.data.single.orig_pos);
5195 tgt_idx, num_src_per_tgt, weights, src_field_idx, src_idx,
5196 src_field_buffer_size);
5203 size_t num_src_fields,
size_t tgt_count,
5205 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
5206 void * interp_raw, Xt_config redist_config) {
5209 src_points, num_src_points, num_src_fields, tgt_count, tgt_stencils,
5210 num_src_per_tgt, weights, src_idx, src_field_idx, comm,
5216 size_t num_src_fields,
size_t tgt_count,
5218 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
5219 void * interp_raw, Xt_config redist_config) {
5224 src_points, num_src_points, num_src_fields, tgt_count, tgt_stencils,
5225 num_src_per_tgt, NULL, src_idx, src_field_idx, comm,
5231 size_t num_src_fields,
size_t tgt_count,
5233 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
5234 void * interp_raw, Xt_config redist_config) {
5239 src_points, num_src_points, num_src_fields, tgt_count, tgt_stencils,
5240 num_src_per_tgt, weights, src_idx, NULL, comm,
5246 size_t num_src_fields,
size_t tgt_count,
5248 double * weights,
size_t * src_idx,
size_t * src_field_idx, MPI_Comm comm,
5249 void * interp_raw, Xt_config redist_config) {
5255 src_points, num_src_points, num_src_fields, tgt_count, tgt_stencils,
5256 num_src_per_tgt, NULL, src_idx, NULL, comm,
5263 double frac_mask_fallback_value,
5264 double scaling_factor,
double scaling_summand,
5265 char const * yaxt_exchanger_name,
5268 int is_source,
int is_target) {
5272 "non-contiguous selections are not supported for raw interpolation");
5278 frac_mask_fallback_value, scaling_factor, scaling_summand,
5281 MPI_Comm comm = weights->comm;
5284 int * flag_buffer =
xmalloc(2 * (
size_t)comm_size *
sizeof(*flag_buffer));
5285 int * rank_is_source = flag_buffer;
5286 int * rank_is_target = flag_buffer + comm_size;
5288 MPI_Allgather(&is_source, 1, MPI_INT, rank_is_source, 1, MPI_INT, comm),
5291 MPI_Allgather(&is_target, 1, MPI_INT, rank_is_target, 1, MPI_INT, comm),
5297 qsort(weights->stencils, weights->stencils_size,
sizeof(*(weights->stencils)),
5304 memset(&(local_stencil_counts[0]), 0,
sizeof(local_stencil_counts));
5305 for (
size_t i = 0; i < weights->stencils_size; ++i)
5306 local_stencil_counts[(
int)(weights->stencils[i].type)]++;
5309 stencils_offsets[i] = accu;
5310 accu += local_stencil_counts[i];
5318 local_stencil_counts, global_stencil_counts,
5322 size_t local_collection_size =
5324 size_t max_collection_size;
5328 MPI_MAX, comm), comm);
5330 (
size_t)max_collection_size == local_collection_size,
5331 "mismatching collection sizes")
5334 if (global_stencil_counts[
FIXED] > 0)
5336 weights->comm, local_stencil_counts[
FIXED],
5337 weights->stencils + stencils_offsets[
FIXED],
5340 if (global_stencil_counts[
DIRECT] > 0)
5342 weights->comm, local_stencil_counts[
DIRECT],
5343 weights->stencils + stencils_offsets[
DIRECT],
5345 redist_config, rank_is_source, rank_is_target);
5347 if (global_stencil_counts[
SUM] > 0) {
5351 weights->stencils + stencils_offsets[
SUM],
5352 (
size_t)(local_stencil_counts[
SUM]),
SUM,
5353 rank_is_source, rank_is_target);
5355 weights->comm, wsum_stencils, (
void*)&interpolation_raw,
5357 for (
size_t i = 0; i < wsum_stencils->
count; ++i)
5359 free(wsum_stencils->
data);
5360 free(wsum_stencils);
5367 weights->stencils + stencils_offsets[
WEIGHT_SUM],
5369 rank_is_source, rank_is_target);
5371 weights->comm, wsum_stencils, (
void*)&interpolation_raw,
5373 for (
size_t i = 0; i < wsum_stencils->
count; ++i)
5375 free(wsum_stencils->
data);
5376 free(wsum_stencils);
5379 if (global_stencil_counts[
DIRECT_MF] > 0)
5381 weights->comm, local_stencil_counts[
DIRECT_MF],
5382 weights->stencils + stencils_offsets[
DIRECT_MF],
5384 rank_is_source, rank_is_target);
5386 if (global_stencil_counts[
SUM_MF] > 0) {
5390 weights->stencils + stencils_offsets[
SUM_MF],
5392 rank_is_source, rank_is_target);
5394 weights->comm, sum_mf_stencils, (
void*)&interpolation_raw,
5396 for (
size_t i = 0; i < sum_mf_stencils->
count; ++i)
5398 free(sum_mf_stencils->
data);
5399 free(sum_mf_stencils);
5408 rank_is_source, rank_is_target);
5410 weights->comm, wsum_mf_stencils, (
void*)&interpolation_raw,
5412 for (
size_t i = 0; i < wsum_mf_stencils->
count; ++i)
5414 free(wsum_mf_stencils->
data);
5415 free(wsum_mf_stencils);
5426 *interpolation_exchange =
5430 with_frac_mask,
"yac_interp_weights_get_interpolation_raw_");
5433 if (redists != NULL) {
5436 xt_redist_delete(redists[i]);
5444 xt_config_delete(redist_config);
5450 double scaling_factor,
double scaling_summand,
5451 char const * yaxt_exchanger_name,
5454 int is_source,
int is_target) {
5460 weights, collection_selection, frac_mask_fallback_value,
5461 scaling_factor, scaling_summand, yaxt_exchanger_name,
5472 int is_source,
int is_target) {
5487 double scaling_factor,
double scaling_summand,
5493 "reorder type must be of YAC_MAPPING_ON_SRC/YAC_MAPPING_ON_TGT");
5499 scaling_factor, scaling_summand,
5500 ((yaxt_exchanger_name != NULL) && (yaxt_exchanger_name[0] !=
'\0'))?
5513 for (
size_t i = 0 ; i < count; ++i) {
5522 (stencils[i].
type ==
FIXED),
"invalid stencil type")
5523 switch(stencils[i].
type) {
5533 free(stencils[i].
data.weight_sum.weights);
5540 free(stencils[i].
data.sum_mf.field_indices);
5544 free(stencils[i].
data.weight_sum_mf.weights);
5545 free(stencils[i].
data.weight_sum_mf.field_indices);
5556#ifdef YAC_NETCDF_ENABLED
5559 double const * _a = (
double const *)a;
5560 double const * _b = (
double const *)b;
5561 if (isnan(*_a) || isnan(*_b))
5562 return isnan(*_a) - isnan(*_b);
5564 return (*_a > *_b) - (*_a < *_b);
5572 size_t num_fixed_values,
double * fixed_values,
5573 size_t * num_tgt_per_fixed_value,
size_t num_links,
5574 size_t num_weights_per_link,
size_t num_src_fields,
5575 size_t * num_links_per_src_field,
5577 size_t src_grid_size,
size_t tgt_grid_size) {
5582 yac_nc_create(filename, NC_CLOBBER | NC_64BIT_OFFSET, &ncid);
5584 int dim_weight_id[8];
5587 if (num_links > 0) {
5588 YAC_HANDLE_ERROR(nc_def_dim(ncid,
"num_links", num_links, &dim_weight_id[0]));
5590 num_weights_per_link > 0,
5591 "number of links is %zu but number of weights per link is zero for "
5592 "weight file %s", num_links, filename)
5594 nc_def_dim(ncid,
"num_wgts", num_weights_per_link, &dim_weight_id[1]));
5597 num_src_fields > 0,
"number of source fields is zero for weight file %s",
5600 nc_def_dim(ncid,
"num_src_fields", num_src_fields, &dim_weight_id[2]));
5605 if (num_fixed_values > 0) {
5608 ncid,
"num_fixed_values", num_fixed_values, &dim_weight_id[4]));
5609 size_t num_fixed_dst = 0;
5610 for (
size_t i = 0; i < num_fixed_values; ++i)
5611 num_fixed_dst += num_tgt_per_fixed_value[i];
5613 num_fixed_dst > 0,
"number of fixed values is %zu but number "
5614 "of fixed destination points is zero for weight file %s",
5615 num_fixed_values, filename)
5617 nc_def_dim(ncid,
"num_fixed_dst", num_fixed_dst, &dim_weight_id[5]));
5620 if (src_grid_size > 0)
5622 nc_def_dim(ncid,
"src_grid_size", src_grid_size, &dim_weight_id[6]));
5624 if (tgt_grid_size > 0)
5626 nc_def_dim(ncid,
"dst_grid_size", tgt_grid_size, &dim_weight_id[7]));
5628 int var_src_add_id, var_dst_add_id, var_weight_id, var_num_links_id,
5629 src_var_locs_id, tgt_var_loc_id, var_fixed_values_id,
5630 var_num_dst_per_fixed_value_id, var_dst_add_fixed_id;
5633 if (num_links > 0) {
5636 ncid,
"src_address", NC_INT, 1, dim_weight_id, &var_src_add_id));
5639 ncid,
"dst_address", NC_INT, 1, dim_weight_id, &var_dst_add_id));
5642 ncid,
"remap_matrix", NC_DOUBLE, 2, dim_weight_id, &var_weight_id));
5644 nc_def_var(ncid,
"num_links_per_src_field", NC_INT, 1,
5645 &dim_weight_id[2], &var_num_links_id));
5649 ncid,
"src_locations", NC_CHAR, 2, &dim_weight_id[2], &src_var_locs_id));
5652 ncid,
"dst_location", NC_CHAR, 1, &dim_weight_id[3], &tgt_var_loc_id));
5653 if (num_fixed_values > 0) {
5655 nc_def_var(ncid,
"fixed_values", NC_DOUBLE, 1, &dim_weight_id[4],
5656 &var_fixed_values_id));
5658 nc_def_var(ncid,
"num_dst_per_fixed_value", NC_INT, 1, &dim_weight_id[4],
5659 &var_num_dst_per_fixed_value_id));
5661 nc_def_var(ncid,
"dst_address_fixed", NC_INT, 1, &dim_weight_id[5],
5662 &var_dst_add_fixed_id));
5667 nc_put_att_text(ncid, NC_GLOBAL,
"version",
5671 nc_put_att_text(ncid, NC_GLOBAL,
"src_grid_name",
5674 nc_put_att_text(ncid, NC_GLOBAL,
"dst_grid_name",
5691 if (num_links > 0) {
5692 int * num_links_per_src_field_int =
5693 xmalloc(num_src_fields *
sizeof(*num_links_per_src_field_int));
5694 for (
size_t i = 0; i < num_src_fields; ++i) {
5696 num_links_per_src_field[i] <= INT_MAX,
5697 "number of links per source field too big (not yet supported)")
5698 num_links_per_src_field_int[i] = (int)num_links_per_src_field[i];
5701 nc_put_var_int(ncid, var_num_links_id, num_links_per_src_field_int));
5702 free(num_links_per_src_field_int);
5705 for (
size_t i = 0; i < num_src_fields; ++i) {
5706 char const * loc_str =
yac_loc2str(src_locations[i]);
5707 size_t str_start[2] = {i, 0};
5708 size_t str_count[2] = {1, strlen(loc_str)};
5710 nc_put_vara_text(ncid, src_var_locs_id, str_start, str_count, loc_str));
5715 size_t str_start[1] = {0};
5716 size_t str_count[1] = {strlen(loc_str)};
5718 nc_put_vara_text(ncid, tgt_var_loc_id, str_start, str_count, loc_str));
5720 if (num_fixed_values > 0) {
5722 int * num_tgt_per_fixed_value_int =
5723 xmalloc(num_fixed_values *
sizeof(*num_tgt_per_fixed_value_int));
5724 for (
unsigned i = 0; i < num_fixed_values; ++i) {
5726 num_tgt_per_fixed_value[i] <= INT_MAX,
5727 "number of targets per fixed value is too big (not yet supported)")
5728 num_tgt_per_fixed_value_int[i] = (int)num_tgt_per_fixed_value[i];
5730 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_fixed_values_id, fixed_values));
5732 num_tgt_per_fixed_value_int));
5733 free(num_tgt_per_fixed_value_int);
5744 int ret = b_is_fixed - a_is_fixed;
5746 if (ret)
return ret;
5751 double fixed_value_a =
5753 double fixed_value_b =
5756 ret = memcmp(&fixed_value_a, &fixed_value_b,
sizeof(fixed_value_a));
5758 if (ret)
return ret;
5769 yac_int * min_tgt_global_id,
yac_int * max_tgt_global_id, MPI_Comm comm) {
5771 yac_int min_max[2] = {YAC_INT_MAX, YAC_INT_MIN};
5773 for (
size_t i = 0; i < stencils_size; ++i) {
5776 if (curr_id < min_max[0]) min_max[0] = curr_id;
5777 if (curr_id > min_max[1]) min_max[1] = curr_id;
5780 min_max[0] = YAC_INT_MAX - min_max[0];
5784 MPI_IN_PLACE, min_max, 2,
yac_int_dt, MPI_MAX, comm), comm);
5786 *min_tgt_global_id = YAC_INT_MAX - min_max[0];
5787 *max_tgt_global_id = min_max[1];
5793 int num_io_procs_int,
int * io_owner) {
5795 long long num_io_procs = (
long long)num_io_procs_int;
5796 long long id_range =
5797 MAX((
long long)(max_tgt_global_id - min_tgt_global_id),1);
5799 for (
size_t i = 0; i < stencils_size; ++i)
5801 ((
int)(
MIN(((
long long)(stencils[i].
tgt.
global_id - min_tgt_global_id) *
5802 num_io_procs) / id_range, num_io_procs - 1)));
5807 double ** fixed_values,
size_t * num_fixed_values, MPI_Comm comm) {
5812 double * local_fixed_values =
5813 xmalloc(stencil_count *
sizeof(*local_fixed_values));
5815 int * int_buffer =
xmalloc(2 * (
size_t)comm_size *
sizeof(*int_buffer));
5816 int * recvcounts = int_buffer + 0 * comm_size;
5817 int * rdispls = int_buffer + 1 * comm_size;
5819 size_t local_num_fixed = 0;
5822 for (
size_t i = 0; i < stencil_count;
5823 ++i, ++local_num_fixed) {
5827 qsort(local_fixed_values, local_num_fixed,
sizeof(*local_fixed_values),
5832 int local_num_fixed_int = (int)(local_num_fixed);
5835 &local_num_fixed_int, 1, MPI_INT, recvcounts, 1,MPI_INT, comm), comm);
5836 for (
int i = 0, accu = 0; i < comm_size; ++i) {
5838 accu += recvcounts[i];
5841 size_t num_all_fixed_values = 0;
5842 for (
int i = 0; i < comm_size; ++i)
5843 num_all_fixed_values += (
size_t)(recvcounts[i]);
5845 double * all_fixed_values =
5846 xmalloc(num_all_fixed_values *
sizeof(*all_fixed_values));
5851 local_fixed_values, local_num_fixed_int, MPI_DOUBLE,
5852 all_fixed_values, recvcounts, rdispls, MPI_DOUBLE, comm), comm);
5854 free(local_fixed_values);
5856 qsort(all_fixed_values, num_all_fixed_values,
sizeof(*all_fixed_values),
5859 *fixed_values =
xrealloc(all_fixed_values,
5860 num_all_fixed_values *
sizeof(*all_fixed_values));
5861 *num_fixed_values = num_all_fixed_values;
5882 size_t num_weights_per_link = 0;
5883 for (
size_t i = 0; i < stencil_count; ++i)
5884 num_weights_per_link =
5887 size_t num_weights_per_link_64_t = num_weights_per_link;
5891 MPI_MAX, comm), comm);
5892 num_weights_per_link = (size_t)num_weights_per_link_64_t;
5894 return num_weights_per_link;
5901 stencil->
type !=
FIXED,
"stencil type FIXED not supported by this routine")
5909 switch (stencil->
type) {
5911 case(
DIRECT):
return (src_field_idx == 0)?1:0;
5920 for (
size_t i = 0; i < stencil_size; ++i)
5928 for (
size_t i = 0; i < stencil_size; ++i)
5937 size_t num_fixed_values,
double * fixed_values,
5938 size_t * num_tgt_per_fixed_value,
5939 size_t * num_fixed_tgt,
size_t num_src_fields,
5940 size_t * num_links_per_src_field,
size_t * num_links) {
5944 for (
size_t i = 0; i < num_fixed_values; ++i) num_tgt_per_fixed_value[i] = 0;
5945 for (
size_t i = 0; i < num_src_fields; ++i) num_links_per_src_field[i] = 0;
5947 for (
size_t i = 0; i < stencil_count; ++i) {
5950 for (
size_t j = 0; j < num_fixed_values; ++j) {
5952 if (!memcmp(&curr_fixed_value, &fixed_values[j],
sizeof(curr_fixed_value))) {
5953 num_tgt_per_fixed_value[j]++;
5959 for (
size_t j = 0; j < num_src_fields; ++j) {
5960 num_links_per_src_field[j] +=
5965 for (
size_t i = 0; i < num_src_fields; ++i)
5966 *num_links += num_links_per_src_field[i];
5970 size_t num_fixed_values,
size_t * num_tgt_per_fixed_value,
5971 size_t num_src_fields,
size_t * num_links_per_src_field,
5972 size_t * fixed_offsets,
size_t * link_offsets, MPI_Comm comm) {
5977 size_t count = num_fixed_values + num_src_fields;
5978 size_t * size_t_buffer =
xmalloc(3 * count *
sizeof(*size_t_buffer));
5979 size_t * global_counts = size_t_buffer + 0 * count;
5980 size_t * local_counts = size_t_buffer + 1 * count;
5981 size_t * offsets = size_t_buffer + 2 * count;
5983 for (
size_t i = 0; i < num_fixed_values; ++i)
5984 local_counts[i] = num_tgt_per_fixed_value[i];
5985 for (
size_t i = 0; i < num_src_fields; ++i)
5986 local_counts[num_fixed_values + i] = num_links_per_src_field[i];
5989 MPI_Allreduce(local_counts, global_counts, (
int)count,
YAC_MPI_SIZE_T,
5990 MPI_SUM, comm), comm);
5992 MPI_Exscan(local_counts, offsets, (
int)count,
YAC_MPI_SIZE_T, MPI_SUM, comm),
5994 if (comm_rank == 0) memset(offsets, 0, count *
sizeof(*offsets));
5996 for (
size_t i = 0, accu = 0; i < num_fixed_values; ++i) {
5997 fixed_offsets[i] = (size_t)(offsets[i]) + accu;
5998 accu += (size_t)(global_counts[i]);
6000 for (
size_t i = 0, accu = 0; i < num_src_fields; ++i) {
6001 link_offsets[i] = (size_t)(offsets[i+num_fixed_values]) + accu;
6002 accu += (size_t)(global_counts[i+num_fixed_values]);
6004 free(size_t_buffer);
6010 (global_id < INT_MAX) && (global_id != YAC_INT_MAX),
6011 "a global id (%" YAC_INT_FMT
") cannot be converted into a address; "
6012 "too big (> %d)", global_id, INT_MAX);
6013 return (
int)global_id + 1;
6018 int * tgt_address) {
6020 for (
size_t i = 0; i < stencil_count; ++i)
6026 size_t * num_links_per_src_field,
size_t num_src_fields,
6027 int * src_address,
int * tgt_address,
double * weight) {
6029 size_t * src_field_offsets =
6030 xmalloc(2 * num_src_fields *
sizeof(*src_field_offsets));
6031 size_t * prev_src_field_offsets = src_field_offsets + num_src_fields;
6032 for (
size_t i = 0, accu = 0; i < num_src_fields; ++i) {
6033 src_field_offsets[i] = accu;
6034 accu += num_links_per_src_field[i];
6038 for (
size_t i = 0; i < stencil_count; ++i, ++curr_stencil) {
6040 memcpy(prev_src_field_offsets, src_field_offsets,
6041 num_src_fields *
sizeof(*prev_src_field_offsets));
6045 curr_stencil->
type !=
FIXED,
"this call is invalid for FIXED stencils")
6048 (curr_stencil->
type ==
SUM) ||
6053 size_t src_field_offset;
6054 switch (curr_stencil->
type) {
6057 src_field_offset = src_field_offsets[0]++;
6058 src_address[src_field_offset] =
6060 tgt_address[src_field_offset] = curr_tgt_address;
6061 weight[src_field_offset] = 1.0;
6066 for (
size_t k = 0; k < curr_count; ++k) {
6067 src_field_offset = src_field_offsets[0]++;
6068 src_address[src_field_offset] =
6070 tgt_address[src_field_offset] = curr_tgt_address;
6071 weight[src_field_offset] = 1.0;
6079 for (
size_t k = 0; k < curr_count; ++k) {
6080 src_field_offset = src_field_offsets[0]++;
6081 src_address[src_field_offset] =
6083 tgt_address[src_field_offset] = curr_tgt_address;
6084 weight[src_field_offset] = weights[k];
6091 src_address[src_field_offset ] =
6093 tgt_address[src_field_offset ] = curr_tgt_address;
6094 weight[src_field_offset ] = 1.0;
6101 for (
size_t k = 0; k < curr_count; ++k) {
6102 src_field_offset = src_field_offsets[field_indices[k]]++;
6103 src_address[src_field_offset] =
6105 tgt_address[src_field_offset] = curr_tgt_address;
6106 weight[src_field_offset] = 1.0;
6116 for (
size_t k = 0; k < curr_count; ++k) {
6117 src_field_offset = src_field_offsets[field_indices[k]]++;
6118 src_address[src_field_offset] =
6120 tgt_address[src_field_offset] = curr_tgt_address;
6121 weight[src_field_offset] = weights[k];
6127 for (
size_t j = 0; j < num_src_fields; ++j)
6129 src_address + prev_src_field_offsets[j],
6130 src_field_offsets[j] - prev_src_field_offsets[j],
6131 weight + prev_src_field_offsets[j]);
6133 free(src_field_offsets);
6138 int * owner_ranks,
size_t * new_count,
6141 int comm_rank, comm_size;
6145 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
6147 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
6149 size_t * stencil_indices =
xmalloc(count *
sizeof(*stencil_indices));
6150 for (
size_t i = 0; i < count; ++i) {
6151 stencil_indices[i] = i;
6152 sendcounts[owner_ranks[i]]++;
6156 1, sendcounts, recvcounts, sdispls, rdispls, comm);
6161 *new_count = recvcounts[comm_size - 1] + rdispls[comm_size - 1];
6165 free(stencil_indices);
6173 size_t src_grid_size,
size_t tgt_grid_size,
6176#ifndef YAC_NETCDF_ENABLED
6186 "ERROR(yac_interp_weights_write_to_file): "
6187 "YAC is built without the NetCDF support");
6190 MPI_Comm comm = weights->comm;
6191 int comm_rank, comm_size;
6201 int io_root = io_ranks[0];
6204 int weight_file_exists =
6207 MPI_Bcast(&weight_file_exists, 1, MPI_INT, io_root, comm), comm);
6216 if (io_root == comm_rank) {
6217 char const msg_fmt[] =
6218 "ERROR(yac_interp_weights_write_to_file): "
6219 "weight file already exists (%s)";
6220 char msg[strlen(msg_fmt) + strlen(filename)];
6221 sprintf(msg, msg_fmt, filename);
6222 yac_abort(comm, msg, __FILE__, __LINE__);
6229 yac_int min_tgt_global_id, max_tgt_global_id;
6231 weights->stencils, weights->stencils_size,
6232 &min_tgt_global_id, &max_tgt_global_id, comm);
6236 xmalloc(weights->stencils_size *
sizeof(*io_owner));
6238 weights->stencils, weights->stencils_size,
6239 min_tgt_global_id, max_tgt_global_id,
6240 num_io_ranks, io_owner);
6241 for (
size_t i = 0; i < weights->stencils_size; ++i)
6242 io_owner[i] = io_ranks[io_owner[i]];
6245 size_t io_stencil_count = 0;
6251 &io_stencil_count, &io_stencils);
6255 size_t grid_sizes[2] = {src_grid_size, tgt_grid_size};
6258 MPI_IN_PLACE, grid_sizes, 2,
YAC_MPI_SIZE_T, MPI_MAX, comm), comm);
6259 src_grid_size = (size_t)(grid_sizes[0]);
6260 tgt_grid_size = (size_t)(grid_sizes[1]);
6263 yac_mpi_call(MPI_Comm_split(comm, io_flag, comm_rank, &io_comm), comm);
6277 qsort(io_stencils, io_stencil_count,
sizeof(*io_stencils),
6280 yac_mpi_call(MPI_Comm_rank(io_comm, &comm_rank), comm);
6281 yac_mpi_call(MPI_Comm_size(io_comm, &comm_size), comm);
6283 double * fixed_values = NULL;
6284 size_t num_fixed_values = 0;
6286 io_stencils, io_stencil_count, &fixed_values, &num_fixed_values, io_comm);
6287 size_t num_src_fields =
weights->num_src_fields;
6288 size_t num_weights_per_link =
6291 size_t * size_t_buffer =
6292 xmalloc(2 * (num_fixed_values + num_src_fields) *
sizeof(*size_t_buffer));
6293 size_t * num_tgt_per_fixed_value = size_t_buffer;
6294 size_t * num_links_per_src_field = size_t_buffer + num_fixed_values;
6295 size_t * fixed_offsets = size_t_buffer + num_fixed_values + num_src_fields;
6296 size_t * link_offsets = size_t_buffer + 2 * num_fixed_values + num_src_fields;
6298 size_t num_fixed_tgt = 0;
6299 size_t num_links = 0;
6301 io_stencils, io_stencil_count, num_fixed_values, fixed_values,
6302 num_tgt_per_fixed_value, &num_fixed_tgt, num_src_fields,
6303 num_links_per_src_field, &num_links);
6306 num_fixed_values, num_tgt_per_fixed_value,
6307 num_src_fields, num_links_per_src_field,
6308 fixed_offsets, link_offsets, io_comm);
6310 if (comm_rank == comm_size - 1) {
6312 size_t * total_num_tgt_per_fixed_value =
6313 xmalloc(num_fixed_values *
sizeof(*total_num_tgt_per_fixed_value));
6314 for (
size_t i = 0, accu = 0; i < num_fixed_values; ++i) {
6315 total_num_tgt_per_fixed_value[i] =
6316 fixed_offsets[i] + num_tgt_per_fixed_value[i] - accu;
6317 accu += total_num_tgt_per_fixed_value[i];
6319 size_t total_num_links = link_offsets[num_src_fields-1] +
6320 num_links_per_src_field[num_src_fields-1];
6322 size_t * total_num_links_per_src_field =
6323 xmalloc(num_src_fields *
sizeof(*total_num_links_per_src_field));
6324 for (
size_t i = 0, accu = 0; i < num_src_fields; ++i) {
6325 total_num_links_per_src_field[i] =
6326 link_offsets[i] + num_links_per_src_field[i] - accu;
6327 accu += total_num_links_per_src_field[i];
6332 num_fixed_values, fixed_values, total_num_tgt_per_fixed_value,
6333 total_num_links, num_weights_per_link,
6334 num_src_fields, total_num_links_per_src_field,
6336 src_grid_size, tgt_grid_size);
6338 free(total_num_links_per_src_field);
6339 free(total_num_tgt_per_fixed_value);
6350 yac_nc_open(filename, NC_WRITE | NC_SHARE, &ncid);
6352 if (num_fixed_tgt > 0) {
6354 int * tgt_address_fixed =
6355 xmalloc(num_fixed_tgt *
sizeof(*tgt_address_fixed));
6359 int var_dst_add_fixed_id;
6363 for (
size_t i = 0, offset = 0; i < num_fixed_values; ++i) {
6365 if (num_tgt_per_fixed_value[i] == 0)
continue;
6367 size_t start[1] = {fixed_offsets[i]};
6368 size_t count[1] = {num_tgt_per_fixed_value[i]};
6371 ncid, var_dst_add_fixed_id, start, count, tgt_address_fixed + offset));
6372 offset += num_tgt_per_fixed_value[i];
6375 free(tgt_address_fixed);
6378 if (num_links > 0) {
6380 int * src_address_link =
xmalloc(num_links *
sizeof(*src_address_link));
6381 int * tgt_address_link =
xmalloc(num_links *
sizeof(*tgt_address_link));
6382 double * w =
xmalloc(num_links * num_weights_per_link *
sizeof(*w));
6384 io_stencils + num_fixed_tgt, io_stencil_count - num_fixed_tgt,
6385 num_links_per_src_field, num_src_fields,
6386 src_address_link, tgt_address_link, w);
6388 int var_src_add_id, var_dst_add_id, var_weight_id;
6393 for (
size_t i = 0, offset = 0; i < num_src_fields; ++i) {
6395 if (num_links_per_src_field[i] == 0)
continue;
6397 size_t start[2] = {link_offsets[i], 0};
6398 size_t count[2] = {num_links_per_src_field[i], num_weights_per_link};
6402 ncid, var_src_add_id, start, count, src_address_link + offset));
6405 ncid, var_dst_add_id, start, count, tgt_address_link + offset));
6408 ncid, var_weight_id, start, count,
6409 w + num_weights_per_link * offset));
6411 offset += num_links_per_src_field[i];
6415 free(tgt_address_link);
6416 free(src_address_link);
6425 free(size_t_buffer);
6433 return weights->stencils_size;
6440 size_t stencils_size =
weights->stencils_size;
6442 yac_int * global_ids =
xmalloc(stencils_size *
sizeof(*global_ids));
6444 for (
size_t i = 0; i < stencils_size; ++i)
6474#define COPY_ARRAY(DATA, COUNT) \
6476 size_t size = COUNT * sizeof(*(interp_weights_data.DATA)); \
6477 interp_weights_data_copy.DATA = xmalloc(size); \
6478 memcpy(interp_weights_data_copy.DATA, interp_weights_data.DATA, size); \
6490 size_t total_num_fixed_tgt = 0;
6499 size_t num_weights = 0;
6514 return interp_weights_data_copy;
#define YAC_ASSERT(exp, msg)
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
int yac_collection_selection_is_contiguous(struct yac_collection_selection const *collection_selection)
Query whether a selection is contiguous.
size_t yac_collection_selection_get_collection_size(struct yac_collection_selection const *collection_selection)
Get the size of the collection selection.
void yac_collection_selection_delete(struct yac_collection_selection *collection_selection)
Delete a collection selection object.
struct yac_collection_selection * yac_collection_selection_new(size_t collection_size, size_t const *selection_indices)
Create a new collection selection.
#define YAC_WEIGHT_FILE_VERSION_STRING
static Xt_redist * generate_src_field_exchange_redists(struct yac_src_field_exchange_data *src_field_exchange_data, size_t num_src_fields, MPI_Comm comm, Xt_config redist_config)
static struct yac_interpolation * yac_interp_weights_get_interpolation_(struct yac_interp_weights const *weights, enum yac_interp_weights_reorder_type reorder, struct yac_collection_selection const *collection_selection, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, int is_source, int is_target)
static void interpolation_raw_add_wsum_mf(struct remote_point_info_reorder *src_points, size_t num_src_points, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, void *interp_raw, Xt_config redist_config)
static void interpolation_add_wsum(struct remote_point_info_reorder *remote_src_points, size_t halo_size, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, enum yac_interp_weights_reorder_type reorder, void *interp, Xt_config redist_config)
static MPI_Datatype get_fixed_stencil_mpi_datatype(MPI_Comm comm)
static size_t get_num_links_per_src_field(struct interp_weight_stencil *stencil, size_t src_field_idx)
static int get_stencil_pack_size_direct_mf(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
static void interp_add_direct_raw(void *interp, size_t *src_orig_poses, size_t *sendcounts, struct interp_weight_stencil_direct *tgt_stencils, size_t *recvcounts, MPI_Comm comm, Xt_config redist_config)
static void interpolation_add_w_sum_mf(struct remote_point_info_reorder *remote_src_points, size_t halo_size, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, enum yac_interp_weights_reorder_type reorder, struct yac_interpolation *interp, void(*interp_add_wsum_mf_at_src)(struct yac_interpolation *, Xt_redist *, size_t, size_t *, double *, size_t *, size_t *, size_t, Xt_redist), void(*interp_add_wsum_mf_at_tgt)(struct yac_interpolation *, Xt_redist *, size_t *, size_t, size_t *, double *, size_t *, size_t *, size_t), Xt_config redist_config)
static void interpolation_raw_add_sum(struct remote_point_info_reorder *src_points, size_t num_src_points, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, void *interp_raw, Xt_config redist_config)
static void unpack_stencil_wsum_mf(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static MPI_Datatype get_direct_stencil_mpi_datatype(MPI_Comm comm)
static void stencil_determine_tgt_global_id_range(struct interp_weight_stencil *stencils, size_t stencils_size, yac_int *min_tgt_global_id, yac_int *max_tgt_global_id, MPI_Comm comm)
static void unpack_stencil_sum_mf(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_interp_weights_add_fixed(struct yac_interp_weights *weights, struct remote_points *tgts, double fixed_value)
struct yac_interp_weights_data yac_interp_weights_data_copy(struct yac_interp_weights_data interp_weights_data)
struct yac_interpolation * yac_interp_weights_get_interpolation(struct yac_interp_weights *weights, enum yac_interp_weights_reorder_type reorder, size_t collection_size, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, int is_source, int is_target)
static int compare_stencils_direct_mf(const void *a, const void *b)
void yac_interp_weights_add_sum_mf(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_field_per_tgt, struct remote_point **srcs_per_field, size_t num_src_fields)
static void yac_interp_weights_redist_direct_mf(MPI_Comm comm, size_t count, struct interp_weight_stencil *direct_mf_stencils, void *interp, void(*interp_add_direct_mf)(void *, size_t, size_t *, size_t *, struct interp_weight_stencil_direct_mf *, size_t *, MPI_Comm, Xt_config), Xt_config redist_config, int *rank_is_source, int *rank_is_target)
static struct remote_points * copy_remote_points_mf(struct remote_point **points, size_t *counts, size_t num_fields)
static struct interp_weight_stencils_wsum_mf * redist_wsum_mf_stencils_tgt(MPI_Comm comm, struct interp_weight_stencils_wsum_mf *wsum_stencils_data)
static int compare_remote_point_info(const void *a, const void *b)
static void yac_src_field_exchange_data_realloc(struct yac_interpolation_raw *interp_raw, size_t num_src_fields)
static int global_id_to_address(yac_int global_id)
static void yac_interp_weights_get_interpolation_raw_(struct yac_interp_weights const *weights, struct yac_collection_selection const *collection_selection, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, struct yac_interpolation_exchange **interpolation_exchange, struct yac_interp_weights_data *interp_weights_data, int is_source, int is_target)
static int get_stencil_pack_size_sum(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_interp_weights_data_init(struct yac_interp_weights_data *interp_weights_data)
#define COPY_ARRAY(DATA, COUNT)
static void pack_stencil_direct(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
yac_interp_weight_stencil_type
@ WEIGHT_STENCIL_TYPE_SIZE
static void interpolation_add_sum_mf(struct remote_point_info_reorder *remote_src_points, size_t halo_size, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, enum yac_interp_weights_reorder_type reorder, void *interp, Xt_config redist_config)
static void pack_stencil_wsum(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static void yac_src_field_exchange_data_msgs_add(struct yac_src_field_exchange_data_msgs *msgs, int rank, size_t count, size_t *pos, size_t offset)
static void free_remote_points(struct remote_points *points)
static void interpolation_add_wsum_mf(struct remote_point_info_reorder *remote_src_points, size_t halo_size, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, enum yac_interp_weights_reorder_type reorder, void *interp, Xt_config redist_config)
static struct remote_point_info select_src(char const *routine, struct remote_point_infos src, int *rank_is_source)
static void yac_interp_weights_redist_fixed(MPI_Comm comm, size_t count, struct interp_weight_stencil *fixed_stencils, void *interp, void(*interp_add_fixed)(void *, double, size_t, size_t *), int *rank_is_target)
static struct remote_point copy_remote_point_masked(char const *routine, struct remote_point point, int *rank_is_target)
struct yac_interpolation * yac_interp_weights_get_interpolation_ext(struct yac_interp_weights const *weights, struct yac_interpolation_gen_config const *config, int is_source, int is_target)
static void interpolation_raw_add_w_sum_mf(struct remote_point_info_reorder *remote_src_points, size_t num_src_points, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, struct yac_interpolation_raw *interp_raw, Xt_config redist_config)
static void yac_interp_weight_stencils_delete(struct interp_weight_stencil *stencils, size_t count)
static void interpolation_raw_add_sum_mf(struct remote_point_info_reorder *src_points, size_t num_src_points, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, void *interp_raw, Xt_config redist_config)
static void interpolation_add_sum(struct remote_point_info_reorder *remote_src_points, size_t halo_size, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, enum yac_interp_weights_reorder_type reorder, void *interp, Xt_config redist_config)
static int compare_stencils_fixed(const void *a, const void *b)
static void interp_add_direct_mf_raw(void *interp, size_t num_src_fields, size_t *src_orig_poses, size_t *sendcounts, struct interp_weight_stencil_direct_mf *tgt_stencils, size_t *recvcounts, MPI_Comm comm, Xt_config redist_config)
static struct interp_weight_stencil stencils_merge(struct interp_weight_stencil **stencils, double *w, size_t num_stencils, struct remote_point point)
static int get_stencil_wsum_mf_pack_size(struct interp_weight_stencil_wsum_mf *stencil, MPI_Datatype wsum_mf_weight_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_interp_weights_add_wsum(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_tgt, struct remote_point *srcs, double *w)
static struct interp_weight_stencil stencils_merge_sum(struct interp_weight_stencil **stencils, double *w, size_t num_stencils)
static int compare_w_global_id(const void *a, const void *b)
static void compact_srcs_w(struct remote_points *srcs, double **w)
void yac_interp_weights_delete(struct yac_interp_weights *weights)
void yac_interp_weights_get_interpolation_raw(struct yac_interp_weights *weights, size_t collection_size, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, struct yac_interpolation_exchange **interpolation_exchange, struct yac_interp_weights_data *interp_weights_data, int is_source, int is_target)
static size_t unpack_stencils_wsum_mf(struct interp_weight_stencil_wsum_mf *wsum_stencils, struct interp_weight_stencil_wsum_mf_weight *weight_buffer, size_t count, void *packed_data, size_t packed_data_size, MPI_Comm comm)
static void pack_stencil_sum(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static void determine_stencils_io_owner(struct interp_weight_stencil *stencils, size_t stencils_size, yac_int min_tgt_global_id, yac_int max_tgt_global_id, int num_io_procs_int, int *io_owner)
static Xt_redist * generate_direct_mf_redists(size_t *src_orig_poses, size_t *sendcounts, struct interp_weight_stencil_direct_mf *tgt_stencils, size_t *recvcounts, size_t num_src_fields, MPI_Comm comm, Xt_config redist_config)
static size_t get_num_weights_per_link(struct interp_weight_stencil *stencil)
static void free_remote_point(struct remote_point point)
static void yac_interp_weights_redist_stencils(MPI_Comm comm, size_t count, struct interp_weight_stencil *stencils, int *owner_ranks, size_t *new_count, struct interp_weight_stencil **new_stencils)
static struct yac_src_field_exchange_data_msg * yac_src_field_exchange_data_msgs_get_msg(struct yac_src_field_exchange_data_msgs *msgs, int rank)
void yac_interp_weights_data_free(struct yac_interp_weights_data interp_weights_data)
static void unpack_stencil_wsum(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_interp_weights_wcopy_weights(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_stencils_per_tgt, size_t *stencil_indices, int *stencil_ranks, double *w)
static int compare_interp_weight_stencil(const void *a, const void *b)
static Xt_config get_redist_config(char const *yaxt_exchanger_name, MPI_Comm comm)
static void yac_interp_weights_redist_w_sum_mf(MPI_Comm comm, struct interp_weight_stencils_wsum_mf *wsum_mf_stencils_data, struct yac_interpolation *interp, enum yac_interp_weights_reorder_type reorder, void(*interp_add_w_sum_mf)(struct remote_point_info_reorder *, size_t, size_t, size_t, struct interp_weight_stencil_wsum_mf *, size_t *, double *, size_t *, size_t *, MPI_Comm, enum yac_interp_weights_reorder_type, void *, Xt_config), Xt_config redist_config)
static void pack_stencil_wsum_mf(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_interp_weights_add_wsum_mf(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_field_per_tgt, struct remote_point **srcs_per_field, double *w, size_t num_src_fields)
static int compare_rank_pos_reorder_field_idx(const void *a, const void *b)
static int get_stencil_pack_size_wsum(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
static void pack_stencils(struct interp_weight_stencil *stencils, size_t count, size_t *pack_order, void **pack_data, int *pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm)
static void yac_src_field_exchange_data_init(struct yac_src_field_exchange_data *src_field_exchange_data)
static void interp_add_fixed(void *interp, double fixed_value, size_t count, size_t *tgt_pos)
static void get_stencils_pack_sizes(struct interp_weight_stencil *stencils, size_t count, size_t *pack_order, int *pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm)
yac_int * yac_interp_weights_get_interp_tgt(struct yac_interp_weights *weights)
static int get_stencil_pack_size_sum_mf(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
static void pack_stencil_fixed(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static void yac_src_field_exchange_data_add(struct yac_src_field_exchange_data *src_field_exchange_data, size_t num_src_fields, MPI_Comm comm, size_t *send_msg_sizes, size_t *send_pos, size_t *recv_msg_sizes, size_t *recv_pos, size_t *recv_offsets)
static int get_stencil_pack_size_wsum_mf(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
static struct interp_weight_stencil wcopy_interp_weight_stencil(struct interp_weight_stencil *stencil, struct remote_point point, double weight)
static Xt_redist generate_direct_redist(size_t *src_orig_poses, size_t *sendcounts, struct interp_weight_stencil_direct *tgt_stencils, size_t *recvcounts, MPI_Comm comm, Xt_config redist_config)
static struct interp_weight_stencil * yac_interp_weights_get_stencils(struct yac_interp_weights *weights, size_t *stencil_indices, int *stencil_ranks, size_t count)
static void unpack_stencil_direct_mf(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static int compare_stencils(const void *a, const void *b)
static void create_weight_file(char const *filename, char const *src_grid_name, char const *tgt_grid_name, size_t num_fixed_values, double *fixed_values, size_t *num_tgt_per_fixed_value, size_t num_links, size_t num_weights_per_link, size_t num_src_fields, size_t *num_links_per_src_field, enum yac_location *src_locations, enum yac_location tgt_location, size_t src_grid_size, size_t tgt_grid_size)
static int get_stencil_pack_size_direct(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
static void stencil_get_counts(struct interp_weight_stencil *stencils, size_t stencil_count, size_t num_fixed_values, double *fixed_values, size_t *num_tgt_per_fixed_value, size_t *num_fixed_tgt, size_t num_src_fields, size_t *num_links_per_src_field, size_t *num_links)
static void copy_remote_points_no_alloc(struct remote_point *points_to, struct remote_point *points_from, size_t count, struct remote_point_info **point_info_buffer_)
static void interpolation_raw_add_wsum(struct remote_point_info_reorder *src_points, size_t num_src_points, size_t num_src_fields, size_t tgt_count, struct interp_weight_stencil_wsum_mf *tgt_stencils, size_t *num_src_per_tgt, double *weights, size_t *src_idx, size_t *src_field_idx, MPI_Comm comm, void *interp_raw, Xt_config redist_config)
static struct remote_points * copy_remote_points(struct remote_point *points, size_t count)
static void interpolation_add_sum_at_src(struct yac_interpolation *interp, Xt_redist *halo_redists, size_t tgt_count, size_t *num_src_per_tgt, double *weights, size_t *src_field_idx, size_t *src_idx, size_t num_src_fields, Xt_redist result_redist)
static Xt_redist generate_redist_put_double(struct remote_point_infos *point_infos, size_t count, MPI_Comm comm, Xt_config redist_config)
static int compare_remote_point(const void *a, const void *b)
static struct interp_weight_stencils_wsum_mf * generate_w_sum_mf_stencils(struct interp_weight_stencil *stencils, size_t count, enum yac_interp_weight_stencil_type stencil_type, int *rank_is_source, int *rank_is_target)
static MPI_Datatype get_direct_mf_stencil_mpi_datatype(MPI_Comm comm)
#define YAC_YAXT_EXCHANGER_STR
MPI_Comm yac_interp_weights_get_comm(struct yac_interp_weights *weights)
static MPI_Datatype get_wsum_mf_weight_mpi_datatype(MPI_Comm comm)
static struct interp_weight_stencil copy_interp_weight_stencil(struct interp_weight_stencil *stencil, struct remote_point point)
void yac_interp_weights_add_direct(struct yac_interp_weights *weights, struct remote_points *tgts, struct remote_point *srcs)
void yac_interp_weights_add_sum(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_tgt, struct remote_point *srcs)
static void unpack_stencil_direct(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static int compare_interp_weight_stencil_wsum_mf_tgt_orig_pos(const void *a, const void *b)
static void interp_raw_add_fixed(void *interp, double fixed_value, size_t count, size_t *tgt_pos)
struct yac_interp_weights * yac_interp_weights_new(MPI_Comm comm, enum yac_location tgt_location, enum yac_location *src_locations, size_t num_src_fields)
static void unpack_stencil_sum(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static struct interp_weight_stencils_wsum_mf * redist_wsum_mf_stencils(MPI_Comm comm, struct interp_weight_stencils_wsum_mf *wsum_stencils_data, int *stencil_owner, size_t *reorder_idx, size_t num_owners)
static struct interp_weight_stencils_wsum_mf * redist_wsum_mf_stencils_src(MPI_Comm comm, struct interp_weight_stencils_wsum_mf *wsum_stencils_data)
static int compare_stencils_direct(const void *a, const void *b)
static void yac_interp_weights_data_init_(double frac_mask_fallback_value, double scaling_factor, double scaling_summand, struct yac_interp_weights_data *interp_weights_data)
static size_t stencil_get_num_weights_per_tgt(struct interp_weight_stencil *stencils, size_t stencil_count, MPI_Comm comm)
static void stencil_get_tgt_address(struct interp_weight_stencil *stencils, size_t stencil_count, int *tgt_address)
static int get_stencil_pack_size_fixed(struct interp_weight_stencil *stencil, MPI_Datatype point_info_dt, MPI_Comm comm)
static struct remote_point copy_remote_point(struct remote_point point)
static void stencil_get_link_data(struct interp_weight_stencil *stencils, size_t stencil_count, size_t *num_links_per_src_field, size_t num_src_fields, int *src_address, int *tgt_address, double *weight)
static void interp_add_direct(void *interp, size_t *src_orig_poses, size_t *sendcounts, struct interp_weight_stencil_direct *tgt_stencils, size_t *recvcounts, MPI_Comm comm, Xt_config redist_config)
size_t yac_interp_weights_get_interp_count(struct yac_interp_weights *weights)
static struct interp_weight_stencil stencils_merge_wsum(struct interp_weight_stencil **stencils, double *w, size_t num_stencils)
static void pack_stencil_sum_mf(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static Xt_redist * generate_halo_redists(struct remote_point_info_reorder *halo_points, size_t count, size_t num_src_fields, MPI_Comm comm, Xt_config redist_config)
static void pack_stencil_direct_mf(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static void pack_stencils_wsum_mf(struct interp_weight_stencil_wsum_mf *wsum_stencils, size_t count, size_t *pack_order, void **pack_data, int *pack_sizes, int *weight_counts, MPI_Comm comm)
struct yac_interpolation * yac_interp_weights_get_interpolation_f2c(struct yac_interp_weights *weights, int reorder, size_t collection_size, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, int is_source, int is_target)
static int compare_interp_weight_stencil_wsum_mf_src_orig_pos(const void *a, const void *b)
static struct interp_weight_stencil * exchange_stencils(MPI_Comm comm, struct interp_weight_stencil *stencils, size_t *stencil_indices, size_t *stencil_sendcounts, size_t *stencil_recvcounts)
static int remote_point_is_valid(char const *routine, struct remote_point point, int *rank_is_target)
static void unpack_stencil_fixed(struct interp_weight_stencil *stencil, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
static int compare_double(void const *a, void const *b)
static void stencil_xscan_offsets(size_t num_fixed_values, size_t *num_tgt_per_fixed_value, size_t num_src_fields, size_t *num_links_per_src_field, size_t *fixed_offsets, size_t *link_offsets, MPI_Comm comm)
void yac_interp_weights_get_interpolation_raw_ext(struct yac_interp_weights const *weights, struct yac_interpolation_gen_config const *config, struct yac_interpolation_exchange **interpolation_exchange, struct yac_interp_weights_data *interp_weights_data, int is_source, int is_target)
static void interpolation_add_sum_at_tgt(struct yac_interpolation *interp, Xt_redist *src_redists, size_t *tgt_pos, size_t tgt_count, size_t *num_src_per_tgt, double *weights, size_t *src_field_idx, size_t *src_idx, size_t num_src_fields)
static void yac_interp_weights_redist_direct(MPI_Comm comm, size_t count, struct interp_weight_stencil *direct_stencils, void *interp, void(*interp_add_direct)(void *, size_t *, size_t *, struct interp_weight_stencil_direct *, size_t *, MPI_Comm, Xt_config), Xt_config redist_config, int *rank_is_source, int *rank_is_target)
static void interp_add_direct_mf(void *interp, size_t num_src_fields, size_t *src_orig_poses, size_t *sendcounts, struct interp_weight_stencil_direct_mf *tgt_stencils, size_t *recvcounts, MPI_Comm comm, Xt_config redist_config)
void yac_interp_weights_write_to_file(struct yac_interp_weights *weights, char const *filename, char const *src_grid_name, char const *tgt_grid_name, size_t src_grid_size, size_t tgt_grid_size, enum yac_weight_file_on_existing on_existing)
static void xt_redist_msg_free(struct Xt_redist_msg *msgs, size_t count, MPI_Comm comm)
void yac_interp_weights_add_direct_mf(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *src_field_indices, struct remote_point **srcs_per_field, size_t num_src_fields)
static void unpack_stencils(struct interp_weight_stencil *stencils, size_t count, void *packed_data, size_t packed_data_size, MPI_Datatype point_info_dt, MPI_Comm comm)
static void yac_src_field_exchange_data_free(struct yac_src_field_exchange_data *src_field_exchange_data, size_t num_src_fields)
static int compute_owner(int *ranks, size_t count)
static void yac_interp_weights_redist_w_sum_mf_raw(MPI_Comm comm, struct interp_weight_stencils_wsum_mf *wsum_mf_stencils_data, struct yac_interpolation *interp, void(*interp_add_w_sum_mf)(struct remote_point_info_reorder *, size_t, size_t, size_t, struct interp_weight_stencil_wsum_mf *, size_t *, double *, size_t *, size_t *, MPI_Comm, void *, Xt_config), Xt_config redist_config)
static void stencil_get_fixed_values(struct interp_weight_stencil *stencils, size_t stencil_count, double **fixed_values, size_t *num_fixed_values, MPI_Comm comm)
static void yac_interp_weights_data_set_wgt_tgt(struct yac_interp_weights_data *interp_weights_data, size_t num_src_fields, size_t tgt_count, size_t *tgt_idx, size_t *num_src_per_tgt, double *weights, size_t *src_field_idx, size_t *src_idx, size_t *src_field_buffer_size)
yac_interp_weights_reorder_type
@ YAC_MAPPING_ON_TGT
weights will be applied at target processes
@ YAC_MAPPING_ON_SRC
weights will be applied at source processes
yac_weight_file_on_existing
@ YAC_WEIGHT_FILE_KEEP
keep existing weight file
@ YAC_WEIGHT_FILE_ERROR
error when weight file existis already
void yac_interpolation_add_sum_at_src(struct yac_interpolation *interp, Xt_redist *halo_redists, size_t tgt_count, size_t *num_src_per_tgt, size_t *src_field_idx, size_t *src_idx, size_t num_src_fields, Xt_redist result_redist)
Add a sum operator where accumulation occurs on source processes.
void yac_interpolation_add_weight_sum_mvp_at_tgt(struct yac_interpolation *interp, Xt_redist *src_redists, size_t *tgt_pos, size_t tgt_count, size_t *num_src_per_tgt, double *weights, size_t *src_field_idx, size_t *src_idx, size_t num_src_fields)
Add a weighted sum operator (distributed matrix-vector product), which computes the product at the ta...
void yac_interpolation_add_direct_mf(struct yac_interpolation *interp, Xt_redist *redists, size_t num_src_fields)
Add a direct redistribution operator for multiple source fields.
void yac_interpolation_add_sum_at_tgt(struct yac_interpolation *interp, Xt_redist *src_redists, size_t *tgt_pos, size_t tgt_count, size_t *num_src_per_tgt, size_t *src_field_idx, size_t *src_idx, size_t num_src_fields)
Add a sum operator where accumulation occurs on target processes.
void yac_interpolation_add_fixed(struct yac_interpolation *interp, double value, size_t count, size_t *pos)
Add a fixed-value operator to an interpolation.
double const YAC_FRAC_MASK_UNDEF
void yac_interpolation_add_direct(struct yac_interpolation *interp, Xt_redist redist)
Add a direct redistribution operator.
struct yac_interpolation * yac_interpolation_new(struct yac_collection_selection const *collection_selection, double frac_mask_fallback_value, double scale_factor, double scale_summand)
Create a new interpolation object.
void yac_interpolation_add_weight_sum_mvp_at_src(struct yac_interpolation *interp, Xt_redist *halo_redists, size_t tgt_count, size_t *num_src_per_tgt, double *weights, size_t *src_field_idx, size_t *src_idx, size_t num_src_fields, Xt_redist result_redist)
Add a weighted sum operator (distributed matrix-vector product), which computes the productes at the ...
struct Xt_redist_ * Xt_redist
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.
Interpolation exchange object for temporary buffers and MPI exchanges.
enum yac_interp_weights_reorder_type yac_interpolation_gen_config_get_reorder(struct yac_interpolation_gen_config const *config)
Get the configured reordering strategy.
double yac_interpolation_gen_config_get_frac_mask_fallback_value(struct yac_interpolation_gen_config const *config)
Get the configured fractional mask fallback value.
double yac_interpolation_gen_config_get_scaling_factor(struct yac_interpolation_gen_config const *config)
Get the configured scaling factor.
struct yac_collection_selection const * yac_interpolation_gen_config_get_collection_selection(struct yac_interpolation_gen_config const *config)
Get the configured collection selection.
const char * yac_interpolation_gen_config_get_yaxt_exchanger_name(struct yac_interpolation_gen_config const *config)
Get the configured Yaxt exchanger name.
double yac_interpolation_gen_config_get_scaling_summand(struct yac_interpolation_gen_config const *config)
Get the configured scaling summand.
#define YAC_FRAC_MASK_VALUE_IS_VALID(value)
Test whether a fractional mask value is valid.
void yac_get_io_ranks(MPI_Comm comm, int *local_is_io_, int **io_ranks_, int *num_io_ranks_)
void yac_nc_create(const char *path, int cmode, int *ncidp)
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
int yac_file_exists(const char *filename)
Check whether a file exists.
void yac_nc_open(const char *path, int omode, int *ncidp)
char const * yac_loc2str(enum yac_location location)
#define YAC_MAX_LOC_STR_LEN
add versions of standard API functions not returning on error
#define xrealloc(ptr, size)
void yac_remote_point_pack(struct remote_point *point, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_remote_point_unpack(void *buffer, int buffer_size, int *position, struct remote_point *point, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_remote_points_pack(struct remote_points *points, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_remote_points_unpack(void *buffer, int buffer_size, int *position, struct remote_points **points, MPI_Datatype point_info_dt, MPI_Comm comm)
int yac_remote_points_get_pack_size(struct remote_points *points, MPI_Datatype point_info_dt, MPI_Comm comm)
MPI_Datatype yac_get_remote_point_info_mpi_datatype(MPI_Comm comm)
int yac_remote_point_get_pack_size(struct remote_point *point, MPI_Datatype point_info_dt, MPI_Comm comm)
struct remote_point_info src
struct remote_point_info src
struct remote_point_info src
struct interp_weight_stencil_wsum_mf_weight * data
struct interp_weight_stencil::@14::@21 weight_sum_mf
struct remote_points * srcs
struct interp_weight_stencil::@14::@18 weight_sum
union interp_weight_stencil::@14 data
struct interp_weight_stencil::@14::@15 fixed
struct interp_weight_stencil::@14::@17 sum
enum yac_interp_weight_stencil_type type
struct interp_weight_stencil::@14::@20 sum_mf
struct interp_weight_stencil::@14::@19 direct_mf
struct interp_weight_stencil::@14::@16 direct
struct interp_weight_stencils_wsum_mf stencils
struct interp_weight_stencil_wsum_mf_weight buffer[]
struct interp_weight_stencil_wsum_mf * data
size_t * num_tgt_per_fixed_value
double frac_mask_fallback_value
struct remote_point_info data
single location information of a point
location information about a point that is located on one or
union remote_point_infos::@53 data
struct remote_point_info single
struct remote_point_info * multi
information (global id and location) about a point that
struct remote_point_infos data
structure containing the information (global id and location)
struct remote_point_info buffer[]
struct remote_point * data
double frac_mask_fallback_value
size_t * src_field_buffer_size
size_t * num_tgt_per_fixed_value
struct interp_weight_stencil * stencils
size_t stencils_array_size
enum yac_location tgt_location
enum yac_location * src_locations
Configuration structure for interpolation generation.
struct yac_interpolation_raw::yac_src_field_exchange_data::yac_src_field_exchange_data_msgs::yac_src_field_exchange_data_msg * msg
struct yac_interpolation_raw::yac_src_field_exchange_data::yac_src_field_exchange_data_msgs send
struct yac_interpolation_raw::yac_src_field_exchange_data::yac_src_field_exchange_data_msgs recv
struct yac_interp_weights_data interp_weights_data
struct yac_interpolation_raw::yac_src_field_exchange_data * src_field_exchange_data
double frac_mask_fallback_value
struct yac_collection_selection * collection_selection
Selection of field collections to which this interpolation applies.
static struct yac_interp_method_config * config
char const src_grid_name[]
char const tgt_grid_name[]
static double const fixed_value
static MPI_Comm split_comm
#define YAC_HANDLE_ERROR(exp)
void yac_quicksort_index_int_double(int *a, size_t n, double *idx)
void yac_quicksort_index_int_size_t(int *a, size_t n, size_t *idx)
void yac_quicksort_index_int_size_t_size_t(int *a, size_t n, size_t *b, size_t *c)
static void yac_remove_duplicates_double(double *array, size_t *n)
void yac_quicksort_index_size_t_size_t(size_t *a, size_t n, size_t *idx)
void yac_quicksort_index(int *a, size_t n, int *idx)
void yac_abort(MPI_Comm comm, const char *msg, const char *source, int line) __attribute__((noreturn))
#define YAC_ASSERT_F(exp, format,...)
#define YAC_ASSERT_F_FUNC(exp, func, format,...)
#define YAC_UNREACHABLE_DEFAULT(msg)
void yac_generate_alltoallv_args(int count, size_t const *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls, MPI_Comm comm)
void yac_free_comm_buffers(size_t *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls)
void yac_get_comm_buffers(int count, size_t **sendcounts, size_t **recvcounts, size_t **sdispls, size_t **rdispls, MPI_Comm comm)
MPI_Datatype yac_create_resized(MPI_Datatype dt, size_t new_size, MPI_Comm comm)
void yac_alltoallv_p2p(void const *send_buffer, size_t const *sendcounts, size_t const *sdispls, void *recv_buffer, size_t const *recvcounts, size_t const *rdispls, size_t dt_size, MPI_Datatype dt, MPI_Comm comm, char const *caller, int line)
#define yac_mpi_call(call, comm)