95 size_t num_src_fields,
96 struct link_data ** links,
size_t * num_links,
97 struct fixed_data ** fixed,
size_t * num_fixed) {
99#ifndef YAC_NETCDF_ENABLED
113 die(
"ERROR(read_weight_file): YAC is built without the NetCDF support");
130 int io_idx = INT_MAX;
132 for (
int i = 0; (i < num_io_ranks) && (io_idx == INT_MAX); ++i)
133 if (io_ranks[i] == rank) io_idx = i;
137 if (!local_is_io)
return;
151 version =
xmalloc(version_len + 1);
152 version[version_len] =
'\0';
157 "version string from weight file (\"%s\") does not match "
161 size_t grid_name_len;
163 YAC_HANDLE_ERROR(nc_inq_attlen(ncid, NC_GLOBAL,
"src_grid_name", &grid_name_len));
164 grid_name =
xmalloc(grid_name_len + 1);
165 grid_name[grid_name_len] =
'\0';
166 YAC_HANDLE_ERROR(nc_get_att_text(ncid, NC_GLOBAL,
"src_grid_name", grid_name));
170 "source grid name from weight file (\"%s\") "
171 "does not match with the one provided through the interface (\"%s\")",
176 YAC_HANDLE_ERROR(nc_inq_attlen(ncid, NC_GLOBAL,
"dst_grid_name", &grid_name_len));
177 grid_name =
xmalloc(grid_name_len + 1);
178 grid_name[grid_name_len] =
'\0';
179 YAC_HANDLE_ERROR(nc_get_att_text(ncid, NC_GLOBAL,
"dst_grid_name", grid_name));
183 "target grid name from weight file (\"%s\") "
184 "does not match with the one provided through the interface (\"%s\")",
196 YAC_HANDLE_ERROR(nc_inq_attlen(ncid, var_id,
"contains_links", &str_link_len));
197 str_link =
xmalloc(str_link_len + 1);
198 str_link[str_link_len] =
'\0';
199 YAC_HANDLE_ERROR(nc_get_att_text(ncid, var_id,
"contains_links", str_link));
201 int contains_links = (strlen(
"TRUE") == str_link_len) &&
202 !strncmp(
"TRUE", str_link, str_link_len);
205 ((strlen(
"FALSE") == str_link_len) &&
206 !strncmp(
"FALSE", str_link, str_link_len)),
207 "invalid global attribute contains_links")
211 if (contains_links) {
214 YAC_ASSERT(num_wgts == 1,
"YAC only supports num_wgts == 1")
219 size_t num_links_in_file = 0;
220 if (contains_links) {
223 YAC_ASSERT(num_links_in_file != 0,
"no links defined")
227 size_t tmp_num_src_fields = 0;
228 if (contains_links) {
231 YAC_ASSERT(tmp_num_src_fields != 0,
"no source fields in file")
233 tmp_num_src_fields == num_src_fields,
234 "number of source fields in file (%zu) does not "
235 "match with the number provided through the interface (%zu)",
236 tmp_num_src_fields, num_src_fields)
240 size_t max_loc_str_len;
245 "wrong max location string length in weight file")
249 xmalloc(num_src_fields *
sizeof(*tmp_src_locations));
252 for (
size_t i = 0; i < num_src_fields; ++i) {
256 size_t str_start[2] = {i, 0};
260 nc_get_vara_text(ncid, var_id, str_start, str_count, loc_str));
265 tmp_src_locations[i] == src_locations[i],
266 "source locations in file does not match with "
267 "the locations provided through the interface\n"
268 "location index: %d\n"
269 "location in weight file: %s\n"
270 "location from interface: %s",
274 free(tmp_src_locations);
283 "target locations in file does not match with "
284 "the locations provided through the interface")
287 if (contains_links) {
290 unsigned * num_links_per_src_field =
291 xmalloc(num_src_fields *
sizeof(*num_links_per_src_field));
296 (size_t)(((
long long)io_idx * (
long long)num_links_in_file) /
297 (
long long)num_io_ranks);
299 (size_t)((((
long long)io_idx + 1) * (
long long)num_links_in_file) /
300 (
long long)num_io_ranks) - offset;
304 *links =
xmalloc(count *
sizeof(**links));
307 size_t src_field_idx = 0, src_field_start_offset = 0;
308 while ((src_field_idx < num_src_fields) &&
309 (src_field_start_offset +
310 (
size_t)num_links_per_src_field[src_field_idx] <
313 src_field_start_offset += (size_t)num_links_per_src_field[src_field_idx];
317 src_field_idx < num_src_fields,
"problem in num_links_per_src_field")
318 size_t src_field_offset = offset - src_field_start_offset;
319 for (
size_t k = 0; (src_field_idx < num_src_fields) && (k < count);
320 src_field_offset = 0, ++src_field_idx) {
322 for (; (src_field_offset <
323 (size_t)num_links_per_src_field[src_field_idx]) &&
324 (k < count); ++src_field_offset, ++k) {
325 (*links)[k].src_field_idx = src_field_idx;
329 free(num_links_per_src_field);
332 int * address =
xmalloc(count *
sizeof(*address));
335 for (
size_t i = 0; i < count; ++i)
336 (*links)[i].src.global_id = (
yac_int)(address[i] - 1);
340 for (
size_t i = 0; i < count; ++i)
341 (*links)[i].tgt.global_id = (
yac_int)(address[i] - 1);
344 double * weights =
xmalloc(count *
sizeof(*weights));
347 size_t offsets[2] = {offset, 0};
348 size_t counts[2] = {count, 1};
349 YAC_HANDLE_ERROR(nc_get_vara_double(ncid, var_id, offsets, counts, weights));
350 for (
size_t i = 0; i < count; ++i)
351 (*links)[i].weight = weights[i];
361 size_t str_fixed_len;
365 nc_inq_attlen(ncid, var_id,
"contains_fixed_dst", &str_fixed_len));
366 str_fixed =
xmalloc(str_fixed_len + 1);
367 str_fixed[str_fixed_len] =
'\0';
368 YAC_HANDLE_ERROR(nc_get_att_text(ncid, var_id,
"contains_fixed_dst", str_fixed));
370 int contains_fixed = (strlen(
"TRUE") == str_fixed_len) &&
371 !strncmp(
"TRUE", str_fixed, str_fixed_len);
375 ((strlen(
"FALSE") == str_fixed_len) &&
376 !strncmp(
"FALSE", str_fixed, str_fixed_len)),
377 "invalid global attribute contains_fixed_dst")
380 if (contains_fixed) {
383 size_t num_fixed_values;
388 size_t num_fixed_tgt;
393 (size_t)(((
long long)io_idx * (
long long)num_fixed_tgt) /
394 (
long long)num_io_ranks);
396 (size_t)((((
long long)io_idx + 1) * (
long long)num_fixed_tgt) /
397 (
long long)num_io_ranks) - offset;
399 *fixed =
xmalloc(num_fixed_values *
sizeof(**fixed));
400 *num_fixed = num_fixed_values;
402 double * fixed_values =
xmalloc(num_fixed_values *
sizeof(*fixed_values));
403 int * num_tgt_indices_per_fixed_value =
404 xmalloc(num_fixed_values *
sizeof(*num_tgt_indices_per_fixed_value));
405 int * global_tgt_indices =
xmalloc(count *
sizeof(*global_tgt_indices));
409 YAC_HANDLE_ERROR(nc_get_var_int(ncid, var_id, num_tgt_indices_per_fixed_value));
417 nc_get_vara_int(ncid, var_id, &offset, &count, global_tgt_indices));
420 void * tgt_global_id_buffer =
xmalloc(count *
sizeof(*((*fixed)->tgt)));
421 size_t fixed_value_idx = 0, fixed_value_start_offset = 0;
422 while ((fixed_value_idx < num_fixed_values) &&
423 (fixed_value_start_offset +
424 (
size_t)num_tgt_indices_per_fixed_value[fixed_value_idx] <
427 fixed_value_start_offset +=
428 (size_t)num_tgt_indices_per_fixed_value[fixed_value_idx];
429 (*fixed)[fixed_value_idx].value = fixed_values[fixed_value_idx];
430 (*fixed)[fixed_value_idx].num_tgt = 0;
431 (*fixed)[fixed_value_idx].tgt = tgt_global_id_buffer;
435 fixed_value_idx < num_fixed_values,
436 "problem in num_tgt_indices_per_fixed_value")
437 size_t fixed_value_offset = offset - fixed_value_start_offset;
438 for (
size_t k = 0; (fixed_value_idx < num_fixed_values) && (k < count);
439 fixed_value_offset = 0, ++fixed_value_idx) {
441 size_t curr_tgt_count =
442 MIN((
size_t)num_tgt_indices_per_fixed_value[fixed_value_idx] -
443 fixed_value_offset, count - k);
445 (*fixed)[fixed_value_idx].value = fixed_values[fixed_value_idx];
446 (*fixed)[fixed_value_idx].num_tgt = curr_tgt_count;
447 (*fixed)[fixed_value_idx].tgt =
448 (
void*)(((
unsigned char *)tgt_global_id_buffer) +
449 k *
sizeof(*((*fixed)->tgt)));
451 for (
size_t i = 0; i < curr_tgt_count; ++fixed_value_offset, ++k, ++i)
452 (*fixed)[fixed_value_idx].tgt[i].global_id =
453 (
yac_int)(global_tgt_indices[k] - 1);
455 for (; fixed_value_idx < num_fixed_values; ++fixed_value_idx) {
456 (*fixed)[fixed_value_idx].value = fixed_values[fixed_value_idx];
457 (*fixed)[fixed_value_idx].num_tgt = 0;
458 (*fixed)[fixed_value_idx].tgt = NULL;
462 free(global_tgt_indices);
463 free(num_tgt_indices_per_fixed_value);
822 struct yac_interp_grid * interp_grid,
size_t * tgt_points,
size_t tgt_count,
823 size_t * num_interpolated_points,
824 struct link_data ** links,
size_t * num_links,
825 struct fixed_data ** fixed,
size_t * num_fixed) {
833 yac_int * tgt_global_ids =
xmalloc(tgt_count *
sizeof(*tgt_global_ids));
835 interp_grid, tgt_points, tgt_count, tgt_global_ids);
843 size_t * size_t_buffer =
844 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
845 size_t * total_sendcounts = size_t_buffer + 0 * comm_size;
846 size_t * total_recvcounts = size_t_buffer + 1 * comm_size;
847 size_t * total_sdispls = size_t_buffer + 2 * comm_size;
848 size_t * total_rdispls = size_t_buffer + 3 * comm_size;
849 size_t * sendcounts, * recvcounts, * sdispls, *rdispls;
851 3, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
853 for (
size_t i = 0; i < tgt_count; ++i)
854 sendcounts[3 *
compute_bucket(tgt_global_ids[i], comm_size) + 0]++;
855 for (
size_t i = 0; i < *num_links; ++i)
857 for (
size_t i = 0; i < *num_fixed; ++i)
858 for (
size_t j = 0; j < (*fixed)[i].num_tgt; ++j)
866 size_t saccu = 0, raccu = 0;
867 for (
int i = 0; i < comm_size; ++i) {
868 total_sdispls[i] = saccu;
869 sdispls[3*i+0] = saccu;
872 (total_sendcounts[i] =
873 sendcounts[3*i+0] * (size_t)tgt_pack_size));
876 (total_sendcounts[i] +=
877 sendcounts[3*i+1] * (size_t)link_pack_size));
878 total_sendcounts[i] +=
879 sendcounts[3*i+2] * (size_t)fixed_pack_size;
880 total_rdispls[i] = raccu;
881 rdispls[3*i+0] = raccu;
884 (total_recvcounts[i] =
885 recvcounts[3*i+0] * (size_t)tgt_pack_size));
888 (total_recvcounts[i] +=
889 recvcounts[3*i+1] * (size_t)link_pack_size));
890 total_recvcounts[i] +=
891 recvcounts[3*i+2] * (size_t)fixed_pack_size;
892 saccu += total_sendcounts[i];
893 raccu += total_recvcounts[i];
896 size_t send_size = total_sendcounts[comm_size - 1] +
897 total_sdispls[comm_size - 1];
898 size_t recv_size = total_recvcounts[comm_size - 1] +
899 total_rdispls[comm_size - 1];
901 void * pack_buffer =
xmalloc(send_size + recv_size);
902 void * send_pack_buffer = pack_buffer;
903 void * recv_pack_buffer = (
void*)((
unsigned char *)pack_buffer + send_size);
906 for (
size_t i = 0; i < tgt_count; ++i) {
907 yac_int curr_global_id = tgt_global_ids[i];
911 (
void*)((
unsigned char*)send_pack_buffer + sdispls[3*rank+0]),
912 tgt_pack_size, comm);
913 sdispls[3*rank+0] += (size_t)tgt_pack_size;
915 for (
size_t i = 0; i < *num_links; ++i) {
916 struct link_data * curr_link = (*links) + i;
920 (
void*)((
unsigned char*)send_pack_buffer + sdispls[3*rank+1]),
921 link_pack_size, comm);
922 sdispls[3*rank+1] += (size_t)link_pack_size;
924 for (
size_t i = 0; i < *num_fixed; ++i) {
925 double curr_fixed_value = (*fixed)[i].value;
926 size_t curr_num_tgt = (*fixed)[i].num_tgt;
927 for (
size_t j = 0; j < curr_num_tgt; ++j) {
928 yac_int curr_global_id = (*fixed)[i].tgt[j].global_id;
931 curr_fixed_value, curr_global_id,
932 (
void*)((
unsigned char*)send_pack_buffer + sdispls[3*rank+2]),
933 fixed_pack_size, comm);
934 sdispls[3*rank+2] += (size_t)fixed_pack_size;
939 yac_alltoallv_packed_p2p(
940 send_pack_buffer, total_sendcounts, total_sdispls,
941 recv_pack_buffer, total_recvcounts, total_rdispls, comm,
944 size_t recv_tgt_count = 0, recv_link_count = 0, recv_fixed_count = 0;
945 for (
int i = 0; i < comm_size; ++i) {
946 recv_tgt_count += recvcounts[3*i+0];
947 recv_link_count += recvcounts[3*i+1];
948 recv_fixed_count += recvcounts[3*i+2];
951 xrealloc(*links, recv_link_count *
sizeof(*recv_links));
953 xmalloc(recv_fixed_count *
sizeof(*recv_fixed));
955 xmalloc((recv_tgt_count + tgt_count) *
sizeof(*result_buffer));
957 struct temp_result * recv_results = result_buffer + recv_tgt_count;
960 recv_tgt_count = 0, recv_link_count = 0, recv_fixed_count = 0;
961 size_t unpack_offset = 0;
962 for (
int i = 0; i < comm_size; ++i) {
963 size_t curr_num_tgt = recvcounts[3 * i + 0];
964 size_t curr_num_links = recvcounts[3 * i + 1];
965 size_t curr_num_fixed = recvcounts[3 * i + 2];
966 for (
size_t j = 0; j < curr_num_tgt; ++j, ++recv_tgt_count) {
968 (
void*)((
unsigned char *)recv_pack_buffer + unpack_offset),
969 tgt_pack_size, &(send_results[recv_tgt_count].
tgt.
global_id),
971 unpack_offset += (size_t)tgt_pack_size;
972 send_results[recv_tgt_count].
owner = i;
973 send_results[recv_tgt_count].
reorder_idx = recv_tgt_count;
975 for (
size_t j = 0; j < curr_num_links; ++j, ++recv_link_count) {
977 (
void*)((
unsigned char *)recv_pack_buffer + unpack_offset),
978 link_pack_size, recv_links + recv_link_count, comm);
979 unpack_offset += (size_t)link_pack_size;
981 for (
size_t j = 0; j < curr_num_fixed; ++j, ++recv_fixed_count) {
983 (
void*)((
unsigned char *)recv_pack_buffer + unpack_offset),
984 fixed_pack_size, recv_fixed + recv_fixed_count, comm);
985 unpack_offset += (size_t)fixed_pack_size;
991 send_results, recv_tgt_count,
sizeof(*send_results),
1000 recv_fixed, recv_fixed_count,
sizeof(*recv_fixed),
1004 for (
size_t tgt_idx = 0, link_idx = 0, fixed_idx = 0;
1005 tgt_idx < recv_tgt_count; ++tgt_idx) {
1009 while ((link_idx < recv_link_count) &&
1010 (recv_links[link_idx].
tgt.
global_id < curr_tgt)) ++link_idx;
1011 while ((fixed_idx < recv_fixed_count) &&
1012 (recv_fixed[fixed_idx].
tgt.
global_id < curr_tgt)) ++fixed_idx;
1015 (link_idx >= recv_link_count) ||
1017 (fixed_idx >= recv_fixed_count) ||
1019 "inconsistent data in weight file;"
1020 "link and fixed data available for a target point")
1021 if ((link_idx < recv_link_count) &&
1024 size_t temp_link_idx = link_idx;
1025 while ((temp_link_idx < recv_link_count) &&
1029 send_results[tgt_idx].
data.
link.
links = recv_links + link_idx;
1030 send_results[tgt_idx].
data.
link.
count = temp_link_idx - link_idx;
1032 }
else if ((fixed_idx < recv_fixed_count) &&
1046 send_results, recv_tgt_count,
sizeof(*send_results),
1049 int * pack_size_buffer =
1050 xmalloc((recv_tgt_count + tgt_count) *
sizeof(*pack_size_buffer));
1051 int * send_pack_sizes = pack_size_buffer;
1052 int * recv_pack_sizes = pack_size_buffer + recv_tgt_count;
1053 for (
size_t i = 0; i < recv_tgt_count; ++i)
1056 saccu = 0, raccu = 0;
1057 for (
int i = 0; i < comm_size; ++i) {
1060 int sendcount = recvcounts[3*i];
1061 int recvcount = sendcounts[3*i];
1062 saccu += (sendcounts[i] = sendcount);
1063 raccu += (recvcounts[i] = recvcount);
1066 yac_alltoallv_int_p2p(
1067 send_pack_sizes, sendcounts, sdispls,
1068 recv_pack_sizes, recvcounts, rdispls, comm, __func__, __LINE__);
1070 saccu = 0, raccu = 0;
1071 for (
int i = 0, k = 0, l = 0; i < comm_size; ++i) {
1072 size_t sendcount = sendcounts[i];
1073 size_t recvcount = recvcounts[i];
1076 for (
size_t j = 0; j < sendcount; ++j, ++k)
1077 sendcounts[i] += send_pack_sizes[k];
1078 for (
size_t j = 0; j < recvcount; ++j, ++l)
1079 recvcounts[i] += recv_pack_sizes[l];
1082 saccu += sendcounts[i];
1083 raccu += recvcounts[i];
1085 size_t total_send_pack_size =
1086 sdispls[comm_size-1] + sendcounts[comm_size-1];
1087 size_t total_recv_pack_size =
1088 rdispls[comm_size-1] + recvcounts[comm_size-1];
1091 xrealloc(pack_buffer, total_send_pack_size + total_recv_pack_size);
1092 send_pack_buffer = pack_buffer;
1094 (
void*)((
unsigned char*)pack_buffer + total_send_pack_size);
1096 for (
size_t i = 0, offset = 0; i < recv_tgt_count; ++i) {
1098 send_results + i, (
void*)((
unsigned char*)send_pack_buffer + offset),
1099 send_pack_sizes[i], comm);
1100 offset += (size_t)(send_pack_sizes[i]);
1106 send_pack_buffer, sendcounts, sdispls,
1107 recv_pack_buffer, recvcounts, rdispls,
1108 1, MPI_PACKED, comm, __func__, __LINE__);
1111 for (
size_t i = 0, offset = 0; i < tgt_count; ++i) {
1113 (
void*)((
unsigned char*)recv_pack_buffer + offset),
1114 recv_pack_sizes[i], recv_results + i, comm);
1115 offset += (size_t)(recv_pack_sizes[i]);
1117 free(pack_size_buffer);
1121 recv_results, tgt_count,
sizeof(*recv_results),
1124 for (
size_t i = 0; i < tgt_count; ++i)
1129 recv_results, tgt_count,
sizeof(*recv_results),
1132 size_t new_num_links = 0;
1133 size_t new_total_num_links = 0;
1134 size_t new_num_fixed = 0;
1137 while ((i < tgt_count) && (recv_results[i].
type ==
LINK))
1140 while ((i < tgt_count) && (recv_results[i].
type ==
FIXED)) ++i;
1141 new_num_fixed = i - new_num_links;
1146 for (
size_t i = 0, offset = 0; i < new_num_links;
1148 memcpy(*
links + offset, recv_results[i].
data.link.links,
1150 *num_links = new_total_num_links;
1153 if (new_num_fixed > 0) {
1154 recv_results += new_num_links;
1156 recv_results, new_num_fixed,
sizeof(*recv_results),
1159 double curr_fixed_value =
1161 size_t num_fixed_values = 0;
1162 void * tgt_global_id_buffer =
1163 xrealloc((*num_fixed > 0)?(*fixed)->tgt:NULL,
1164 new_num_fixed *
sizeof(*((*fixed)->tgt)));
1166 for (
size_t i = 0, offset = 0; i < new_num_fixed; ++i) {
1169 &recv_results[i].
data.fixed.value, &curr_fixed_value,
1170 sizeof(curr_fixed_value))) {
1172 *fixed =
xrealloc(*fixed, (num_fixed_values + 1) *
sizeof(**fixed));
1173 curr_fixed = *fixed + num_fixed_values;
1175 curr_fixed->
value = curr_fixed_value;
1176 curr_fixed->
tgt = (
void*)(((
unsigned char *)tgt_global_id_buffer) +
1177 offset *
sizeof(*((*fixed)->tgt)));
1183 *num_fixed = num_fixed_values;
1184 recv_results -= new_num_links;
1187 if (*num_fixed > 0) free((*fixed)->tgt);
1193 for (
size_t i = 0; i < tgt_count; ++i)
1195 *num_interpolated_points = new_num_links + new_num_fixed;
1197 for (
size_t i = 0; i < new_num_links; ++i)
1198 free(recv_results[i].
data.link.links);
1199 free(result_buffer);
1202 free(size_t_buffer);
1203 free(tgt_global_ids);
1264 size_t * tgt_points,
size_t count,
1266 int * interpolation_complete) {
1268 if (*interpolation_complete)
return 0;
1284 int root_io_rank = io_ranks[0];
1290 "unsupported value for on_missing_file %d "
1291 "(has to be either YAC_INTERP_FILE_MISSING_ERROR(%d) or "
1292 "YAC_INTERP_FILE_MISSING_CONT (%d))",
1298 (comm_rank == root_io_rank) &&
1302 MPI_IN_PLACE, &file_exists, 1, MPI_INT, MPI_MAX, comm), comm);
1306 if ((comm_rank == root_io_rank) && !file_exists &&
1308 char const msg_fmt[] =
1309 "ERROR(do_search_file): weight file \"%s\" does not exist";
1312 yac_abort(comm, msg, __FILE__, __LINE__);
1324 xmalloc(num_src_fields *
sizeof(*src_locations));
1325 for (
size_t i = 0; i < num_src_fields; ++i)
1331 size_t num_links = 0;
1333 size_t num_fixed = 0;
1340 src_locations, tgt_location, num_src_fields,
1341 &links, &num_links, &fixed, &num_fixed);
1343 free(src_locations);
1349 size_t num_interpolated_points;
1351 interp_grid, tgt_points, count, &num_interpolated_points,
1352 &links, &num_links, &fixed, &num_fixed);
1354 size_t * tgt_points_reorder_idx =
1355 xmalloc(num_interpolated_points *
sizeof(*tgt_points_reorder_idx));
1356 for (
size_t i = 0; i < num_interpolated_points; ++i)
1357 tgt_points_reorder_idx[i] = i;
1359 size_t num_fixed_tgt = 0;
1361 for (
size_t i = 0; i < num_fixed; ++i) num_fixed_tgt += fixed[i].
num_tgt;
1363 size_t tgt_points_offset = num_interpolated_points - num_fixed_tgt;
1365 for (
size_t i = 0; i < num_fixed; ++i) {
1370 interp_grid, tgt_points + tgt_points_offset, fixed[i].num_tgt),
1375 tgt_points_offset += fixed[i].
num_tgt;
1381 size_t num_link_tgt = 0;
1382 if (num_links > 0) {
1385 for (
size_t link_idx = 0, tgt_idx = 0; link_idx < num_links; tgt_idx++) {
1388 size_t curr_local_id = tgt_points[tgt_idx];
1390 while ((link_idx < num_links) &&
1391 (links[link_idx].tgt.global_id == curr_global_id)) {
1401 size_t num_src_fields = links[num_links-1].
src_field_idx + 1;
1404 int int_num_src_fields = (int)num_src_fields;
1407 MPI_Allreduce(MPI_IN_PLACE, &int_num_src_fields, 1, MPI_INT, MPI_MAX,
1409 num_src_fields = (size_t)int_num_src_fields;
1412 yac_int * src_global_ids =
xmalloc(num_links *
sizeof(*src_global_ids));
1413 size_t * src_local_ids =
xmalloc(num_links *
sizeof(*src_local_ids));
1414 size_t src_field_prefix_sum[num_src_fields];
1418 for (
size_t src_field_idx = 0, link_idx = 0, offset = 0;
1419 src_field_idx < num_src_fields; ++src_field_idx) {
1421 size_t curr_num_links = 0;
1422 while ((link_idx < num_links) &&
1423 (links[link_idx].src_field_idx == src_field_idx)) {
1426 src_global_ids[offset + curr_num_links] =
1434 interp_grid, src_field_idx, src_global_ids + offset, curr_num_links,
1435 src_local_ids + offset);
1442 link_idx -= curr_num_links;
1443 if (src_mask != NULL) {
1444 for (
size_t i = 0; i < curr_num_links; ++i, ++link_idx)
1445 links[link_idx].
src.local_id =
1446 (src_mask[src_local_ids[link_idx]])?
1447 src_local_ids[link_idx]:SIZE_MAX;
1449 for (
size_t i = 0; i < curr_num_links; ++i, ++link_idx)
1450 links[link_idx].
src.local_id = src_local_ids[link_idx];
1453 src_field_prefix_sum[src_field_idx] = offset;
1454 offset += curr_num_links;
1461 size_t new_num_links = 0;
1462 int contains_masked_tgt = 0;
1463 num_link_tgt = num_interpolated_points - num_fixed_tgt;
1464 size_t * tgt_local_ids =
xmalloc(num_link_tgt *
sizeof(*tgt_local_ids));
1465 size_t * num_src_per_field_per_tgt =
1466 xcalloc(num_link_tgt * num_src_fields,
sizeof(*num_src_per_field_per_tgt));
1467 size_t num_links_per_src_field[num_src_fields];
1468 memset(num_links_per_src_field, 0,
sizeof(num_links_per_src_field));
1470 for (
size_t link_idx = 0, tgt_idx = 0; link_idx < num_links; ++tgt_idx) {
1472 size_t curr_tgt_local_id = links[link_idx].
tgt.
local_id;
1473 int is_masked = links[link_idx].
src.
local_id == SIZE_MAX;
1474 tgt_points[tgt_idx] = curr_tgt_local_id;
1479 while ((link_idx < num_links) &&
1480 (links[link_idx].tgt.local_id == curr_tgt_local_id)) ++link_idx;
1481 contains_masked_tgt = 1;
1482 tgt_points_reorder_idx[tgt_idx] += num_interpolated_points;
1486 size_t * curr_num_src_per_field_per_tgt =
1487 num_src_per_field_per_tgt + num_link_tgt * num_src_fields;
1488 if (contains_masked_tgt) {
1489 while ((link_idx < num_links) &&
1490 (links[link_idx].tgt.local_id == curr_tgt_local_id)) {
1493 src_field_prefix_sum[curr_src_field_idx] +
1494 num_links_per_src_field[curr_src_field_idx] +
1495 curr_num_src_per_field_per_tgt[curr_src_field_idx]++] =
1497 links[new_num_links++] = links[link_idx++];
1501 while ((link_idx < num_links) &&
1502 (links[link_idx].tgt.local_id == curr_tgt_local_id)) {
1505 src_field_prefix_sum[curr_src_field_idx] +
1506 num_links_per_src_field[curr_src_field_idx] +
1507 curr_num_src_per_field_per_tgt[curr_src_field_idx]++] =
1509 ++link_idx, ++new_num_links;
1512 for (
size_t i = 0; i < num_src_fields; ++i) {
1513 num_links_per_src_field[i] += curr_num_src_per_field_per_tgt[i];
1515 tgt_local_ids[num_link_tgt++] = curr_tgt_local_id;
1518 num_links = new_num_links;
1520 xrealloc(tgt_local_ids, num_link_tgt *
sizeof(*tgt_local_ids));
1521 num_src_per_field_per_tgt =
1523 num_src_per_field_per_tgt,
1524 num_link_tgt * num_src_fields *
sizeof(*num_src_per_field_per_tgt));
1528 for (
size_t src_field_idx = 0; src_field_idx < num_src_fields; ++src_field_idx)
1529 srcs_per_field[src_field_idx] =
1531 interp_grid, src_field_idx, src_local_ids + src_field_prefix_sum[src_field_idx],
1532 num_links_per_src_field[src_field_idx]);
1533 free(src_local_ids);
1539 double * w =
xmalloc(num_links *
sizeof(*w));
1540 for (
size_t link_idx = 0; link_idx < num_links; ++link_idx)
1541 w[link_idx] = links[link_idx].weight;
1546 interp_grid, tgt_local_ids, num_link_tgt),
1547 .count = num_link_tgt};
1548 free(tgt_local_ids);
1551 weights, &tgts, num_src_per_field_per_tgt, srcs_per_field, w, num_src_fields);
1554 for (
size_t i = 0; i < num_src_fields; ++i) free(srcs_per_field[i]);
1555 free(num_src_per_field_per_tgt);
1557 free(src_global_ids);
1560 int num_src_fields = 0;
1563 MPI_Allreduce(MPI_IN_PLACE, &num_src_fields, 1, MPI_INT, MPI_MAX,
1568 for (
int i = 0; i < num_src_fields; ++i)
1574 tgt_points_reorder_idx, num_interpolated_points, tgt_points);
1575 free(tgt_points_reorder_idx);
1581 "unsupported value for on_success %d "
1582 "(has to be either YAC_INTERP_FILE_SUCCESS_STOP(%d) or "
1583 "YAC_INTERP_FILE_SUCCESS_CONT (%d))",
1587 *interpolation_complete =
1592 return num_fixed_tgt + num_link_tgt;