32#define CHECK_LOCATION(caller) \
34 (location == YAC_LOC_CELL) || \
35 (location == YAC_LOC_CORNER) || \
36 (location == YAC_LOC_EDGE), \
37 "ERROR(%s): \"%d\" is not a invalid location", \
38 caller, (int)location)
40#define CHECK_GRID_NAME(caller, GRID_NAME) \
42 strcmp((GRID_NAME), yac_dist_grid_dummy_name), \
43 "ERROR(%s): grid name \"%s\" is a reserved dist-grid internal name", \
44 (caller), (GRID_NAME))
154 char const * caller,
yac_int * ids,
size_t * idx,
size_t num_ids,
155 yac_int * ref_sorted_ids,
size_t * ref_sorted_reorder_idx,
156 size_t num_sorted_ids) {
158 size_t * reorder =
xmalloc(num_ids *
sizeof(*reorder));
159 for (
size_t i = 0; i < num_ids; ++i) reorder[i] = i;
163 for (
size_t i = 0, j = 0; i < num_ids; ++i) {
166 while ((j < num_sorted_ids) && (ref_sorted_ids[j] < curr_id)) ++j;
168 (j < num_sorted_ids) && (ref_sorted_ids[j] == curr_id),
169 "ERROR(%s): id %" YAC_INT_FMT
" not found", caller, curr_id)
170 idx[reorder[i]] = ref_sorted_reorder_idx[j];
181 if (num_vertices == 0)
return SIZE_MAX;
186 size_t min_idx = vertices[0];
187 yac_int min_global_id = grid_vertex_ids[min_idx];
188 for (
int j = 1; j < num_vertices; ++j) {
189 size_t curr_vertex = vertices[j];
190 yac_int curr_global_id = grid_vertex_ids[curr_vertex];
191 if (min_global_id > curr_global_id) {
192 min_global_id = curr_global_id;
193 min_idx = curr_vertex;
202 struct yac_dist_grid * dist_grid,
int is_root,
int * vertex_owner_mask) {
213 (ref_vertex != SIZE_MAX)?(vertex_owner_mask[ref_vertex]):is_root;
216 return cell_owner_mask;
224 size_t * edge_vertices = &(dist_grid->
edge_to_vertex[edge_idx][0]);
226 return edge_vertices[
227 (vertex_ids[edge_vertices[0]] > vertex_ids[edge_vertices[1]])?1:0];
237 int * edge_owner_mask =
xmalloc(num_edges *
sizeof(*edge_owner_mask));
242 for (
size_t i = 0; i < num_edges; ++i)
246 return edge_owner_mask;
252 struct yac_dist_grid * dist_grid,
int comm_rank,
int * vertex_owner) {
256 int * vertex_owner_mask =
259 vertex_owner_mask[i] = vertex_owner_mask[i] == comm_rank;
273 MPI_Datatype id_pos_dt;
274 int array_of_blocklengths[] = {1,1};
275 const MPI_Aint array_of_displacements[] =
276 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
global_id) -
277 (MPI_Aint)(intptr_t)(
const void *)&dummy,
278 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
orig_pos) -
279 (MPI_Aint)(intptr_t)(
const void *)&dummy};
280 const MPI_Datatype array_of_types[] = {
yac_int_dt, MPI_UINT64_T};
282 MPI_Type_create_struct(
283 2, array_of_blocklengths, array_of_displacements,
284 array_of_types, &id_pos_dt), comm);
292 for (i = 0; i < n; ++i)
if (ids[i] >=
id)
break;
294 if (n != i) memmove(ids + i + 1, ids + i, (n - i) *
sizeof(*ids));
305 for (i = 0; i < n; ++i)
if (ranks[i] >= rank)
break;
309 if (ranks[i] == rank)
return;
310 else memmove(ranks + i + 1, ranks + i, ((
size_t)(n - i)) *
sizeof(*ranks));
317 const void * a,
const void * b) {
323 int ret = count_a - count_b;
324 for (
int i = 0; !ret && (i < count_a); ++i)
325 ret = (a_ids[i] > b_ids[i]) - (a_ids[i] < b_ids[i]);
330 const void * a,
const void * b) {
344 int * dist_cell_rank_counts,
size_t * dist_cell_rank_offsets,
345 int max_num_vertices_per_cell) {
351 int * ranks_buffer =
xmalloc((
size_t)comm_size *
sizeof(*ranks_buffer));
352 size_t dist_cell_ranks_array_size =
num_cells;
356 int * core_cell_mask =
grid_data->core_cell_mask;
367 size_t * cell_to_vertex_offsets =
grid_data->cell_to_vertex_offsets;
368 size_t * cell_to_edge =
grid_data->cell_to_edge;
369 size_t * cell_to_edge_offsets =
grid_data->cell_to_edge_offsets;
381 if ((core_cell_mask == NULL) || core_cell_mask[i]) {
389 size_t * curr_cell_to_vertex =
391 size_t * curr_cell_to_edge =
392 cell_to_edge + cell_to_edge_offsets[i];
393 for (
int j = 0; j < num_vertices_per_cell[i]; ++j) {
395 vertex_coordinates + curr_cell_to_vertex[j];
396 for (
int k = 0; k < 3; ++k)
409 proc_sphere_part, bnd_circle, ranks_buffer, &rank_count);
422 offset + (
size_t)rank_count);
423 memcpy(dist_cell_ranks_ + offset, ranks_buffer,
424 (
size_t)rank_count *
sizeof(*ranks_buffer));
426 dist_cell_rank_counts[i] = rank_count;
427 dist_cell_rank_offsets[i] = offset;
428 offset += (size_t)rank_count;
432 dist_cell_rank_offsets[
num_cells] = offset;
438 *dist_cell_ranks = dist_cell_ranks_;
444 int max_num_vertices_per_cell, MPI_Comm comm) {
446 char const * routine =
"generate_ce_ids";
453 int comm_rank, comm_size;
459 int ids_available_local[2], ids_available_global[2];
460 ids_available_local[0] =
462 ids_available_local[1] =
463 (num_edges > 0) && (
grid_data->edge_ids != NULL);
464 yac_mpi_call(MPI_Allreduce(ids_available_local, ids_available_global, 2,
465 MPI_INT, MPI_MAX, comm), comm);
469 (ids_available_local[0] == ids_available_global[0]),
470 "ERROR(%s): inconsistent global ids", routine)
474 (ids_available_local[1] == ids_available_global[1]),
475 "ERROR(%s): inconsistent global ids", routine)
478 if (ids_available_global[0] && ids_available_global[1])
return;
482 (((ids_available_global[0])?0:(
num_cells)) +
483 ((ids_available_global[1])?0:(num_edges))) *
484 sizeof(*rank_buffer));
485 int * cell_ranks = rank_buffer;
487 rank_buffer + ((ids_available_global[0])?0:(
num_cells));
489 size_t * size_t_buffer =
490 xmalloc((8 * (
size_t)comm_size + 1) *
sizeof(*size_t_buffer));
491 size_t * sendcounts = size_t_buffer + 0 * comm_size;
492 size_t * recvcounts = size_t_buffer + 2 * comm_size;
493 size_t * total_sendcounts = size_t_buffer + 4 * comm_size;
494 size_t * total_recvcounts = size_t_buffer + 5 * comm_size;
495 size_t * total_sdispls = size_t_buffer + 6 * comm_size;
496 size_t * total_rdispls = size_t_buffer + 7 * comm_size + 1;
497 memset(sendcounts, 0, 2 * (
size_t)comm_size *
sizeof(*sendcounts));
499 yac_int * cell_to_vertex_ids = NULL;
501 if (!ids_available_global[0]) {
505 size_t * cell_to_vertex_offsets =
grid_data->cell_to_vertex_offsets;
509 sizeof(*cell_to_vertex_ids));
513 int curr_num_vertices = num_vertices_per_cell[i];
514 yac_int * curr_cell_to_vertex_ids =
515 cell_to_vertex_ids + i * max_num_vertices_per_cell;
518 if (curr_num_vertices > 0) {
519 size_t * curr_cell_vertices =
521 size_t min_vertex = curr_cell_vertices[0];
522 curr_cell_to_vertex_ids[0] = vertex_ids[min_vertex];
523 for (
int j = 1; j < curr_num_vertices; ++j) {
524 size_t curr_vertex_idx = curr_cell_vertices[j];
525 yac_int curr_vertex_id = vertex_ids[curr_vertex_idx];
527 if (curr_cell_to_vertex_ids[0] == curr_vertex_id)
528 min_vertex = curr_vertex_idx;
530 cell_rank = vertex_ranks[min_vertex];
534 for (
int j = curr_num_vertices; j < max_num_vertices_per_cell; ++j)
535 curr_cell_to_vertex_ids[j] = YAC_INT_MAX;
537 sendcounts[2 * ((cell_ranks[i] = cell_rank)) + 0]++;
541 yac_int * edge_to_vertex_ids = NULL;
543 if (!ids_available_global[1]) {
546 xmalloc(2 * num_edges *
sizeof(*edge_to_vertex_ids));
549 for (
size_t i = 0; i < num_edges; ++i) {
551 size_t * curr_edge_to_vertex = edge_to_vertex[i];
552 yac_int * curr_edge_vertex_ids = edge_to_vertex_ids + 2 * i;
553 curr_edge_vertex_ids[0] = vertex_ids[curr_edge_to_vertex[0]];
554 curr_edge_vertex_ids[1] = vertex_ids[curr_edge_to_vertex[1]];
556 if (curr_edge_vertex_ids[0] > curr_edge_vertex_ids[1]) {
557 yac_int temp = curr_edge_vertex_ids[0];
558 curr_edge_vertex_ids[0] = curr_edge_vertex_ids[1];
559 curr_edge_vertex_ids[1] = temp;
561 2 * ((edge_ranks[i] = vertex_ranks[curr_edge_to_vertex[1]])) + 1]++;
564 2 * ((edge_ranks[i] = vertex_ranks[curr_edge_to_vertex[0]])) + 1]++;
573 total_sdispls[0] = 0;
574 size_t recv_counts[2] = {0,0};
575 size_t saccu = 0, raccu = 0;
576 for (
int i = 0; i < comm_size; ++i) {
577 total_sdispls[i+1] = saccu;
578 total_rdispls[i] = raccu;
579 recv_counts[0] += recvcounts[2 * i + 0];
580 recv_counts[1] += recvcounts[2 * i + 1];
581 total_sendcounts[i] = sendcounts[2 * i + 0] *
582 (size_t)max_num_vertices_per_cell +
583 sendcounts[2 * i + 1] * 2;
584 total_recvcounts[i] = recvcounts[2 * i + 0] *
585 (size_t)max_num_vertices_per_cell +
586 recvcounts[2 * i + 1] * 2;
587 saccu += total_sendcounts[i];
588 raccu += total_recvcounts[i];
590 size_t local_data_count = total_sendcounts[comm_size - 1] +
591 total_sdispls[comm_size];
592 size_t recv_count = total_recvcounts[comm_size - 1] +
593 total_rdispls[comm_size - 1];
596 xcalloc((local_data_count + recv_count),
sizeof(*yac_int_buffer));
601 if (!ids_available_global[0])
603 for (
int j = 0; j < max_num_vertices_per_cell; ++j)
605 cell_to_vertex_ids[i * max_num_vertices_per_cell + j];
606 if (!ids_available_global[1])
607 for (
size_t i = 0; i < num_edges; ++i)
608 for (
int j = 0; j < 2; ++j)
610 edge_to_vertex_ids[2 * i + j];
612 free(edge_to_vertex_ids);
613 free(cell_to_vertex_ids);
616 yac_alltoallv_yac_int_p2p(
618 recv_buffer, total_recvcounts, total_rdispls, comm, routine, __LINE__);
621 xmalloc((recv_counts[0] + recv_counts[1]) *
sizeof(*n_ids_reorder_buffer));
623 {n_ids_reorder_buffer, n_ids_reorder_buffer + recv_counts[0]};
626 int index_counts[2] = {max_num_vertices_per_cell, 2};
630 for (
int i = 0; i < comm_size; ++i) {
631 for (
int j = 0; j < 2; ++j) {
632 size_t curr_count = recvcounts[2 * i + j];
633 for (
size_t k = 0; k < curr_count;
638 offset += index_counts[j];
643 for (
int i = 0; i < 2; ++i) {
645 if (ids_available_global[i])
continue;
650 size_t unique_count = recv_counts[i] > 0;
654 for (
size_t j = 0; j < recv_counts[i]; ++j, ++curr) {
663 unique_count <= (
size_t)YAC_INT_MAX,
664 "ERROR(%s): global_id out of bounds", routine)
671 MPI_SUM, comm), comm);
672 if (comm_rank == 0) id_offset = 0;
675 ((
size_t)id_offset + unique_count) <= (
size_t)YAC_INT_MAX,
676 "ERROR(%s): global_id out of bounds", routine)
679 for (
size_t j = 0; j < recv_counts[i]; ++j)
682 free(yac_int_buffer);
684 qsort(n_ids_reorder_buffer, recv_counts[0] + recv_counts[1],
688 xmalloc((recv_counts[0] + recv_counts[1] +
689 ((ids_available_global[0])?0:(
num_cells)) +
690 ((ids_available_global[1])?0:(num_edges))) *
691 sizeof(*global_ids_buffer));
692 yac_int * send_global_ids = global_ids_buffer;
694 global_ids_buffer + recv_counts[0] + recv_counts[1];
696 for (
size_t i = 0; i < recv_counts[0] + recv_counts[1]; ++i)
697 send_global_ids[i] = n_ids_reorder_buffer[i].
global_id;
698 free(n_ids_reorder_buffer);
701 saccu = 0, raccu = 0;
702 for (
int i = 0; i < comm_size; ++i) {
703 total_sdispls[i] = saccu;
704 total_rdispls[i] = raccu;
706 ((total_sendcounts[i] = recvcounts[2 * i + 0] + recvcounts[2 * i + 1]));
708 ((total_recvcounts[i] = sendcounts[2 * i + 0] + sendcounts[2 * i + 1]));
712 yac_alltoallv_yac_int_p2p(
713 send_global_ids, total_sendcounts, total_sdispls,
714 recv_global_ids, total_recvcounts, total_rdispls, comm,
717 if ((!ids_available_global[0]) && (
num_cells > 0))
720 if ((!ids_available_global[1]) && (num_edges > 0))
725 if (!ids_available_global[0])
728 recv_global_ids[total_rdispls[cell_ranks[i]]++];
729 if (!ids_available_global[1])
730 for (
size_t i = 0; i < num_edges; ++i)
732 recv_global_ids[total_rdispls[edge_ranks[i]]++];
736 free(global_ids_buffer);
780 "ERROR: inconsistent edge core mask for grid \"%s\" "
781 "(edge %" YAC_INT_FMT
" is valid but one of its vertices is not)",
823 for (
int k = 0; k < curr_num_edges; ++k) {
826 "ERROR: inconsistent cell core mask for grid \"%s\" "
827 "(cell %" YAC_INT_FMT
" is valid but edge %" YAC_INT_FMT
" is not)",
842 for (
int k = 0; k < curr_num_edges; ++k)
853 int max_num_vertices_per_cell, MPI_Comm comm) {
859 "ERROR(generate_global_ids): internal error grid \"%s\" does not "
877 edge_to_cell[i][0] = SIZE_MAX;
878 edge_to_cell[i][1] = SIZE_MAX;
881 for (
size_t i = 0, offset = 0; i <
num_cells; ++i) {
883 size_t curr_num_edges = num_edges_per_cell[i];
885 offset += curr_num_edges;
889 for (
size_t j = 0; j < curr_num_edges; ++j) {
891 size_t curr_edge = curr_cell_to_edge[j];
892 size_t * curr_edge_to_cell = edge_to_cell[curr_edge];
893 curr_edge_to_cell += *curr_edge_to_cell != SIZE_MAX;
895 *curr_edge_to_cell == SIZE_MAX,
896 "ERROR(generate_edge_to_cell): "
897 "more than two cells point to a single edge "
898 "(does the grid contain degenrated cells (less than 3 corners) "
899 "or duplicated cells; "
900 "these can be masked out using the core mask)\n"
901 "(num_cells: %zu cell_idx: %zu: num_cell_edge %zu)",
903 *curr_edge_to_cell = i;
917 size_t * curr_edge_to_vertex = edge_to_vertex[edge_id];
918 double * vertices[2] =
919 {vertex_coordinates[curr_edge_to_vertex[0]],
920 vertex_coordinates[curr_edge_to_vertex[1]]};
922 bnd_circle.
base_vector[0] = vertices[0][0] + vertices[1][0];
923 bnd_circle.
base_vector[1] = vertices[0][1] + vertices[1][1];
924 bnd_circle.
base_vector[2] = vertices[0][2] + vertices[1][2];
928 bnd_circle.
sq_crd = DBL_MAX;
936 size_t * dist_cell_rank_offsets,
size_t * dist_edge_rank_offsets,
937 int * num_cell_ranks,
int * num_edge_ranks,
938 int ** rank_buffer,
size_t * rank_buffer_array_size) {
948 size_t dist_edge_rank_offset = dist_cell_rank_offsets[
num_cells];
960 int edge_rank_count = 0;
965 int cell_rank_counts[2] = {0, 0};
966 size_t * curr_edge_cells = edge_to_cell[i];
968 for (
int j = 0; j < 2; ++j)
969 if (curr_edge_cells[j] != SIZE_MAX)
971 ((cell_rank_counts[j] = num_cell_ranks[curr_edge_cells[j]]));
974 if (edge_rank_count > 0) {
977 *rank_buffer, *rank_buffer_array_size,
978 dist_edge_rank_offset + edge_rank_count);
980 int * curr_edge_ranks = *rank_buffer + dist_edge_rank_offset;
984 for (
int j = 0; j < 2; ++j) {
985 if (cell_rank_counts[j] > 0) {
987 *rank_buffer + dist_cell_rank_offsets[curr_edge_cells[j]];
988 for (
int k = 0; k < cell_rank_counts[j]; ++k)
990 curr_edge_ranks, &edge_rank_count, cell_ranks[k]);
997 *rank_buffer, *rank_buffer_array_size,
998 dist_edge_rank_offset + comm_size);
1000 int * curr_edge_ranks = *rank_buffer + dist_edge_rank_offset;
1008 curr_edge_ranks, &edge_rank_count);
1012 dist_edge_rank_offset += (size_t)edge_rank_count;
1013 num_edge_ranks[i] = edge_rank_count;
1015 dist_edge_rank_offsets[i+1] = dist_edge_rank_offset;
1023 size_t * vertex_to_edge,
int * num_edges_per_vertex) {
1026 num_edges_per_vertex, 0,
num_vertices *
sizeof(*num_edges_per_vertex));
1028 for (
size_t i = 0; i <
num_edges; ++i) {
1033 size_t * vertex_edges_offsets =
1036 vertex_edges_offsets[0] = 0;
1037 for (
size_t i = 0, offset = 0; i <
num_vertices; ++i) {
1038 vertex_edges_offsets[i + 1] = offset;
1039 offset += (size_t)(num_edges_per_vertex[i]);
1042 for (
size_t i = 0; i <
num_edges; ++i) {
1043 for (
int j = 0; j < 2; ++j) {
1045 vertex_to_edge[vertex_edges_offsets[curr_vertex+1]] = i;
1046 vertex_edges_offsets[curr_vertex+1]++;
1050 free(vertex_edges_offsets);
1055 size_t * dist_edge_rank_offsets,
int * num_edge_ranks,
int * num_vertex_ranks,
1056 int ** rank_buffer,
size_t * rank_buffer_array_size) {
1065 size_t vertex_rank_offset = dist_edge_rank_offsets[
num_edges];
1069 size_t * vertex_to_edge =
xmalloc(2 *
num_edges *
sizeof(*vertex_to_edge));
1070 int * num_edges_per_vertex =
1074 vertex_to_edge, num_edges_per_vertex);
1075 size_t * curr_edges = vertex_to_edge;
1080 int vertex_rank_count = 0;
1081 int curr_num_edges = num_edges_per_vertex[i];
1086 for (
int j = 0; j < curr_num_edges; ++j)
1087 vertex_rank_count += num_edge_ranks[curr_edges[j]];
1090 if (vertex_rank_count > 0) {
1093 *rank_buffer, *rank_buffer_array_size,
1094 vertex_rank_offset + vertex_rank_count);
1096 int * curr_vertex_ranks = *rank_buffer + vertex_rank_offset;
1099 vertex_rank_count = 0;
1100 for (
int j = 0; j < curr_num_edges; ++j) {
1101 size_t curr_edge = curr_edges[j];
1102 int curr_num_edge_ranks = num_edge_ranks[curr_edge];
1103 int * curr_edge_ranks =
1104 *rank_buffer + dist_edge_rank_offsets[curr_edge];
1105 for (
int k = 0; k < curr_num_edge_ranks; ++k)
1107 curr_vertex_ranks, &vertex_rank_count, curr_edge_ranks[k]);
1113 *rank_buffer, *rank_buffer_array_size, vertex_rank_offset + 1);
1115 int * curr_vertex_ranks = *rank_buffer + vertex_rank_offset;
1117 *curr_vertex_ranks = vertex_ranks[i];
1118 vertex_rank_count = 1;
1122 vertex_rank_offset += (size_t)vertex_rank_count;
1123 num_vertex_ranks[i] = vertex_rank_count;
1124 curr_edges += curr_num_edges;
1127 free(num_edges_per_vertex);
1128 free(vertex_to_edge);
1132 const void * a,
const void * b) {
1146 int max_num_vertices_per_cell, MPI_Comm comm,
1148 size_t * dist_count) {
1150 char const * routine =
"generate_dist_remote_points";
1159 int * num_ranks_buffer =
1162 int * num_cell_ranks = num_ranks_buffer;
1163 int * num_vertex_ranks = num_ranks_buffer +
num_cells;
1165 size_t * dist_rank_offsets =
1167 size_t * dist_cell_rank_offsets = dist_rank_offsets;
1168 size_t * dist_edge_rank_offsets = dist_rank_offsets +
num_cells;
1179 &rank_buffer, num_cell_ranks, dist_cell_rank_offsets, max_num_vertices_per_cell);
1181 size_t rank_buffer_array_size = dist_cell_rank_offsets[
num_cells];
1189 proc_sphere_part, grid, comm, dist_cell_rank_offsets, dist_edge_rank_offsets,
1190 num_cell_ranks, num_edge_ranks, &rank_buffer, &rank_buffer_array_size);
1198 vertex_ranks, grid, comm, dist_edge_rank_offsets,
1199 num_edge_ranks, num_vertex_ranks, &rank_buffer, &rank_buffer_array_size);
1201 int * dist_cell_ranks = rank_buffer;
1202 int * dist_vertex_ranks = rank_buffer + dist_edge_rank_offsets[
num_edges];
1203 int * dist_edge_ranks = rank_buffer + dist_cell_rank_offsets[
num_cells];
1205 free(dist_rank_offsets);
1215 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1217 3, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1218 size_t * size_t_buffer =
1219 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
1220 size_t * total_sendcounts = size_t_buffer + 0 * comm_size;
1221 size_t * total_recvcounts = size_t_buffer + 1 * comm_size;
1222 size_t * total_sdispls = size_t_buffer + 2 * comm_size;
1223 size_t * total_rdispls = size_t_buffer + 3 * comm_size;
1232 .ranks = dist_cell_ranks,
1233 .num_ranks = num_cell_ranks,
1235 {.count = num_vertices,
1236 .ranks = dist_vertex_ranks,
1237 .num_ranks = num_vertex_ranks,
1239 {.count = num_edges,
1240 .ranks = dist_edge_ranks,
1241 .num_ranks = num_edge_ranks,
1247 size_t count = cve_data[
location].count;
1248 int * ranks = cve_data[
location].ranks;
1249 int * num_ranks = cve_data[
location].num_ranks;
1250 for (
size_t i = 0, k = 0; i < count; ++i) {
1251 int curr_num_ranks = num_ranks[i];
1252 for (
int j = 0; j < curr_num_ranks; ++j, ++k)
1253 sendcounts[3 * ranks[k] +
location]++;
1258 3, sendcounts, recvcounts, sdispls, rdispls, comm);
1260 size_t receive_counts[3] = {0,0,0};
1261 size_t saccu = 0, raccu = 0;
1262 for (
int i = 0; i < comm_size; ++i) {
1263 total_sdispls[i] = saccu;
1264 total_rdispls[i] = raccu;
1265 total_sendcounts[i] = 0;
1266 total_recvcounts[i] = 0;
1268 total_sendcounts[i] += sendcounts[3 * i +
location];
1269 total_recvcounts[i] += recvcounts[3 * i +
location];
1272 saccu += total_sendcounts[i];
1273 raccu += total_recvcounts[i];
1275 size_t local_data_count = total_sendcounts[comm_size - 1] +
1276 total_sdispls[comm_size - 1];
1277 size_t recv_count = total_recvcounts[comm_size - 1] +
1278 total_rdispls[comm_size - 1];
1280 struct id_pos * id_pos_buffer =
1281 xcalloc((local_data_count + recv_count),
sizeof(*id_pos_buffer));
1282 struct id_pos * id_pos_send_buffer = id_pos_buffer;
1283 struct id_pos * id_pos_recv_buffer =
1284 id_pos_buffer + local_data_count;
1288 size_t count = cve_data[
location].count;
1289 int * ranks = cve_data[
location].ranks;
1290 int * num_ranks = cve_data[
location].num_ranks;
1292 for (
size_t i = 0, k = 0; i < count; ++i) {
1293 int curr_num_ranks = num_ranks[i];
1295 for (
int j = 0; j < curr_num_ranks; ++j, ++k) {
1296 size_t pos = sdispls[3 * ranks[k] +
location + 1]++;
1298 id_pos_send_buffer[pos].
orig_pos = i;
1302 free(num_ranks_buffer);
1309 id_pos_send_buffer, total_sendcounts, total_sdispls,
1310 id_pos_recv_buffer, total_recvcounts, total_rdispls,
1311 sizeof(*id_pos_send_buffer), id_pos_dt, comm,
1316 size_t dist_owner_counts[3] = {0, 0, 0};
1317 for (
int i = 0; i < comm_size; ++i)
1320 size_t max_dist_owner_count =
1321 MAX(
MAX(dist_owner_counts[0], dist_owner_counts[1]), dist_owner_counts[2]);
1323 xcalloc(max_dist_owner_count,
sizeof(*temp_buffer));
1331 for (
int i = 0; i < comm_size; ++i) {
1332 size_t curr_recvcount = recvcounts[3 * i +
location];
1333 struct id_pos * curr_id_pos =
1334 id_pos_recv_buffer + rdispls[3 * i +
location];
1335 for (
size_t k = 0; k < curr_recvcount; ++k, ++count) {
1343 qsort(temp_buffer, count,
sizeof(*temp_buffer),
1346 unique_ids =
xrealloc(unique_ids, count *
sizeof(*unique_ids));
1347 size_t num_unique_ids = 0;
1351 for (
size_t i = 0; i < count; ++i) {
1354 if (curr_id != prev_id) {
1356 unique_ids[num_unique_ids].
global_id = curr_id;
1357 unique_ids[num_unique_ids].
data.
count = 1;
1360 unique_ids[num_unique_ids-1].
data.
count++;
1370 dist_count[
location] = num_unique_ids;
1375 for (
size_t i = 0, l = 0; i < num_unique_ids; ++i) {
1376 global_ids[i] = unique_ids[i].
global_id;
1377 int curr_count = unique_ids[i].
data.
count;
1378 point_infos[i].
count = curr_count;
1379 if (curr_count == 1) {
1385 (
size_t)curr_count *
1386 sizeof(*(point_infos[i].
data.multi)));
1387 for (
int k = 0; k < curr_count; ++k, ++l) {
1395 free(id_pos_buffer);
1397 free(size_t_buffer);
1403 yac_int ** sorted_global_ids,
size_t ** reorder_idx) {
1405 *sorted_global_ids =
xmalloc(
count *
sizeof(**sorted_global_ids));
1406 memcpy(*sorted_global_ids, global_ids,
count *
sizeof(**sorted_global_ids));
1408 for (
size_t i = 0; i <
count; ++i) (*reorder_idx)[i] = i;
1412 const void * a,
const void * b) {
1421 const void * a,
const void * b) {
1431 MPI_Datatype coord_dt;
1432 yac_mpi_call(MPI_Type_contiguous(3, MPI_DOUBLE, &coord_dt), comm);
1443 uint64_t counts[2], max_counts[2];
1444 if (orig_field_data != NULL) {
1453 counts, max_counts, 2, MPI_UINT64_T, MPI_MAX, comm), comm);
1455 (orig_field_data == NULL) ||
1456 ((counts[0] == max_counts[0]) && (counts[1] == max_counts[1])),
1457 "ERROR(field_data_init): inconsistent number of masks or coordinates")
1459 int * data_available_flag =
1460 xcalloc(2 * max_counts[0] + max_counts[1],
sizeof(*data_available_flag));
1462 for (
size_t i = 0; i < counts[0]; ++i) {
1463 data_available_flag[i] =
1465 data_available_flag[i + counts[0]] =
1469 for (
size_t i = 0; i < counts[1]; ++i)
1470 data_available_flag[i + 2 * counts[0]] =
1475 MPI_IN_PLACE, data_available_flag,
1476 (
int)(2 * max_counts[0] + max_counts[1]), MPI_INT, MPI_MAX, comm), comm);
1478 for (
size_t i = 0; i < counts[0]; ++i) {
1480 data_available_flag[i] ==
1482 "ERROR(field_data_init): inconsistent availability of masks")
1487 data_available_flag[i + counts[0]] ==
1489 "ERROR(field_data_init): inconsistent mask names")
1492 for (
size_t i = 0; i < counts[1]; ++i)
1494 data_available_flag[i + 2 * counts[0]] ==
1496 "ERROR(field_data_init): inconsistent availability of coordinates")
1498 for (uint64_t i = 0; i < max_counts[0]; ++i) {
1499 int * dist_mask = NULL;
1500 if (data_available_flag[i]) {
1501 dist_mask =
xmalloc(dist_size *
sizeof(*dist_mask));
1502 int const * orig_mask =
1503 (orig_field_data != NULL)?
1505 xt_redist_s_exchange1(redist_mask, orig_mask, dist_mask);
1508 int mask_name_len = data_available_flag[i + max_counts[0]];
1509 char * mask_name = NULL;
1510 if (mask_name_len > 0) {
1511 mask_name =
xmalloc((
size_t)mask_name_len *
sizeof(*mask_name));
1512 if ((orig_field_data != NULL) &&
1516 (
size_t)mask_name_len);
1518 memset(mask_name, 0, (
size_t)mask_name_len *
sizeof(*mask_name));
1521 MPI_IN_PLACE, mask_name, mask_name_len, MPI_CHAR, MPI_MAX, comm),
1524 (orig_field_data == NULL) ||
1528 (
size_t)mask_name_len *
sizeof(*mask_name)),
1529 "ERROR(field_data_init): inconsistent mask names")
1534 for (uint64_t i = 0; i < max_counts[1]; ++i) {
1536 if (data_available_flag[i + 2 * max_counts[0]]) {
1537 dist_coordinates =
xmalloc(dist_size *
sizeof(*dist_coordinates));
1539 (orig_field_data != NULL)?
1541 xt_redist_s_exchange1(redist_coords, orig_coordinates, dist_coordinates);
1546 free(data_available_flag);
1548 return dist_field_data;
1554 MPI_Comm comm, MPI_Datatype dt_coord,
int * vertex_ranks,
1572 xt_redist_s_exchange1(
1577 xt_redist_s_exchange1(redist_vertex_int, vertex_ranks, vertex_owner);
1583 redist_vertex_int, redist_vertex_coords, comm);
1585 xt_redist_delete(redist_vertex_int);
1586 xt_redist_delete(redist_vertex_coords);
1588 *vertex_coordinates_ = vertex_coordinates;
1589 *vertex_owner_ = vertex_owner;
1590 *vertex_field_data_ = vertex_field_data;
1596 MPI_Datatype dt_coord,
size_t num_vertices,
yac_int * sorted_vertex_ids,
1597 size_t * sorted_vertex_reorder_idx,
1607 MPI_Datatype dt_2yac_int;
1618 int * temp_edge_type_src, * temp_edge_type_dst;
1619 if (
sizeof(*
edge_type) ==
sizeof(
int)) {
1620 temp_edge_type_src = (
int*)(
grid_data->edge_type);
1623 temp_edge_type_src =
1625 for (
size_t i = 0; i <
grid_data->num_edges; ++i)
1626 temp_edge_type_src[i] = (
int)(
grid_data->edge_type[i]);
1629 temp_edge_type_dst[i] = (
int)(
edge_type[i]);
1632 xt_redist_s_exchange1(
1633 redist_edge_int, temp_edge_type_src, temp_edge_type_dst);
1635 if (
sizeof(*
edge_type) !=
sizeof(
int)) {
1640 free(temp_edge_type_src);
1641 free(temp_edge_type_dst);
1651 yac_int * grid_edge_vertex_ids = vertex_id_buffer;
1654 size_t * grid_edge_to_vertex = &(
grid_data->edge_to_vertex[0][0]);
1656 for (
size_t i = 0; i < 2 *
grid_data->num_edges; ++i)
1657 grid_edge_vertex_ids[i] =
1658 grid_data->vertex_ids[grid_edge_to_vertex[i]];
1660 xt_redist_s_exchange1(
1661 redist_edge_2yac_int, grid_edge_vertex_ids, edge_vertex_ids);
1664 "redistribute_edge_data", edge_vertex_ids,
1666 sorted_vertex_ids, sorted_vertex_reorder_idx,
num_vertices);
1668 free(vertex_id_buffer);
1675 redist_edge_int, redist_edge_coords, comm);
1677 xt_redist_delete(redist_edge_2yac_int);
1678 xt_redist_delete(redist_edge_coords);
1679 xt_redist_delete(redist_edge_int);
1681 *edge_to_vertex_ = edge_to_vertex;
1682 *edge_type_ = edge_type;
1683 *edge_field_data_ = edge_field_data;
1689 MPI_Datatype dt_coord,
1690 size_t num_edges,
yac_int * sorted_edge_ids,
1691 size_t * sorted_edge_reorder_idx,
1692 size_t num_vertices,
yac_int * sorted_vertex_ids,
1693 size_t * sorted_vertex_reorder_idx,
int max_num_vertices_per_cell,
1694 size_t ** cell_to_vertex_,
size_t ** cell_to_edge_,
1695 int ** num_vertices_per_cell_,
struct yac_field_data ** cell_field_data_) {
1703 MPI_Datatype dt_yac_ints;
1705 MPI_Type_contiguous(
1706 max_num_vertices_per_cell,
yac_int_dt, &dt_yac_ints), comm);
1720 (
size_t)max_num_vertices_per_cell *
1723 id_buffer + (size_t)max_num_vertices_per_cell *
num_cells;
1724 size_t total_num_ids = 0;
1726 size_t grid_num_cells =
grid_data->num_cells;
1730 size_t * grid_cell_to_ve_offests =
grid_data->cell_to_vertex_offsets;
1732 yac_int * sorted_ve_ids = sorted_vertex_ids;
1733 size_t * sorted_ve_reorder_idx = sorted_vertex_reorder_idx;
1740 for (
size_t i = 0, k = 0; i < grid_num_cells; ++i) {
1741 int curr_num_ve_per_cell = grid_num_ve_per_cell[i];
1742 size_t * curr_cell_to_ve = grid_cell_to_ve + grid_cell_to_ve_offests[i];
1743 for (
int j = 0; j < curr_num_ve_per_cell; ++j, ++k)
1744 grid_id_buffer[k] = grid_ids[curr_cell_to_ve[j]];
1745 for (
int j = curr_num_ve_per_cell; j < max_num_vertices_per_cell; ++j, ++k)
1746 grid_id_buffer[k] = YAC_INT_MAX;
1750 xt_redist_s_exchange1(
1751 redist_cell_yac_ints, grid_id_buffer, id_buffer);
1757 for (
size_t i = 0; i <
num_cells; ++i) {
1760 id_buffer + i * (size_t)max_num_vertices_per_cell;
1761 for (vertex_count = 0; vertex_count < max_num_vertices_per_cell;
1763 if (
vertex_ids[vertex_count] == YAC_INT_MAX)
break;
1764 compact_flag |= vertex_count != max_num_vertices_per_cell;
1766 total_num_ids += (size_t)vertex_count;
1772 for (
size_t i = 0, j = 0; j < total_num_ids; ++i) {
1773 yac_int curr_id = id_buffer[i];
1774 if (curr_id != YAC_INT_MAX) {
1775 id_buffer[j] = curr_id;
1782 size_t * cell_to_ve =
1783 ((*cell_to_ve_ =
xmalloc(total_num_ids *
sizeof(*cell_to_ve))));
1785 "redistribute_cell_data", id_buffer, cell_to_ve, total_num_ids,
1786 sorted_ve_ids, sorted_ve_reorder_idx, num_ve);
1790 grid_cell_to_ve =
grid_data->cell_to_edge;
1791 grid_cell_to_ve_offests =
grid_data->cell_to_edge_offsets;
1793 sorted_ve_ids = sorted_edge_ids;
1794 sorted_ve_reorder_idx = sorted_edge_reorder_idx;
1805 redist_cell_int, redist_cell_coords, comm);
1807 xt_redist_delete(redist_cell_coords);
1808 xt_redist_delete(redist_cell_yac_ints);
1809 xt_redist_delete(redist_cell_int);
1812 *cell_to_edge_ = cell_to_edge;
1813 *num_vertices_per_cell_ = num_vertices_per_cell;
1814 *cell_field_data_ = cell_field_data;
1818 size_t num_cells,
int max_num_vertices_per_cell,
int * num_vertices_per_cell,
1821 size_t * cell_to_edge,
size_t * cell_to_edge_offsets,
1833 for (
size_t i = 0; i <
num_cells; ++i) {
1834 size_t * curr_cell_to_vertex =
1836 size_t * curr_cell_to_edge =
1837 cell_to_edge + cell_to_edge_offsets[i];
1838 for (
int j = 0; j < num_vertices_per_cell[i]; ++j) {
1840 vertex_coordinates + curr_cell_to_vertex[j];
1841 for (
int k = 0; k < 3; ++k)
1849 cell_bnd_circles[i] =
1859 return cell_bnd_circles;
1871 int * core_cell_mask =
grid_data->core_cell_mask;
1873 int max_num_vertices_per_cell = 0;
1876 if (core_cell_mask) {
1878 if (core_cell_mask[i] &&
1879 (num_vertices_per_cell[i] > max_num_vertices_per_cell))
1880 max_num_vertices_per_cell = num_vertices_per_cell[i];
1883 if (num_vertices_per_cell[i] > max_num_vertices_per_cell)
1884 max_num_vertices_per_cell = num_vertices_per_cell[i];
1889 MPI_IN_PLACE, &max_num_vertices_per_cell, 1, MPI_INT, MPI_MAX, comm),
1892 return max_num_vertices_per_cell;
1905 int max_num_vertices_per_cell =
1915 grid, vertex_ranks, max_num_vertices_per_cell, comm);
1922 size_t dist_count[3];
1924 proc_sphere_part, grid, vertex_ranks, max_num_vertices_per_cell, comm,
1925 dist_point_infos, dist_global_ids, dist_count);
1935 yac_int * sorted_cell_ids, * sorted_vertex_ids, * sorted_edge_ids;
1936 size_t * sorted_cell_reorder_idx, * sorted_vertex_reorder_idx,
1937 * sorted_edge_reorder_idx;
1939 cell_ids,
num_cells, &sorted_cell_ids, &sorted_cell_reorder_idx);
1941 vertex_ids, num_vertices, &sorted_vertex_ids,
1942 &sorted_vertex_reorder_idx);
1944 edge_ids, num_edges, &sorted_edge_ids, &sorted_edge_reorder_idx);
1955 comm, dt_coord, vertex_ranks,
1956 &vertex_coordinates, &vertex_owner, &vertex_field_data);
1965 grid, dist_point_infos[
YAC_LOC_EDGE], num_edges, comm, dt_coord,
1966 num_vertices, sorted_vertex_ids, sorted_vertex_reorder_idx,
1967 &edge_to_vertex, &edge_type, &edge_field_data);
1972 size_t * cell_to_edge;
1973 int * num_vertices_per_cell;
1977 num_edges, sorted_edge_ids, sorted_edge_reorder_idx,
1978 num_vertices, sorted_vertex_ids, sorted_vertex_reorder_idx,
1980 &num_vertices_per_cell, &cell_field_data);
1985 size_t * cell_to_vertex_offsets =
1987 size_t * cell_to_edge_offsets = cell_to_vertex_offsets;
1988 for (
size_t i = 0, accu = 0; i <
num_cells; ++i) {
1989 cell_to_vertex_offsets[i] = accu;
1990 accu += (size_t)(num_vertices_per_cell[i]);
1996 .ids = {cell_ids, vertex_ids, edge_ids},
1997 .total_count = {
num_cells, num_vertices, num_edges},
1998 .count = {
num_cells, num_vertices, num_edges},
2011 .owner_mask = {NULL, NULL, NULL},
2012 .sorted_ids = {sorted_cell_ids, sorted_vertex_ids, sorted_edge_ids},
2013 .sorted_reorder_idx =
2014 {sorted_cell_reorder_idx, sorted_vertex_reorder_idx,
2015 sorted_edge_reorder_idx},
2018 cell_field_data, vertex_field_data, edge_field_data),
2033 for (
int i = 0; i < 2; ++i)
2042 for (
int i = 0; i < 2; ++i) {
2052 int ** vertex_ranks[2], MPI_Comm comm) {
2060 yac_int **global_vertex_ids[2] =
2066 &proc_sphere_part, global_vertex_ids, vertex_ranks, comm);
2068 return proc_sphere_part;
2075 char const * routine =
"yac_dist_grid_pair_new";
2078 grid_a,
"ERROR(%s): NULL is not a valid value for parameter grid_a",
2081 grid_b,
"ERROR(%s): NULL is not a valid value for parameter grid_b",
2091 (grid_a == grid_b) || strcmp(grid_name_a, grid_name_b),
2092 "ERROR(%s): both grids use that same name (\"%s\"), "
2093 "but point to different basic grids", routine, grid_name_a);
2097 if (grid_a == grid_b) {
2101 grid_b = dummy_grid;
2109 if (strcmp(grid_name_a, grid_name_b) > 0) {
2113 char const * grid_name_swap = grid_name_a;
2114 grid_name_a = grid_name_b;
2115 grid_name_b = grid_name_swap;
2129 int * vertex_ranks[2] = {NULL, NULL};
2132 grid_a, grid_b, (
int**[2]){&vertex_ranks[0], &vertex_ranks[1]},
comm);
2143 if (dummy_grid != NULL) {
2164 return grid_pair->
comm;
2173 for (
int i = 0; (i < 2) && (dist_grid == NULL); ++i)
2174 if (!strcmp(grid_name, grid_pair->
grid_names[i]))
2177 dist_grid,
"ERROR(yac_dist_grid_pair_get_dist_grid): invalid grid_name")
2193 size_t local_count = 0;
2196 for (
size_t i = 0; i <
count; ++i)
if (owner_mask[i]) ++local_count;
2242 size_t ** indices,
size_t * num_indices) {
2247 int const * owner_mask =
2250 size_t * temp_indices =
xmalloc(
count *
sizeof(*temp_indices));
2252 size_t num_indices_ = 0;
2254 if (field_mask != NULL) {
2255 for (
size_t i = 0; i <
count; ++i)
2256 if (owner_mask[i] && field_mask[i]) temp_indices[num_indices_++] = i;
2258 for (
size_t i = 0; i <
count; ++i)
2259 if (owner_mask[i]) temp_indices[num_indices_++] = i;
2262 *indices =
xrealloc(temp_indices, num_indices_ *
sizeof(**indices));
2263 *num_indices = num_indices_;
2276 if (field.masks_idx == SIZE_MAX)
return NULL;
2279 (field.masks_idx != SIZE_MAX)?
2282 field.masks_idx):NULL;
2289 (field.coordinates_idx != SIZE_MAX)?
2292 field.coordinates_idx):NULL;
2308 if (field_mask == NULL)
2311 int const * owner_mask =
2314 size_t unmasked_local_count = 0;
2315 for (
size_t i = 0; i < count; ++i)
2316 if (owner_mask[i] && field_mask[i]) ++unmasked_local_count;
2317 return unmasked_local_count;
2323 for (
size_t i = 0; i < count; ++i)
2324 if (point_infos[i].count > 1) free(point_infos[i].
data.multi);
2330 free(grid.vertex_coordinates);
2331 free(grid.num_vertices_per_cell);
2332 free(grid.cell_to_vertex);
2333 free(grid.cell_to_vertex_offsets);
2334 free(grid.cell_to_edge);
2335 free(grid.cell_bnd_circles);
2336 free(grid.edge_type);
2337 free(grid.edge_to_vertex);
2338 for (
int i = 0; i < 3; ++i) {
2340 free(grid.owner_mask[i]);
2341 free(grid.sorted_ids[i]);
2342 free(grid.sorted_reorder_idx[i]);
2350 if (grid_pair == NULL)
return;
2355 for (
int i = 0; i < 2; ++i) {
2381 for (
size_t i = 0; i < buffer_cell->
num_corners; ++i)
2404 *buffer_cell = cell;
2407 for (
size_t i = 0; i < num_vertices; ++i) {
2410 grid_data->cell_to_vertex_offsets[cell_idx] + i];
2428 for (
int i = 0; (i < 2) && (search == NULL); ++i)
2429 if (!strcmp(grid_name, grid_pair->
grid_names[i]))
2433 "ERROR(yac_dist_grid_pair_get_cell_sphere_part): invalid grid_name")
2441 double coord[3],
struct yac_dist_grid * dist_grid,
size_t cell_idx,
2449 size_t * temp_cells;
2450 size_t * num_cells_per_coord =
2455 cell_sphere_part, search_coords,
count, &temp_cells,
2456 num_cells_per_coord);
2463 for (
size_t i = 0, k = 0; i < count; ++i) {
2464 size_t curr_num_cells = num_cells_per_coord[i];
2465 if (curr_num_cells == 0) {
2466 cells[i] = SIZE_MAX;
2467 }
else if (curr_num_cells == 1) {
2469 search_coords[i], dist_grid, temp_cells[k], &buffer_cell))
2470 cells[i] = temp_cells[k];
2472 cells[i] = SIZE_MAX;
2475 size_t cell_idx = SIZE_MAX;
2476 yac_int cell_id = YAC_INT_MAX;
2477 for (
size_t j = 0; j < curr_num_cells; ++j, ++k) {
2478 size_t curr_cell_idx = temp_cells[k];
2481 search_coords[i], dist_grid, curr_cell_idx, &buffer_cell))
2483 if (curr_cell_id < cell_id) {
2484 cell_idx = curr_cell_idx;
2485 cell_id = curr_cell_id;
2488 cells[i] = cell_idx;
2493 free(num_cells_per_coord);
2507 size_t count_ = *count;
2508 size_t new_count = 0;
2511 qsort(ids, count_,
sizeof(*ids),
2514 for (
size_t i = 0, j = 0; i < count_; ++i) {
2515 yac_int curr_id = ids[i].data.global_id;
2516 while ((j < num_ids) && (sorted_ids[j] < curr_id)) ++j;
2517 if ((j < num_ids) && (sorted_ids[j] == curr_id)) {
2518 idx[ids[i].reorder_idx] = reorder_idx[j];
2520 if (i != new_count) ids[new_count] = ids[i];
2531 int pack_size_field_coord, pack_size_field_mask;
2534 MPI_Pack_size(3, MPI_DOUBLE, comm, &pack_size_field_coord), comm);
2535 pack_size_field_coord *=
2539 MPI_Pack_size(1, MPI_INT, comm, &pack_size_field_mask), comm);
2540 pack_size_field_mask *=
2543 return pack_size_field_coord + pack_size_field_mask;
2548 MPI_Datatype bnd_circle_dt, MPI_Comm comm) {
2551 pack_size_num_vertices,
2552 pack_size_bnd_circle;
2557 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &pack_size_num_vertices), comm);
2560 MPI_Pack_size(1, bnd_circle_dt, comm, &pack_size_bnd_circle), comm);
2562 return pack_size_id + pack_size_num_vertices + pack_size_bnd_circle +
2570 pack_size_vertex_coords;
2575 MPI_Pack_size(3, MPI_DOUBLE, comm, &pack_size_vertex_coords), comm);
2577 return pack_size_id + pack_size_vertex_coords +
2585 pack_size_edge_to_vertex,
2586 pack_size_edge_type;
2590 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &pack_size_edge_type), comm);
2593 MPI_Pack_size(2,
yac_int_dt, comm, &pack_size_edge_to_vertex), comm);
2595 return pack_size_id + pack_size_edge_type + pack_size_edge_to_vertex +
2600 struct yac_dist_grid * dist_grid, uint64_t * pos,
size_t count,
2601 int * pack_sizes, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
2604 int pack_size_base_cell =
2608 bnd_circle_dt, comm);
2609 int pack_size_base_vertex =
2613 int pack_size_base_edge =
2618 for (
size_t i = 0; i < count; ++i) {
2619 size_t idx = (size_t)(pos[i]);
2621 size_t * curr_vertices =
2623 size_t * curr_edges =
2626 pack_size_base_cell +
2627 num_vertices * (pack_size_base_vertex + pack_size_base_edge) +
2630 for (
int j = 0; j < num_vertices; ++j) {
2634 point_info_dt, comm) +
2638 pack_sizes[i] = pack_size;
2643 struct yac_dist_grid * dist_grid, uint64_t * pos,
size_t count,
2644 int * pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm) {
2646 int pack_size_base_vertex =
2650 for (
size_t i = 0; i < count; ++i)
2652 pack_size_base_vertex +
2658 struct yac_dist_grid * dist_grid, uint64_t * pos,
size_t count,
2659 int * pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm) {
2661 int pack_size_base_vertex =
2665 int pack_size_base_edge =
2669 for (
size_t i = 0; i < count; ++i) {
2672 pack_size_base_edge +
2673 2 * pack_size_base_vertex +
2678 point_info_dt, comm) +
2681 point_info_dt, comm);
2687 size_t count,
int * pack_sizes, MPI_Datatype bnd_circle_dt,
2688 MPI_Datatype point_info_dt, MPI_Comm comm) {
2696 dist_grid, pos, count, pack_sizes, bnd_circle_dt, point_info_dt, comm);
2700 dist_grid, pos, count, pack_sizes, point_info_dt, comm);
2704 dist_grid, pos, count, pack_sizes, point_info_dt, comm);
2710 size_t idx,
void *
buffer,
int buffer_size,
int * position,
2713 size_t coordinates_count =
2715 size_t masks_count =
2719 for (
size_t i = 0; i < coordinates_count; ++i)
2723 3, MPI_DOUBLE,
buffer, buffer_size, position, comm), comm);
2726 for (
size_t i = 0; i < masks_count; ++i)
2730 buffer_size, position, comm), comm);
2735 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
2743 position, comm), comm);
2747 buffer_size, position, comm), comm);
2751 point_info_dt, comm);
2754 idx,
buffer, buffer_size, position,
2760 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
2787 point_info_dt, comm);
2790 idx,
buffer, buffer_size, position,
2796 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
2800 dist_grid, idx,
buffer, buffer_size, position,
2801 bnd_circle_dt, point_info_dt, comm);
2804 for (
int i = 0; i < 2; ++i)
2807 buffer, buffer_size, position, bnd_circle_dt, point_info_dt, comm);
2812 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
2824 idx,
buffer, buffer_size, position,
2828 MPI_Pack(&num_vertices, 1, MPI_INT,
buffer,
2829 buffer_size, position, comm), comm);
2833 buffer_size, position, comm), comm);
2837 point_info_dt, comm);
2839 for (
int i = 0; i < num_vertices; ++i) {
2843 buffer, buffer_size, position, bnd_circle_dt, point_info_dt, comm);
2847 buffer, buffer_size, position, bnd_circle_dt, point_info_dt, comm);
2853 size_t count,
void ** pack_data,
int * pack_sizes,
2854 MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm) {
2857 bnd_circle_dt, point_info_dt, comm);
2859 size_t pack_size = 0;
2860 for (
size_t i = 0; i < count; ++i) pack_size += (
size_t)(pack_sizes[i]);
2862 void * pack_data_ =
xmalloc(pack_size);
2866 void (*func_pack[3])(
2868 int buffer_size,
int * position, MPI_Datatype bnd_circle_dt,
2869 MPI_Datatype point_info_dt, MPI_Comm
comm) =
2872 for (
size_t i = 0, offset = 0; i <
count; ++i) {
2875 dist_grid, pos[i], (
char*)pack_data_ + offset, pack_sizes[i],
2876 &position, bnd_circle_dt, point_info_dt,
comm);
2877 pack_sizes[i] = position;
2878 offset += (size_t)position;
2881 *pack_data = pack_data_;
2885 void *
buffer,
int buffer_size,
int * position,
size_t idx,
2896 MPI_Unpack(
buffer, buffer_size, position,
2902 int buffer_size,
int * position,
2904 MPI_Datatype point_info_dt, MPI_Comm
comm) {
2908 MPI_Unpack(
buffer, buffer_size, position, &(vertex[idx].global_id), 1,
2912 MPI_Unpack(
buffer, buffer_size, position, &(vertex[idx].coord[0]), 3,
2916 buffer, buffer_size, position, &(vertex[idx].
owners), point_info_dt,
comm);
2919 buffer, buffer_size, position, idx, temp_vertex_field_data,
comm);
2924 int buffer_size,
int * position,
2926 MPI_Datatype point_info_dt, MPI_Comm
comm) {
2932 MPI_Unpack(
buffer, buffer_size, position, &(edge[idx].global_id), 1,
2948 buffer, buffer_size, position, idx, temp_edge_field_data,
comm);
2952 const void * a,
const void * b) {
2963 size_t old_count,
size_t new_count) {
2965 size_t add_count = new_count - old_count;
2972 new_count *
sizeof(*
mask));
2974 for (
size_t i = 0, j = old_count; i < add_count; ++i, ++j) {
2976 *(
size_t*)((
unsigned char*)
reorder_idx + i * reorder_idx_size);
2977 mask[j] = temp_mask[idx];
2986 new_count *
sizeof(*coordinates));
2988 for (
size_t i = 0, j = old_count; i < add_count; ++i, ++j) {
2990 *(
size_t*)((
unsigned char*)
reorder_idx + i * reorder_idx_size);
2991 coordinates[j][0] = temp_coordinates[idx][0];
2992 coordinates[j][1] = temp_coordinates[idx][1];
2993 coordinates[j][2] = temp_coordinates[idx][2];
3006 size_t count,
size_t * idx,
3009 if (count == 0)
return;
3012 qsort(vertices, count,
sizeof(*vertices),
3017 size_t * sorted_vertex_reorder_idx =
3021 size_t prev_idx = 0;
3022 size_t add_count = 0;
3026 for (
size_t i = 0, j = 0; i < count; ++i) {
3029 size_t curr_reorder_idx = vertices[i].
reorder_idx;
3032 if (prev_global_id == curr_global_id) {
3033 if (idx != NULL) idx[curr_reorder_idx] = prev_idx;
3037 prev_global_id = curr_global_id;
3041 while ((j < num_total_vertices) && (sorted_vertex_ids[j] < curr_global_id))
3045 if ((j < num_total_vertices) && (sorted_vertex_ids[j] == curr_global_id)) {
3047 if (idx != NULL) idx[curr_reorder_idx] = sorted_vertex_reorder_idx[j];
3048 prev_idx = sorted_vertex_reorder_idx[j];
3054 if (idx != NULL) idx[curr_reorder_idx] = num_total_vertices + add_count;
3055 prev_idx = num_total_vertices + add_count;
3056 if (add_count != i) vertices[add_count] = vertices[i];
3061 size_t new_num_total_vertices = num_total_vertices + add_count;
3064 sizeof(*vertex_coordinates));
3067 new_num_total_vertices *
sizeof(*vertex_ids));
3068 int * vertex_owner_mask =
3070 sizeof(*vertex_owner_mask));
3073 sizeof(*vertex_owners));
3076 sorted_vertex_ids, new_num_total_vertices *
sizeof(*sorted_vertex_ids));
3077 sorted_vertex_reorder_idx =
3079 sorted_vertex_reorder_idx, new_num_total_vertices *
3080 sizeof(*sorted_vertex_reorder_idx));
3083 for (
size_t i = 0, j = num_total_vertices; i < add_count; ++i, ++j) {
3085 vertex_coordinates[j][0] = vertices[i].
coord[0];
3086 vertex_coordinates[j][1] = vertices[i].
coord[1];
3087 vertex_coordinates[j][2] = vertices[i].
coord[2];
3089 vertex_owner_mask[j] = 0;
3090 vertex_owners[j] = vertices[i].
owners;
3091 sorted_vertex_ids[j] = vertices[i].
global_id;
3092 sorted_vertex_reorder_idx[j] = j;
3097 temp_vertex_field_data, vertices,
sizeof(*vertices),
3098 num_total_vertices, new_num_total_vertices);
3100 sorted_vertex_ids, new_num_total_vertices, sorted_vertex_reorder_idx);
3112 const void * a,
const void * b) {
3122 size_t count,
size_t * idx,
struct temp_field_data temp_edge_field_data) {
3124 if (count == 0)
return;
3133 size_t prev_idx = 0;
3134 size_t add_count = 0;
3138 for (
size_t i = 0, j = 0; i < count; ++i) {
3144 if (prev_global_id == curr_global_id) {
3145 if (idx != NULL) idx[curr_reorder_idx] = prev_idx;
3149 prev_global_id = curr_global_id;
3153 while ((j < num_total_edges) && (sorted_edge_ids[j] < curr_global_id)) ++j;
3156 if ((j < num_total_edges) && (sorted_edge_ids[j] == curr_global_id)) {
3158 if (idx != NULL) idx[curr_reorder_idx] = sorted_edge_reorder_idx[j];
3159 prev_idx = sorted_edge_reorder_idx[j];
3165 if (idx != NULL) idx[curr_reorder_idx] = num_total_edges + add_count;
3166 prev_idx = num_total_edges + add_count;
3167 if (add_count != i) edges[add_count] = edges[i];
3172 size_t new_num_total_edges = num_total_edges + add_count;
3175 new_num_total_edges *
sizeof(*edge_ids));
3178 new_num_total_edges *
sizeof(*
edge_type));
3184 new_num_total_edges *
sizeof(*edge_owners));
3185 int * edge_owner_mask =
3187 sizeof(*edge_owner_mask));
3190 sorted_edge_ids, new_num_total_edges *
sizeof(*sorted_edge_ids));
3191 sorted_edge_reorder_idx =
3193 sorted_edge_reorder_idx, new_num_total_edges *
3194 sizeof(*sorted_edge_reorder_idx));
3196 yac_int * vertex_ids =
xmalloc(2 * add_count *
sizeof(*vertex_ids));
3197 size_t * reorder =
xmalloc(2 * add_count *
sizeof(*reorder));
3200 for (
size_t i = 0, j = num_total_edges; i < add_count; ++i, ++j) {
3204 edge_owner_mask[j] = 0;
3205 edge_owners[j] = edges[i].
owners;
3206 sorted_edge_ids[j] = edges[i].
global_id;
3207 sorted_edge_reorder_idx[j] = j;
3211 reorder[2 * i + 0] = 2 * num_total_edges + 2 * i + 0;
3212 reorder[2 * i + 1] = 2 * num_total_edges + 2 * i + 1;
3217 temp_edge_field_data, edges,
sizeof(*edges),
3218 num_total_edges, new_num_total_edges);
3220 sorted_edge_ids, new_num_total_edges, sorted_edge_reorder_idx);
3225 size_t * sorted_vertex_reorder_idx =
3228 size_t * edge_to_vertex_ = (
size_t*)&(edge_to_vertex[0][0]);
3230 for (
size_t i = 0, j = 0; i < 2 * add_count; ++i) {
3231 yac_int curr_id = vertex_ids[i];
3232 while ((j < total_num_vertices) && (sorted_vertex_ids[j] < curr_id)) ++j;
3234 (j < total_num_vertices) && (sorted_vertex_ids[j] == curr_id),
3235 "ERROR(yac_dist_grid_add_edges): vertex id not found")
3236 edge_to_vertex_[reorder[i]] = sorted_vertex_reorder_idx[j];
3255 int * num_vertices_per_cell,
struct bounding_circle * cell_bnd_circles,
3260 if (
count == 0)
return;
3262 size_t * reorder_idx =
xmalloc(
count *
sizeof(reorder_idx));
3263 for (
size_t i = 0; i <
count; ++i) reorder_idx[i] = i;
3266 for (
size_t i = 0, accu = 0; i <
count;
3267 accu += (size_t)(num_vertices_per_cell[i++])) prescan[i] = accu;
3273 size_t * sorted_cell_reorder_idx =
3276 yac_int prev_global_id = cell_ids[0] - 1;
3277 size_t cell_add_count = 0;
3278 size_t relations_add_count = 0;
3282 for (
size_t i = 0, j = 0; i <
count; ++i) {
3284 yac_int curr_global_id = cell_ids[i];
3285 size_t curr_reorder_idx = reorder_idx[i];
3288 if (prev_global_id == curr_global_id) {
3292 prev_global_id = curr_global_id;
3296 while ((j < num_total_cells) && (sorted_cell_ids[j] < curr_global_id)) ++j;
3299 if ((j >= num_total_cells) || (sorted_cell_ids[j] != curr_global_id)) {
3301 if (cell_add_count != i) {
3302 cell_ids[cell_add_count] = curr_global_id;
3303 reorder_idx[cell_add_count] = curr_reorder_idx;
3306 relations_add_count += (size_t)(num_vertices_per_cell[curr_reorder_idx]);
3310 size_t new_num_total_cells = num_total_cells + cell_add_count;
3311 size_t num_total_relations =
3312 (num_total_cells > 0)?
3315 size_t new_num_total_relations = num_total_relations + relations_add_count;
3318 new_num_total_cells *
sizeof(*new_cell_ids));
3319 int * new_num_vertices_per_cell =
3321 sizeof(*new_num_vertices_per_cell));
3322 size_t * new_cell_to_vertex =
3324 sizeof(*new_cell_to_vertex));
3325 size_t * cell_to_vertex_offsets =
3327 sizeof(*cell_to_vertex_offsets));
3328 size_t * new_cell_to_edge =
3330 sizeof(*new_cell_to_edge));
3333 sizeof(*new_cell_bnd_circles));
3334 int * cell_owner_mask =
3336 new_num_total_cells *
sizeof(*cell_owner_mask));
3339 new_num_total_cells *
sizeof(*cell_owners));
3342 sorted_cell_ids, new_num_total_cells *
sizeof(*sorted_cell_ids));
3343 sorted_cell_reorder_idx =
3345 sorted_cell_reorder_idx, new_num_total_cells *
3346 sizeof(*sorted_cell_reorder_idx));
3349 for (
size_t i = 0, j = num_total_cells; i < cell_add_count;
3352 size_t curr_reorder_idx = reorder_idx[i];
3353 int curr_num_vertices = num_vertices_per_cell[curr_reorder_idx];
3354 size_t curr_relation_idx = prescan[curr_reorder_idx];
3356 new_cell_ids[j] = cell_ids[i];
3357 new_num_vertices_per_cell[j] = curr_num_vertices;
3358 cell_to_vertex_offsets[j] = num_total_relations;
3359 for (
int j = 0; j < curr_num_vertices;
3360 ++j, ++num_total_relations, ++curr_relation_idx) {
3361 new_cell_to_vertex[num_total_relations] =
3363 new_cell_to_edge[num_total_relations] = cell_to_edge[curr_relation_idx];
3365 cell_owner_mask[j] = 0;
3366 sorted_cell_ids[j] = cell_ids[i];
3367 sorted_cell_reorder_idx[j] = j;
3368 new_cell_bnd_circles[j] = cell_bnd_circles[curr_reorder_idx];
3369 new_cell_owners[j] = cell_owners[curr_reorder_idx];
3374 temp_cell_field_data, reorder_idx,
sizeof(*reorder_idx),
3375 num_total_cells, new_num_total_cells);
3377 sorted_cell_ids, new_num_total_cells, sorted_cell_reorder_idx);
3457 int buffer_size, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
3461 int * num_vertices_per_cell =
xmalloc(count *
sizeof(*num_vertices_per_cell));
3463 xmalloc(count *
sizeof(*cell_bnd_circles));
3468 size_t vertices_array_size = 0;
3469 size_t total_num_vertices = 0;
3472 size_t edges_array_size = 0;
3487 for (
size_t i = 0, buffer_offset = 0; i < count; ++i) {
3490 void * curr_buffer = (
char*)
buffer + buffer_offset;
3495 MPI_Unpack(curr_buffer, buffer_size, &position, cell_ids + i, 1,
3499 curr_buffer, buffer_size, &position, i, temp_cell_field_data, comm);
3502 MPI_Unpack(curr_buffer, buffer_size, &position, &num_vertices, 1,
3503 MPI_INT, comm), comm);
3506 MPI_Unpack(curr_buffer, buffer_size, &position, cell_bnd_circles + i, 1,
3507 bnd_circle_dt, comm), comm);
3510 curr_buffer, buffer_size, &position, cell_owners + i,
3511 point_info_dt, comm);
3513 num_vertices_per_cell[i] = num_vertices;
3516 vertices, vertices_array_size, total_num_vertices + (
size_t)num_vertices);
3518 edges, edges_array_size, total_num_vertices + (
size_t)num_vertices);
3520 &temp_vertex_field_data, total_num_vertices + (
size_t)num_vertices);
3522 &temp_edge_field_data, total_num_vertices + (
size_t)num_vertices);
3524 for (
int j = 0; j < num_vertices; ++j, ++total_num_vertices) {
3526 vertices, total_num_vertices, curr_buffer, buffer_size, &position,
3527 temp_vertex_field_data, point_info_dt, comm);
3529 edges, total_num_vertices, curr_buffer, buffer_size, &position,
3530 temp_edge_field_data, point_info_dt, comm);
3531 vertices[total_num_vertices].
reorder_idx = total_num_vertices;
3532 edges[total_num_vertices].
reorder_idx = total_num_vertices;
3535 buffer_offset += (size_t)position;
3536 buffer_size -= position;
3540 size_t * cell_to_edge =
xmalloc(total_num_vertices *
sizeof(*cell_to_edge));
3544 temp_vertex_field_data);
3546 dist_grid, edges, total_num_vertices, cell_to_edge,
3547 temp_edge_field_data);
3549 dist_grid, cell_ids, num_vertices_per_cell, cell_bnd_circles, count,
3550 cell_to_vertex, cell_to_edge, cell_owners, temp_cell_field_data);
3560 free(cell_bnd_circles);
3561 free(num_vertices_per_cell);
3567 int buffer_size, MPI_Datatype point_info_dt, MPI_Comm comm) {
3576 for (
size_t i = 0, buffer_offset = 0; i < count; ++i) {
3579 void * curr_buffer = (
char*)
buffer + buffer_offset;
3582 vertices, i, curr_buffer, buffer_size, &position,
3583 temp_vertex_field_data, point_info_dt, comm);
3586 buffer_offset += (size_t)position;
3587 buffer_size -= position;
3591 dist_grid, vertices, count, NULL, temp_vertex_field_data);
3600 int buffer_size, MPI_Datatype point_info_dt, MPI_Comm comm) {
3604 xmalloc(2 * count *
sizeof(*vertices));
3615 for (
size_t i = 0, buffer_offset = 0; i < count; ++i) {
3618 void * curr_buffer = (
char*)
buffer + buffer_offset;
3621 edges, i, curr_buffer, buffer_size, &position,
3622 temp_edge_field_data, point_info_dt, comm);
3625 for (
size_t j = 0; j < 2; ++j)
3627 vertices, 2 * i + j, curr_buffer, buffer_size, &position,
3628 temp_vertex_field_data, point_info_dt, comm);
3630 buffer_offset += (size_t)position;
3631 buffer_size -= position;
3635 dist_grid, vertices, 2 * count, NULL, temp_vertex_field_data);
3637 dist_grid, edges, count, NULL, temp_edge_field_data);
3648 void *
buffer,
int buffer_size, MPI_Datatype bnd_circle_dt,
3649 MPI_Datatype point_info_dt, MPI_Comm comm) {
3657 dist_grid, count,
buffer, buffer_size, bnd_circle_dt,
3658 point_info_dt, comm);
3662 dist_grid, count,
buffer, buffer_size, point_info_dt, comm);
3666 dist_grid, count,
buffer, buffer_size, point_info_dt, comm);
3672 const void * a,
const void * b) {
3682 MPI_Comm comm = dist_grid->
comm;
3683 int comm_rank, comm_size;
3687 size_t remote_count = 0;
3689 for (
size_t i = 0; i < count; ++i) {
3690 if (ids[i].global_id == YAC_INT_MAX) idx[i] = SIZE_MAX;
3691 else if (ids[i].
data.rank != comm_rank) ++remote_count;
3692 else idx[i] = ids[i].data.orig_pos;
3696 xmalloc(remote_count *
sizeof(*missing_ids));
3698 for (
size_t i = 0, j = 0; i < count; ++i) {
3699 if ((ids[i].
data.rank != comm_rank) &&
3700 (ids[i].global_id != YAC_INT_MAX)) {
3701 missing_ids[j].
data = ids[i];
3709 dist_grid,
location, missing_ids, &remote_count, idx);
3712 qsort(missing_ids, remote_count,
sizeof(*missing_ids),
3715 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
3717 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3719 for (
size_t i = 0; i < remote_count; ++i)
3720 sendcounts[missing_ids[i].
data.data.rank]++;
3723 1, sendcounts, recvcounts, sdispls, rdispls, comm);
3725 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
3727 uint64_t * uint64_t_buffer =
3728 xmalloc((remote_count + recv_count) *
sizeof(*uint64_t_buffer));
3729 uint64_t * orig_pos_send_buffer = uint64_t_buffer;
3730 uint64_t * orig_pos_recv_buffer = uint64_t_buffer + remote_count;
3733 for (
size_t i = 0; i < remote_count; ++i) {
3735 if (rank != comm_rank)
3736 orig_pos_send_buffer[sdispls[rank+1]++] =
3737 (uint64_t)(missing_ids[i].
data.data.orig_pos);
3741 yac_alltoallv_uint64_p2p(
3742 orig_pos_send_buffer, sendcounts, sdispls,
3743 orig_pos_recv_buffer, recvcounts, rdispls, comm,
3744 "yac_dist_grid_single_remote_point_to_local", __LINE__);
3751 void * packed_send_data = NULL;
3752 int * pack_sizes =
xmalloc(recv_count *
sizeof(*pack_sizes));
3756 dist_grid,
location, orig_pos_recv_buffer, recv_count,
3757 &packed_send_data, pack_sizes,
3758 bnd_circle_dt, point_info_dt, comm);
3759 free(uint64_t_buffer);
3761 memset(sendcounts, 0, (
size_t)comm_size *
sizeof(*sendcounts));
3762 for (
int i = 0, k = 0; i < comm_size; ++i)
3763 for (
size_t j = 0; j < recvcounts[i]; ++j, ++k)
3764 sendcounts[i] += (
size_t)(pack_sizes[k]);
3769 1, sendcounts, recvcounts, sdispls, rdispls, comm);
3771 recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
3773 void * packed_recv_data =
xmalloc(recv_count);
3776 yac_alltoallv_packed_p2p(
3777 packed_send_data, sendcounts, sdispls+1,
3778 packed_recv_data, recvcounts, rdispls, comm,
3779 "yac_dist_grid_single_remote_point_to_local", __LINE__);
3783 dist_grid,
location, remote_count, packed_recv_data, (
int)recv_count,
3784 bnd_circle_dt, point_info_dt, comm);
3791 dist_grid,
location, missing_ids, &remote_count, idx);
3794 free(packed_recv_data);
3795 free(packed_send_data);
3802 MPI_Datatype single_id_owner_dt;
3803 int array_of_blocklengths[] = {1, 1, 1};
3804 const MPI_Aint array_of_displacements[] =
3805 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
global_id) -
3806 (MPI_Aint)(intptr_t)(
const void *)&dummy,
3807 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
data.
rank) -
3808 (MPI_Aint)(intptr_t)(
const void *)&dummy,
3809 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
data.
orig_pos) -
3810 (MPI_Aint)(intptr_t)(
const void *)&dummy};
3811 const MPI_Datatype array_of_types[] =
3814 MPI_Type_create_struct(3, array_of_blocklengths, array_of_displacements,
3815 array_of_types, &single_id_owner_dt), comm);
3824 double coord[3],
struct yac_dist_grid * dist_grid,
size_t cell_idx,
3829 char const * routine =
"yac_dist_grid_pair_do_point_search_";
3831 MPI_Comm comm = grid_pair->
comm;
3832 int comm_rank, comm_size;
3836 int * ranks =
xmalloc(count *
sizeof(ranks));
3851 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
3853 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3854 for (
size_t i = 0; i < count; ++i) sendcounts[ranks[i]]++;
3856 size_t local_count = sendcounts[comm_rank];
3857 sendcounts[comm_rank] = 0;
3860 1, sendcounts, recvcounts, sdispls, rdispls, comm);
3862 size_t remote_count = sdispls[comm_size] + sendcounts[comm_size-1];
3863 size_t request_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
3866 xmalloc((remote_count + request_count + local_count) *
3867 sizeof(*coord_buffer));
3871 coord_buffer + remote_count + request_count;
3874 for (
size_t i = 0, k = 0; i < count; ++i) {
3875 if (ranks[i] == comm_rank) {
3876 coord_local_buffer[k][0] = search_coords[i][0];
3877 coord_local_buffer[k][1] = search_coords[i][1];
3878 coord_local_buffer[k][2] = search_coords[i][2];
3881 size_t displ = sdispls[ranks[i]+1]++;
3882 coord_send_buffer[displ][0] = search_coords[i][0];
3883 coord_send_buffer[displ][1] = search_coords[i][1];
3884 coord_send_buffer[displ][2] = search_coords[i][2];
3888 MPI_Datatype dt_coord;
3889 yac_mpi_call(MPI_Type_contiguous(3, MPI_DOUBLE, &dt_coord), comm);
3894 coord_send_buffer, sendcounts, sdispls,
3895 coord_recv_buffer, recvcounts, rdispls,
3896 sizeof(*coord_send_buffer), dt_coord, comm, routine, __LINE__);
3900 size_t * local_cells =
3901 xmalloc((request_count + local_count) *
sizeof(*local_cells));
3910 grid_pair, grid_name, coord_recv_buffer, request_count + local_count,
3920 xmalloc((remote_count + request_count) *
3921 sizeof(*single_remote_point_buffer));
3930 for (
size_t i = 0; i < request_count; ++i) {
3931 size_t cell_idx = local_cells[i];
3932 id_send_buffer[i].
data.
rank = comm_rank;
3933 if (cell_idx != SIZE_MAX) {
3937 id_send_buffer[i].
global_id = YAC_INT_MAX;
3942 MPI_Datatype single_remote_point_dt =
3947 id_send_buffer, recvcounts, rdispls, id_recv_buffer, sendcounts, sdispls,
3948 sizeof(*id_send_buffer), single_remote_point_dt,
comm, routine, __LINE__);
3952 size_t * new_local_cells =
3953 xmalloc(remote_count *
sizeof(*new_local_cells));
3964 dist_grid, id_recv_buffer, remote_count,
YAC_LOC_CELL, new_local_cells);
3967 for (
size_t i = 0, k = 0; i <
count; ++i) {
3968 if (ranks[i] == comm_rank) {
3969 cells[i] = local_cells[request_count + k];
3972 size_t displ = sdispls[ranks[i]]++;
3973 cells[i] = new_local_cells[displ];
3977 free(new_local_cells);
3978 free(single_remote_point_buffer);
4012 size_t total_count =
4016 field_coords != NULL,
4017 "ERROR(yac_dist_grid_get_field_sphere_part): "
4018 "no user-provided %s coordinates available\n",
4024 total_count, field_coords, global_ids);
4028 total_count, field_coords, global_ids,
mask);
4042 int const * owner_mask =
4047 if (field_mask == NULL) {
4049 for (
size_t i = 0, j = 0; i < count; ++i) {
4050 if (owner_mask[i]) {
4051 points[j].global_id = global_ids[i];
4052 points[j].data.rank = comm_rank;
4053 points[j].data.orig_pos = i;
4054 if (n == ++j)
return;
4060 for (
size_t i = 0, j = 0; i < count; ++i) {
4061 if (owner_mask[i] && field_mask[i]) {
4062 points[j].global_id = global_ids[i];
4063 points[j].data.rank = comm_rank;
4064 points[j].data.orig_pos = i;
4065 if (n == ++j)
return;
4072 void const * a,
void const * b) {
4081 if (ret)
return ret;
4090 double cos_max_search_distance,
size_t * result_points) {
4096 double * cos_angles = NULL;
4097 size_t cos_angles_array_size = 0;
4098 size_t * temp_result_points = NULL;
4099 size_t temp_result_points_array_size = 0;
4100 size_t * num_temp_results =
xmalloc(count *
sizeof(*num_temp_results));
4102 sphere_part, count, search_coords, n, &cos_angles,
4103 &cos_angles_array_size, NULL, NULL, &temp_result_points,
4104 &temp_result_points_array_size, num_temp_results);
4110 size_t max_num_results = 0;
4111 for (
size_t i = 0; i < count; ++i)
4112 if (max_num_results < num_temp_results[i])
4113 max_num_results = num_temp_results[i];
4116 xmalloc(max_num_results *
sizeof(*temp_results));
4122 for (
size_t i = 0, k = 0; i < count; ++i) {
4124 size_t curr_num_search_results = num_temp_results[i];
4125 size_t curr_num_results = 0;
4128 for (
size_t j = 0; j < curr_num_search_results; ++j, ++k) {
4131 if (cos_angles[k] >= cos_max_search_distance) {
4134 size_t curr_local_id = temp_result_points[k];
4135 temp_results[curr_num_results].
local_id = curr_local_id;
4136 temp_results[curr_num_results].
global_id = global_ids[curr_local_id];
4137 temp_results[curr_num_results].
cos_angle = cos_angles[k];
4144 temp_results, curr_num_results,
sizeof(*temp_results),
4147 if (curr_num_results > n) curr_num_results = n;
4149 for (
size_t l = 0; l < curr_num_results; ++l)
4150 result_points[i * n + l] = temp_results[l].
local_id;
4151 for (
size_t l = curr_num_results; l < n; ++l)
4152 result_points[i * n + l] = UINT64_MAX;
4155 free(num_temp_results);
4158 free(temp_result_points);
4163 size_t const * a_ = a, * b_ = b;
4165 return (*a_ > *b_) - (*b_ > *a_);
4173 char const * routine =
"yac_dist_grid_pair_do_nnn_search";
4175 MPI_Comm comm = grid_pair->
comm;
4176 int comm_rank, comm_size;
4181 (max_search_distance >= 0.0) && (max_search_distance <= M_PI),
4182 "ERROR(%s): invalid max_search_distance (%lf)",
4183 routine, max_search_distance)
4198 uint64_t unmasked_local_count =
4201 uint64_t * unmasked_local_counts =
4202 xmalloc((
size_t)comm_size *
sizeof(*unmasked_local_counts));
4207 &unmasked_local_count, 1, MPI_UINT64_T,
4208 unmasked_local_counts, 1, MPI_UINT64_T,
comm),
comm);
4212 for (
int i = 0; i < comm_size; ++i)
4213 flag |= unmasked_local_counts[i] < (uint64_t)n;
4218 uint64_t global_num_unmasked_count = 0;
4219 for (
int i = 0; i < comm_size; ++i)
4220 global_num_unmasked_count += unmasked_local_counts[i];
4223 (
size_t)global_num_unmasked_count >= n,
"ERROR(%s): "
4224 "insufficient number of unmasked points (available: %zu required: %zu",
4225 routine, (
size_t)global_num_unmasked_count, n)
4227 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4229 1, &sendcounts, &recvcounts, &sdispls, &rdispls,
comm);
4233 int * flag_buffer =
xcalloc(2 * (
size_t)comm_size,
sizeof(*flag_buffer));
4234 int * send_flags = flag_buffer;
4235 int * recv_flags = flag_buffer + comm_size;
4238 send_flags, recv_flags, comm_rank, comm_size);
4239 for (
int i = 0; i < comm_size; ++i) {
4240 sendcounts[i] = (size_t)send_flags[i];
4241 recvcounts[i] = (size_t)recv_flags[i];
4245 size_t local_send_count = (size_t)(
MIN(unmasked_local_count, n));
4248 for (
int i = 0; i < comm_size; ++i) {
4251 sendcounts[i] *= local_send_count;
4252 raccu += (recvcounts[i] *= (int)(
MIN(unmasked_local_counts[i], n)));
4255 size_t recv_count = recvcounts[comm_size-1] + rdispls[comm_size-1];
4259 (local_send_count + recv_count) *
sizeof(*single_remote_point_buffer));
4262 single_remote_point_buffer + local_send_count;
4266 dist_grid, field, comm_rank, local_send_count, local_send_ids);
4268 MPI_Datatype single_remote_point_dt =
4273 local_send_ids, sendcounts, sdispls, recv_ids, recvcounts, rdispls,
4274 sizeof(*local_send_ids), single_remote_point_dt, comm,
4277 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4279 size_t * dummy =
xmalloc(recv_count *
sizeof(*dummy));
4284 dist_grid, recv_ids, recv_count, field.location, dummy);
4287 free(single_remote_point_buffer);
4290 free(unmasked_local_counts);
4303 sphere_part, count, search_coords, n, ubounds);
4310 int * request_ranks = NULL;
4311 size_t request_ranks_array_size = 0;
4312 size_t num_request_ranks = 0;
4313 int * num_requests =
xmalloc(count *
sizeof(*num_requests));
4316 for (
size_t i = 0; i < count; ++i) {
4321 3 *
sizeof(search_coords[0][0]));
4323 ubounds[i] = max_search_distance_angle;
4328 num_request_ranks + (
size_t)comm_size);
4332 int * curr_request_ranks = request_ranks + num_request_ranks;
4335 curr_request_ranks, num_requests + i);
4338 int new_num_requests = 0;
4339 for (
int j = 0; j < num_requests[i]; ++j) {
4340 if (curr_request_ranks[j] == comm_rank)
continue;
4341 if (new_num_requests != j)
4342 curr_request_ranks[new_num_requests] = curr_request_ranks[j];
4346 num_request_ranks += (size_t)(num_requests[i] = new_num_requests);
4355 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4357 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
4359 for (
size_t i = 0; i < num_request_ranks; ++i) sendcounts[request_ranks[i]]++;
4362 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4364 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4367 xmalloc((num_request_ranks + recv_count) *
sizeof(*bnd_circles));
4369 struct bounding_circle * recv_bnd_circles = bnd_circles + num_request_ranks;
4372 for (
size_t i = 0, k = 0; i < count; ++i) {
4373 for (
int j = 0; j < num_requests[i]; ++j, ++k) {
4375 send_bnd_circles + sdispls[request_ranks[k]+1];
4376 sdispls[request_ranks[k]+1]++;
4377 memcpy(curr_bnd_circle->
base_vector, search_coords[i],
4378 3 *
sizeof(search_coords[0][0]));
4379 curr_bnd_circle->
inc_angle = ubounds[i];
4384 free(request_ranks);
4391 send_bnd_circles, sendcounts, sdispls,
4392 recv_bnd_circles, recvcounts, rdispls,
4393 sizeof(*send_bnd_circles), bnd_circle_dt, comm, routine, __LINE__);
4402 size_t * result_points = NULL;
4403 size_t result_points_array_size = 0;
4404 size_t * num_results_points =
4405 xmalloc(recv_count *
sizeof(*num_results_points));
4407 sphere_part, recv_count, recv_bnd_circles, n, &result_points,
4408 &result_points_array_size, num_results_points);
4414 size_t total_num_result_points = 0;
4415 size_t offset = 0, k = 0;
4416 for (
int i = 0; i < comm_size; ++i) {
4417 size_t curr_num_result_points = 0;
4418 for (
size_t j = 0; j < recvcounts[i]; ++j, ++k)
4419 curr_num_result_points += num_results_points[k];
4420 size_t new_num_result_points = curr_num_result_points;
4422 result_points + offset,
4425 result_points + offset, &new_num_result_points);
4427 result_points + total_num_result_points,
4428 result_points + offset, new_num_result_points *
4429 sizeof(*result_points));
4430 total_num_result_points += new_num_result_points;
4431 offset += curr_num_result_points;
4432 sendcounts[i] = new_num_result_points;
4434 free(num_results_points);
4437 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4438 recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4444 xmalloc((total_num_result_points + recv_count) *
4445 sizeof(*single_remote_point_buffer));
4448 total_num_result_points;
4449 for (
size_t i = 0; i < total_num_result_points; ++i) {
4450 size_t orig_pos = result_points[i];
4451 id_send_buffer[i].
global_id = global_ids[orig_pos];
4452 id_send_buffer[i].
data.
rank = comm_rank;
4455 free(result_points);
4457 MPI_Datatype single_remote_point_dt =
4462 id_send_buffer, sendcounts, sdispls+1, id_recv_buffer, recvcounts, rdispls,
4463 sizeof(*id_send_buffer), single_remote_point_dt, comm, routine, __LINE__);
4464 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4473 size_t * temp_idx =
xmalloc(recv_count *
sizeof(*temp_idx));
4475 dist_grid, id_recv_buffer, recv_count, field.location, temp_idx);
4477 free(single_remote_point_buffer);
4484 dist_grid, field, count, search_coords, n, max_search_distance_angle.
cos,
4493 char const * routine =
"yac_dist_grid_pair_do_bnd_circle_search";
4495 MPI_Comm comm = grid_pair->
comm;
4496 int comm_rank, comm_size;
4508 int * rank_buffer = NULL;
4509 size_t rank_buffer_size = 0;
4510 size_t rank_buffer_array_size = 0;
4512 for (
size_t i = 0; i <
count; ++i) {
4515 rank_buffer_size + (
size_t)comm_size);
4523 rank_buffer + rank_buffer_size, num_ranks + i);
4524 rank_buffer_size += (size_t)(num_ranks[i]);
4531 size_t * size_t_buffer =
4532 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
4533 size_t * result_sendcounts = size_t_buffer + 0 * comm_size;
4534 size_t * result_recvcounts = size_t_buffer + 1 * comm_size;
4535 size_t * result_sdispls = size_t_buffer + 2 * comm_size;
4536 size_t * result_rdispls = size_t_buffer + 3 * comm_size;
4538 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4540 1, &sendcounts, &recvcounts, &sdispls, &rdispls,
comm);
4542 for (
size_t i = 0, offset = 0; i <
count; ++i) {
4543 int curr_num_ranks = num_ranks[i];
4544 int * ranks = rank_buffer + offset;
4545 offset += (size_t)curr_num_ranks;
4546 for (
int j = 0; j < curr_num_ranks; ++j) sendcounts[ranks[j]]++;
4550 size_t local_count = sendcounts[comm_rank];
4551 sendcounts[comm_rank] = 0;
4554 1, sendcounts, recvcounts, sdispls, rdispls,
comm);
4556 size_t send_count = sdispls[comm_size] + sendcounts[comm_size-1];
4557 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4560 xmalloc((send_count + recv_count + local_count) *
4561 sizeof(*bnd_circle_buffer));
4565 bnd_circle_buffer + send_count + recv_count;
4568 for (
size_t i = 0, offset = 0, local_offset = 0; i < count; ++i) {
4569 int curr_num_ranks = num_ranks[i];
4570 int * ranks = rank_buffer + offset;
4571 offset += (size_t)curr_num_ranks;
4572 for (
int j = 0; j < curr_num_ranks; ++j) {
4573 int rank = ranks[j];
4574 if (rank == comm_rank)
4575 local_buffer[local_offset++] = bnd_circles[i];
4577 send_buffer[sdispls[rank + 1]++] = bnd_circles[i];
4587 sizeof(*
send_buffer), bnd_circle_dt, comm, routine, __LINE__);
4598 size_t * local_cells = NULL;
4599 size_t * num_local_cells_per_bnd_circle =
4600 xmalloc((recv_count + local_count) *
4601 sizeof(*num_local_cells_per_bnd_circle));
4603 uint64_t * uint64_t_buffer =
4604 xmalloc((send_count + recv_count + local_count) *
4605 sizeof(*uint64_t_buffer));
4606 uint64_t * num_local_cells_per_bnd_circle_uint64_t = uint64_t_buffer;
4607 uint64_t * num_remote_cells_per_bnd_circle =
4608 uint64_t_buffer + recv_count + local_count;
4612 cell_sphere_part,
recv_buffer, recv_count + local_count, &local_cells,
4613 num_local_cells_per_bnd_circle);
4620 int const * field_mask =
4627 for (
size_t i = 0, offset = 0, new_offset = 0;
4628 i < recv_count + local_count; ++i) {
4631 size_t curr_num_results = num_local_cells_per_bnd_circle[i];
4634 uint64_t new_num_results = 0;
4635 for (
size_t j = 0; j < curr_num_results; ++j, ++offset) {
4636 size_t local_cell_id = local_cells[offset];
4638 cell_bnd_circles + local_cell_id))
continue;
4639 if ((field_mask == NULL) || (field_mask[local_cell_id])) {
4640 if (offset != new_offset) local_cells[new_offset] = local_cell_id;
4645 num_local_cells_per_bnd_circle_uint64_t[i] = new_num_results;
4647 free(num_local_cells_per_bnd_circle);
4648 free(bnd_circle_buffer);
4656 num_local_cells_per_bnd_circle_uint64_t, recvcounts, rdispls,
4657 num_remote_cells_per_bnd_circle, sendcounts, sdispls,
4658 sizeof(*num_local_cells_per_bnd_circle_uint64_t), MPI_UINT64_T, comm,
4661 size_t saccu = 0, raccu = 0, soffset = 0, roffset = 0;
4662 for (
int i = 0; i < comm_size; ++i) {
4664 result_sdispls[i] = saccu;
4665 result_rdispls[i] = raccu;
4667 size_t sendcount = recvcounts[i];
4668 size_t recvcount = sendcounts[i];
4670 result_sendcounts[i] = 0;
4671 result_recvcounts[i] = 0;
4672 for (
size_t j = 0; j < sendcount; ++j, ++soffset)
4673 result_sendcounts[i] +=
4674 (
size_t)(num_local_cells_per_bnd_circle_uint64_t[soffset]);
4675 for (
size_t j = 0; j < recvcount; ++j, ++roffset)
4676 result_recvcounts[i] +=
4677 (
size_t)(num_remote_cells_per_bnd_circle[roffset]);
4679 saccu += result_sendcounts[i];
4680 raccu += result_recvcounts[i];
4685 size_t result_local_count = 0;
4686 for (
size_t i = recv_count; i < recv_count + local_count; ++i)
4687 result_local_count += (
size_t)(num_local_cells_per_bnd_circle_uint64_t[i]);
4689 size_t result_send_count = (size_t)(result_sdispls[comm_size-1]) +
4690 (size_t)(result_sendcounts[comm_size-1]);
4691 size_t result_recv_count = (size_t)(result_rdispls[comm_size-1]) +
4692 (size_t)(result_recvcounts[comm_size-1]);
4695 xmalloc((result_recv_count + result_send_count) *
4696 sizeof(*single_remote_point_buffer));
4703 for (
size_t i = 0; i < result_send_count; ++i) {
4704 size_t local_cell_id = local_cells[i];
4705 id_send_buffer[i].
global_id = cell_ids[local_cell_id];
4706 id_send_buffer[i].
data.
rank = comm_rank;
4710 MPI_Datatype single_remote_point_dt =
4715 id_send_buffer, result_sendcounts, result_sdispls,
4716 id_recv_buffer, result_recvcounts, result_rdispls,
4717 sizeof(*id_send_buffer), single_remote_point_dt, comm,
4720 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4722 size_t * new_local_cells =
4723 xmalloc((result_recv_count + result_local_count) *
4724 sizeof(*new_local_cells));
4726 memcpy(new_local_cells + result_recv_count,
4727 local_cells + result_send_count,
4728 result_local_count *
sizeof(*new_local_cells));
4739 dist_grid, id_recv_buffer, result_recv_count,
YAC_LOC_CELL, new_local_cells);
4741 free(single_remote_point_buffer);
4743 size_t * reorder_idx =
4744 xmalloc((result_recv_count + result_local_count) *
sizeof(*reorder_idx));
4747 num_results_per_bnd_circle, 0, count *
sizeof(*num_results_per_bnd_circle));
4749 for (
size_t i = 0, offset = 0, reorder = 0, local_search_idx = recv_count,
4750 local_offset = result_recv_count; i < count; ++i) {
4751 int curr_num_ranks = num_ranks[i];
4752 int * ranks = rank_buffer + offset;
4753 offset += (size_t)curr_num_ranks;
4754 for (
int j = 0; j < curr_num_ranks; ++j) {
4755 int rank = ranks[j];
4756 if (rank == comm_rank) {
4757 uint64_t curr_num_results =
4758 num_local_cells_per_bnd_circle_uint64_t[local_search_idx++];
4759 num_results_per_bnd_circle[i] += (size_t)curr_num_results;
4760 for (uint64_t k = 0; k < curr_num_results; ++k, ++reorder)
4761 reorder_idx[local_offset++] = reorder;
4763 size_t rank_pos = sdispls[rank]++;
4764 uint64_t curr_num_results = num_remote_cells_per_bnd_circle[rank_pos];
4765 num_results_per_bnd_circle[i] += (size_t)curr_num_results;
4766 for (uint64_t k = 0; k < curr_num_results; ++k, ++reorder)
4767 reorder_idx[result_rdispls[rank]++] = reorder;
4771 free(uint64_t_buffer);
4774 free(size_t_buffer);
4778 reorder_idx, result_recv_count + result_local_count, new_local_cells);
4782 for (
size_t i = 0, offset = 0, new_offset = 0; i < count; ++i) {
4784 size_t * curr_local_cells = new_local_cells + offset;
4785 size_t curr_num_results_per_bnd_circle = num_results_per_bnd_circle[i];
4786 size_t new_num_results_per_bnd_circle = 0;
4787 size_t prev_cell = SIZE_MAX;
4788 offset += curr_num_results_per_bnd_circle;
4791 curr_local_cells, curr_num_results_per_bnd_circle, NULL);
4793 for (
size_t j = 0; j < curr_num_results_per_bnd_circle; ++j) {
4794 size_t curr_cell = curr_local_cells[j];
4795 if (curr_cell != prev_cell) {
4796 new_local_cells[new_offset++] = (prev_cell = curr_cell);
4797 ++new_num_results_per_bnd_circle;
4800 num_results_per_bnd_circle[i] = new_num_results_per_bnd_circle;
4803 *cells = new_local_cells;
4811 char const * routine =
"yac_dist_grid_pair_do_dnn_search";
4813 MPI_Comm comm = grid_pair->
comm;
4814 int comm_rank, comm_size;
4825 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4827 1, &sendcounts, &recvcounts, &sdispls, &rdispls,
comm);
4830 int * rank_buffer = NULL;
4831 size_t rank_buffer_size = 0;
4832 size_t rank_buffer_array_size = 0;
4834 for (
size_t i = 0; i <
count; ++i) {
4837 rank_buffer_size + (
size_t)comm_size);
4840 int * curr_ranks = rank_buffer + rank_buffer_size;
4843 curr_ranks, num_ranks + i);
4846 for (
int j = 0; j < num_ranks[i]; ++j) {
4847 if (curr_ranks[j] != comm_rank) {
4848 sendcounts[curr_ranks[j]]++;
4852 rank_buffer_size += (size_t)(num_ranks[i]);
4859 enum {COUNTS_PER_RANK = 1};
4861 COUNTS_PER_RANK, sendcounts, recvcounts, sdispls, rdispls,
comm);
4863 size_t const send_count = sdispls[comm_size] + sendcounts[comm_size-1];
4864 size_t const recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4867 xmalloc((send_count + recv_count) *
sizeof(*bnd_circle_buffer));
4872 for (
size_t i = 0, k = 0; i < count; ++i) {
4873 int const curr_num_ranks = num_ranks[i];
4874 for (
int j = 0; j < curr_num_ranks; ++j, ++k) {
4875 int const rank = rank_buffer[k];
4876 if (rank != comm_rank) {
4877 send_buffer[sdispls[rank + 1]++] = bnd_circles[i];
4888 sizeof(*
send_buffer), bnd_circle_dt, comm, routine, __LINE__);
4902 size_t * local_points = NULL;
4903 size_t local_points_array_size = 0;
4904 size_t * num_local_points_per_bnd_circle =
4905 xmalloc(recv_count *
sizeof(*num_local_points_per_bnd_circle));
4910 &local_points, &local_points_array_size, num_local_points_per_bnd_circle);
4913 free(bnd_circle_buffer);
4920 size_t total_num_result_points = 0;
4921 size_t offset = 0, k = 0;
4922 for (
int i = 0; i < comm_size; ++i) {
4923 size_t curr_num_result_points = 0;
4926 for (
size_t j = 0; j < recvcounts[i]; ++j, ++k) {
4927 curr_num_result_points += num_local_points_per_bnd_circle[k];
4929 size_t new_num_result_points = curr_num_result_points;
4932 local_points + offset,
4935 local_points + offset, &new_num_result_points);
4938 local_points + total_num_result_points,
4939 local_points + offset, new_num_result_points *
sizeof(*local_points));
4940 total_num_result_points += new_num_result_points;
4941 offset += curr_num_result_points;
4942 sendcounts[i] = new_num_result_points;
4944 free(num_local_points_per_bnd_circle);
4948 COUNTS_PER_RANK, sendcounts, recvcounts, sdispls, rdispls, comm);
4949 size_t const num_remote_points =
4950 rdispls[comm_size-1] + recvcounts[comm_size-1];
4954 xmalloc((total_num_result_points + num_remote_points) *
4955 sizeof(*single_remote_point_buffer));
4958 total_num_result_points;
4964 for (
size_t i = 0; i < total_num_result_points; ++i) {
4965 size_t orig_pos = local_points[i];
4966 id_send_buffer[i].
global_id = global_ids[orig_pos];
4967 id_send_buffer[i].
data.
rank = comm_rank;
4973 MPI_Datatype single_remote_point_dt =
4978 id_send_buffer, sendcounts, sdispls+1, id_recv_buffer, recvcounts, rdispls,
4979 sizeof(*id_send_buffer), single_remote_point_dt, comm, routine, __LINE__);
4980 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4988 size_t * temp_idx =
xmalloc(num_remote_points *
sizeof(*temp_idx));
4990 dist_grid, id_recv_buffer, num_remote_points, field.location, temp_idx);
4992 free(single_remote_point_buffer);
5001 local_points = NULL;
5002 local_points_array_size = 0;
5006 point_sphere_part, count, bnd_circles,
5007 &local_points, &local_points_array_size, num_results_per_bnd_circle);
5011 *points = local_points;
5016 char const * search_grid_name,
char const * result_grid_name,
5017 size_t * search_cells,
size_t count,
size_t ** result_cells,
5018 size_t * num_results_per_search_cell,
struct yac_interp_field result_field) {
5021 xmalloc(count *
sizeof(*search_bnd_circles));
5031 for (
size_t i = 0; i <
count; ++i)
5032 search_bnd_circles[i] = search_grid_cell_bnd_circles[search_cells[i]];
5035 grid_pair, result_grid_name, search_bnd_circles,
count, result_cells,
5036 num_results_per_search_cell, result_field);
5038 size_t total_num_result_cells = 0;
5046 for (
size_t i = 0, offset = 0; i <
count; ++i) {
5048 size_t curr_num_results_per_bnd_circle = num_results_per_search_cell[i];
5049 size_t new_num_results_per_search_cell = 0;
5050 size_t * curr_result_cells = *result_cells + offset;
5051 offset += curr_num_results_per_bnd_circle;
5057 for (
size_t j = 0; j < curr_num_results_per_bnd_circle; ++j) {
5059 size_t curr_result_cell = curr_result_cells[j];
5069 search_bnd_circles + i,
5072 (*result_cells)[total_num_result_cells++] = curr_result_cell;
5073 ++new_num_results_per_search_cell;
5077 num_results_per_search_cell[i] = new_num_results_per_search_cell;
5085 free(search_bnd_circles);
5093 dist_grid->edge_to_vertex, dist_grid->vertex_coordinates, edge_id);
5099 size_t * cells,
size_t count,
size_t * neighbours) {
5101 char const * routine =
"yac_dist_grid_get_cell_neighbours";
5111 int max_num_edges_per_cell = 0;
5113 if (max_num_edges_per_cell < dist_grid->num_vertices_per_cell[i])
5117 xmalloc((
size_t)max_num_edges_per_cell *
sizeof(*edge_vertices));
5119 size_t neigh_idx = 0;
5122 size_t missing_edge_neighbour_array_size = 0;
5123 size_t num_missing_neighbours = 0;
5126 for (
size_t i = 0; i < count; ++i) {
5128 size_t curr_cell = cells[i];
5132 size_t const * cell_edges =
5134 for (
size_t j = 0; j < curr_num_edges; ++j) {
5135 size_t const * curr_edge_to_vertex =
5137 edge_vertices[j][0] = curr_edge_to_vertex[0];
5138 edge_vertices[j][1] = curr_edge_to_vertex[1];
5143 num_missing_neighbours + curr_num_edges);
5147 size_t prev_vertex = edge_vertices[0][0];
5148 for (
size_t j = 0, edge_idx = 0; j < curr_num_edges; ++j, ++
neigh_idx) {
5151 size_t curr_edge = cell_edges[edge_idx];
5152 size_t * curr_edge_cells = edge_to_cell[curr_edge];
5153 size_t other_cell = curr_edge_cells[curr_edge_cells[0] == curr_cell];
5156 if (other_cell == SIZE_MAX) {
5169 size_t new_edge_idx = SIZE_MAX;
5170 for (
size_t k = 0; k < curr_num_edges; ++k) {
5171 if (k == edge_idx)
continue;
5172 else if (edge_vertices[k][0] == prev_vertex) {
5174 prev_vertex = edge_vertices[k][1];
5176 }
else if (edge_vertices[k][1] == prev_vertex) {
5178 prev_vertex = edge_vertices[k][0];
5183 new_edge_idx < SIZE_MAX,
5184 "ERROR(%s): inconsistent cell_to_edge/edge_to_vertex data", routine)
5185 edge_idx = new_edge_idx;
5190 prev_vertex == edge_vertices[0][0],
5191 "ERROR(%s): inconsistent cell_to_edge/edge_to_vertex data", routine)
5195 MPI_Comm comm = dist_grid->
comm;
5196 int comm_rank, comm_size;
5200 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
5202 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
5205 ((
size_t)comm_size + num_missing_neighbours) *
sizeof(*int_buffer));
5206 int * temp_ranks = int_buffer;
5207 int * num_ranks = int_buffer + comm_size;
5208 memset(num_ranks, 0, num_missing_neighbours *
sizeof(*num_ranks));
5210 int * rank_buffer = NULL;
5211 size_t rank_buffer_array_size = 0;
5212 size_t rank_buffer_size = 0;
5214 for (
size_t i = 0; i < num_missing_neighbours; ++i) {
5222 temp_ranks, &curr_num_ranks);
5225 rank_buffer_size + (
size_t)curr_num_ranks);
5227 for (
int j = 0; j < curr_num_ranks; ++j) {
5228 int curr_rank = temp_ranks[j];
5229 if (curr_rank != comm_rank) {
5230 sendcounts[curr_rank] += 2;
5232 rank_buffer[rank_buffer_size++] = curr_rank;
5238 1, sendcounts, recvcounts, sdispls, rdispls, comm);
5241 (sdispls[comm_size] + sendcounts[comm_size-1])/2;
5243 (rdispls[comm_size-1] + recvcounts[comm_size-1])/2;
5246 xmalloc(2 * (send_count + recv_count) *
sizeof(*yac_int_buffer));
5249 size_t * result_reorder_idx =
5250 xmalloc(send_count *
sizeof(*result_reorder_idx));
5253 for (
size_t i = 0, k = 0, rank_offset = 0; i < num_missing_neighbours; ++i) {
5255 int * curr_rank_buffer = rank_buffer + rank_offset;
5256 int curr_num_ranks = num_ranks[i];
5257 rank_offset += (size_t)curr_num_ranks;
5259 for (
int j = 0; j < curr_num_ranks; ++j, ++k) {
5261 int rank = curr_rank_buffer[j];
5263 if (rank == comm_rank)
continue;
5265 size_t pos = sdispls[rank + 1];
5266 sdispls[rank + 1] += 2;
5277 yac_alltoallv_yac_int_p2p(
5279 recv_buffer, recvcounts, rdispls, comm, routine, __LINE__);
5282 xmalloc(recv_count *
sizeof(*request_edge_ids));
5283 size_t * reorder_idx =
xmalloc(recv_count *
sizeof(*reorder_idx));
5286 (send_count + recv_count) *
sizeof(*point_info_buffer));
5289 point_info_buffer + recv_count;
5290 for (
size_t i = 0; i < recv_count; ++i) {
5296 request_edge_ids, recv_count, reorder_idx);
5298 size_t * sorted_edge_reorder_idx =
5304 for (
size_t i = 0, j = 0; i < recv_count; ++i) {
5306 yac_int curr_edge_id = request_edge_ids[i];
5307 size_t curr_reorder_idx = reorder_idx[i];
5309 while ((j < num_edges) && (sorted_edge_ids[j] < curr_edge_id)) ++j;
5312 if ((j >= num_edges) || (sorted_edge_ids[j] != curr_edge_id)) {
5313 point_send_buffer[curr_reorder_idx] =
5316 .data = {.rank = comm_rank, .orig_pos = UINT64_MAX}};
5323 size_t * local_edge_cell_ids = edge_to_cell[sorted_edge_reorder_idx[j]];
5324 yac_int global_edge_cell_ids[2];
5325 for (
int k = 0; k < 2; ++k)
5326 global_edge_cell_ids[k] =
5327 (local_edge_cell_ids[k] == SIZE_MAX)?
5328 YAC_INT_MAX:cell_ids[local_edge_cell_ids[k]];
5330 int missing_idx = global_edge_cell_ids[0] == available_edge_cell_id;
5334 (global_edge_cell_ids[missing_idx^1] == available_edge_cell_id) ||
5335 (global_edge_cell_ids[missing_idx^1] == YAC_INT_MAX),
5336 "ERROR(%s): inconsistent cell edge grid data", routine)
5338 point_send_buffer[curr_reorder_idx].
global_id =
5339 global_edge_cell_ids[missing_idx];
5340 point_send_buffer[curr_reorder_idx].
data.
rank = comm_rank;
5342 (local_edge_cell_ids[missing_idx] == SIZE_MAX)?
5343 (uint64_t)UINT64_MAX:local_edge_cell_ids[missing_idx];
5346 free(request_edge_ids);
5347 free(yac_int_buffer);
5349 for (
int i = 0; i < comm_size; ++i) {
5356 MPI_Datatype single_remote_point_dt =
5360 point_send_buffer, recvcounts, rdispls,
5361 point_recv_buffer, sendcounts, sdispls,
5362 sizeof(*point_send_buffer), single_remote_point_dt, comm,
5365 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
5368 xmalloc(send_count *
sizeof(*results));
5370 for (
size_t i = 0; i < send_count; ++i) {
5371 results[i].
data = point_recv_buffer[i];
5375 qsort(results, send_count,
sizeof(*results),
5379 size_t result_count = 0;
5380 yac_int prev_global_id = YAC_INT_MAX;
5381 for (
size_t i = 0, prev_reorder_idx = SIZE_MAX; i < send_count; ++i) {
5385 if (curr_global_id == YAC_INT_MAX)
continue;
5388 if (curr_reorder_idx != prev_reorder_idx){
5390 results[result_count++] = results[i];
5391 prev_reorder_idx = curr_reorder_idx;
5392 prev_global_id = curr_global_id;
5397 prev_global_id == curr_global_id,
5398 "ERROR(%s): inconsistent cell edge data", routine)
5401 for (
size_t i = 0; i < result_count; ++i) {
5402 point_send_buffer[i] = results[i].
data;
5407 size_t * local_ids =
xmalloc(result_count *
sizeof(*local_ids));
5410 dist_grid, point_send_buffer, result_count,
YAC_LOC_CELL, local_ids);
5412 for (
size_t i = 0; i < result_count; ++i)
5413 neighbours[result_reorder_idx[i]] = local_ids[i];
5416 free(result_reorder_idx);
5417 free(point_send_buffer);
5422 free(edge_vertices);
5428 size_t * cells,
size_t count,
size_t * neighbours) {
5437 size_t * points,
size_t count) {
5445 for (
size_t i = 0; i <
count; ++i) {
5447 point_infos[points[i]].
count > 0,
5448 "ERROR(yac_dist_grid_get_remote_points): "
5449 "owner count has to be > 0 (got %d)", point_infos[points[i]].
count)
5459 return (
int)(
value / 128) % comm_size;
5464 int global_id_pack_size;
5467 MPI_Pack_size(1,
yac_int_dt, comm, &global_id_pack_size), comm);
5469 return global_id_pack_size;
5473 yac_int global_id,
void *
buffer,
int buffer_size,
int * position,
5478 buffer_size, position, comm), comm);
5482 void *
buffer,
int buffer_size,
int * position,
yac_int * global_id,
5486 MPI_Unpack(
buffer, buffer_size, position, global_id, 1,
5491 MPI_Datatype single_remote_point_dt, MPI_Comm comm) {
5496 MPI_Pack_size(1, single_remote_point_dt, comm, &pack_size), comm);
5503 void *
buffer,
int buffer_size,
int * position,
5504 MPI_Datatype single_remote_point_dt, MPI_Comm comm) {
5507 MPI_Pack(point, 1, single_remote_point_dt,
buffer,
5508 buffer_size, position, comm), comm);
5512 void *
buffer,
int buffer_size,
int * position,
5517 MPI_Unpack(
buffer, buffer_size, position, point, 1,
5518 single_remote_point_dt, comm), comm);
5523 yac_int * global_ids,
size_t count,
size_t * local_ids) {
5525 char const * routine =
"yac_dist_grid_global_to_local";
5527 MPI_Comm comm = dist_grid->
comm;
5528 int comm_rank, comm_size;
5532 size_t * size_t_buffer =
5533 xmalloc((8 * (
size_t)comm_size + 1) *
sizeof(*size_t_buffer));
5534 size_t * sendcounts = size_t_buffer + 0 * comm_size;
5535 size_t * recvcounts = size_t_buffer + 2 * comm_size;
5536 size_t * sdispls = size_t_buffer + 4 * comm_size;
5537 size_t * rdispls = size_t_buffer + 5 * comm_size + 1;
5538 size_t * total_sendcounts = size_t_buffer + 6 * comm_size + 1;
5539 size_t * total_recvcounts = size_t_buffer + 7 * comm_size + 1;
5540 memset(sendcounts, 0, 2 * (
size_t)comm_size *
sizeof(*sendcounts));
5542 size_t * core_points, core_count;
5545 .coordinates_idx = SIZE_MAX,
5546 .masks_idx = SIZE_MAX};
5548 dist_grid, dummy_interp_field, &core_points, &core_count);
5549 yac_int const * grid_global_ids =
5552 int * rank_buffer =
xmalloc((count + core_count) *
sizeof(*rank_buffer));
5553 int * core_point_ranks = rank_buffer;
5554 int * global_id_ranks = rank_buffer + core_count;
5556 size_t * global_id_reorder_idx =
5557 xmalloc(count *
sizeof(*global_id_reorder_idx));
5559 for (
size_t i = 0; i < count; ++i) {
5562 sendcounts[2 * rank + 0]++;
5563 global_id_reorder_idx[i] = i;
5568 for (
size_t i = 0; i < core_count; ++i) {
5569 size_t point_idx = core_points[i];
5571 (core_point_ranks[i] =
5573 sendcounts[2 * rank + 1]++;
5584 size_t recv_core_count = 0;
5585 for (
int i = 0; i < comm_size; ++i)
5586 recv_core_count += recvcounts[2*i+1];
5588 MPI_Datatype single_remote_point_dt =
5591 int core_point_pack_size =
5594 for (
int i = 0; i < comm_size; ++i) {
5595 total_sendcounts[i] = sendcounts[2*i+0] * (size_t)global_id_pack_size +
5596 sendcounts[2*i+1] * (
size_t)core_point_pack_size;
5597 total_recvcounts[i] = recvcounts[2*i+0] * (size_t)global_id_pack_size +
5598 recvcounts[2*i+1] * (
size_t)core_point_pack_size;
5601 size_t saccu = 0, raccu = 0;
5603 for (
int i = 0; i < comm_size; ++i) {
5604 sdispls[i+1] = saccu;
5606 saccu += total_sendcounts[i];
5607 raccu += total_recvcounts[i];
5610 size_t send_size = sdispls[comm_size] + total_sendcounts[comm_size-1];
5611 size_t recv_size = rdispls[comm_size-1] + total_recvcounts[comm_size-1];
5612 void * pack_buffer =
xmalloc(send_size + recv_size);
5614 void *
recv_buffer = (
void*)((
unsigned char *)pack_buffer + send_size);
5617 for (
size_t i = 0; i < count; ++i) {
5618 yac_int curr_global_id = global_ids[global_id_reorder_idx[i]];
5619 int rank = global_id_ranks[i];
5620 size_t pos = sdispls[rank + 1];
5623 curr_global_id, (
void*)((
unsigned char*)
send_buffer + pos),
5624 global_id_pack_size, &position, comm);
5625 sdispls[rank + 1] += global_id_pack_size;
5627 for (
size_t i = 0; i < core_count; ++i) {
5628 size_t point_idx = core_points[i];
5629 int rank = core_point_ranks[i];
5630 size_t pos = sdispls[rank + 1];
5632 curr_core_point.
global_id = grid_global_ids[point_idx];
5633 curr_core_point.
data.
rank = comm_rank;
5639 core_point_pack_size, &position, single_remote_point_dt, comm);
5640 sdispls[rank + 1] += core_point_pack_size;
5646 yac_alltoallv_packed_p2p(
5648 recv_buffer, total_recvcounts, rdispls, comm, routine, __LINE__);
5650 size_t num_requested_ids = 0;
5651 for(
int i = 0; i < comm_size; ++i)
5652 num_requested_ids += recvcounts[2*i+0];
5654 yac_int * request_global_ids =
5655 xmalloc(num_requested_ids *
sizeof(*request_global_ids));
5656 size_t * reorder_idx =
5657 xmalloc(num_requested_ids *
sizeof(*reorder_idx));
5659 xmalloc((recv_core_count + num_requested_ids + count) *
5660 sizeof(*point_info_buffer));
5663 point_info_buffer + recv_core_count;
5665 point_info_buffer + recv_core_count + num_requested_ids;
5668 num_requested_ids = 0;
5669 recv_core_count = 0;
5670 for (
int i = 0; i < comm_size; ++i) {
5672 size_t curr_num_requested_ids = recvcounts[2*i+0];
5673 size_t curr_num_core_points = recvcounts[2*i+1];
5675 for (
size_t j = 0; j < curr_num_requested_ids; ++j, ++num_requested_ids) {
5680 request_global_ids + num_requested_ids, comm);
5681 reorder_idx[num_requested_ids] = num_requested_ids;
5684 for (
size_t j = 0; j < curr_num_core_points; ++j, ++recv_core_count) {
5689 recv_core_points + recv_core_count, single_remote_point_dt, comm);
5697 request_global_ids, num_requested_ids, reorder_idx);
5700 qsort(recv_core_points, recv_core_count,
sizeof(*recv_core_points),
5704 for (
size_t i = 0, j = 0; i < num_requested_ids; ++i) {
5706 yac_int curr_global_id = request_global_ids[i];
5707 while ((j < recv_core_count) &&
5708 (recv_core_points[j].
global_id < curr_global_id)) ++j;
5711 (j < recv_core_count) &&
5712 (recv_core_points[j].
global_id == curr_global_id),
5713 "ERROR(%s): no matching core point found for global id %zu",
5714 routine, (
size_t)curr_global_id)
5716 send_point_info[reorder_idx[i]] = recv_core_points[j];
5719 free(request_global_ids);
5721 saccu = 0, raccu = 0;
5722 for (
int i = 0; i < comm_size; ++i) {
5726 int recvcount = sendcounts[2*i+0];
5727 int sendcount = recvcounts[2*i+0];
5728 saccu += (sendcounts[i] = sendcount);
5729 raccu += (recvcounts[i] = recvcount);
5734 send_point_info, sendcounts, sdispls,
5735 recv_point_info, recvcounts, rdispls,
5736 sizeof(*send_point_info), single_remote_point_dt, comm,
5739 free(size_t_buffer);
5740 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
5743 dist_grid, recv_point_info, count,
location, local_ids);
5747 free(global_id_reorder_idx);
5748 free(point_info_buffer);
5753 size_t * vertices,
size_t count,
size_t ** cells,
5761 xmalloc(count *
sizeof(*vertex_bnd_circles));
5766 for (
size_t i = 0; i < count; ++i) {
5767 memcpy(vertex_bnd_circles[i].base_vector,
5769 vertex_bnd_circles[i].
inc_angle = sin_cos_high_tol;
5770 vertex_bnd_circles[i].
sq_crd = DBL_MAX;
5775 grid_pair, grid_name, vertex_bnd_circles, count,
5776 cells, num_cells_per_vertex, field);
5777 free(vertex_bnd_circles);
5780 size_t total_num_cells = 0;
5781 for (
size_t i = 0, k = 0; i < count; ++i) {
5783 size_t curr_vertex = vertices[i];
5784 size_t curr_num_cells_per_vertex = num_cells_per_vertex[i];
5786 size_t new_num_cells_per_vertex = 0;
5789 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j, ++k) {
5791 size_t curr_cell = (*cells)[k];
5792 size_t * curr_cell_vertices =
5797 size_t vertex_idx = 0;
5798 for (; vertex_idx < curr_cell_size; ++vertex_idx)
5799 if (curr_cell_vertices[vertex_idx] == curr_vertex)
break;
5802 if (vertex_idx == curr_cell_size)
continue;
5804 if (total_num_cells != k)
5805 (*cells)[total_num_cells] = curr_cell;
5806 ++new_num_cells_per_vertex;
5810 num_cells_per_vertex[i] = new_num_cells_per_vertex;
5813 *cells =
xrealloc(*cells, total_num_cells *
sizeof(**cells));
5839 size_t * vertices,
size_t count,
size_t ** cells,
5846 size_t * result_cells;
5847 size_t * num_result_per_vertex =
5850 grid_pair, grid_name, vertices,
count,
5851 &result_cells, num_result_per_vertex, field);
5853 size_t max_num_cell_per_vertex = 0;
5854 for (
size_t i = 0; i <
count; ++i)
5855 if (num_result_per_vertex[i] > max_num_cell_per_vertex)
5856 max_num_cell_per_vertex = num_result_per_vertex[i];
5857 size_t (*neigh_vertices)[2] =
5858 xmalloc(max_num_cell_per_vertex *
sizeof(*neigh_vertices));
5859 size_t * temp_vertex_cell =
5860 xmalloc(max_num_cell_per_vertex *
sizeof(*temp_vertex_cell));
5862 xmalloc(max_num_cell_per_vertex *
sizeof(*global_cell_ids));
5865 for (
size_t i = 0, offset = 0, new_offset = 0; i <
count; ++i) {
5867 size_t curr_vertex = vertices[i];
5868 size_t * curr_cells = result_cells + offset;
5869 size_t curr_num_cells_per_vertex = num_result_per_vertex[i];
5872 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j) {
5874 size_t curr_cell = curr_cells[j];
5875 size_t * curr_cell_vertices =
5879 size_t vertex_idx = 0;
5880 for (; vertex_idx < curr_cell_size; ++vertex_idx)
5881 if (curr_cell_vertices[vertex_idx] == curr_vertex)
break;
5884 vertex_idx != curr_cell_size,
5885 "ERROR(yac_dist_grid_pair_get_aux_grid_cells): "
5886 "internal error; cell %zu does not contain vertex %zu",
5887 curr_cell, curr_vertex)
5890 neigh_vertices[j][0] =
5891 curr_cell_vertices[((vertex_idx + curr_cell_size) - 1)%curr_cell_size];
5892 neigh_vertices[j][1] =
5893 curr_cell_vertices[(vertex_idx + 1)%curr_cell_size];
5895 if (new_offset != offset) result_cells[new_offset + j] = curr_cell;
5898 offset += curr_num_cells_per_vertex;
5899 curr_cells = result_cells + new_offset;
5901 if (curr_num_cells_per_vertex > 0) {
5904 temp_vertex_cell[0] = curr_cells[0];
5905 size_t start_neigh_vertex = neigh_vertices[0][0];
5906 size_t prev_vertex = neigh_vertices[0][1];
5907 for (
size_t j = 1, prev_cell_idx = 0; j < curr_num_cells_per_vertex; ++j) {
5910 for (k = 0; k < curr_num_cells_per_vertex; ++k) {
5912 if (k == prev_cell_idx)
continue;
5914 int flag = neigh_vertices[k][0] == prev_vertex;
5915 if (
flag || (neigh_vertices[k][1] == prev_vertex)) {
5916 temp_vertex_cell[j] = curr_cells[k];
5918 prev_vertex = neigh_vertices[k][
flag];
5925 if (k == curr_num_cells_per_vertex) {
5926 curr_num_cells_per_vertex = 0;
5930 if ((prev_vertex != start_neigh_vertex) ||
5931 (curr_num_cells_per_vertex < 3))
5932 curr_num_cells_per_vertex = 0;
5935 new_offset += curr_num_cells_per_vertex;
5936 num_cells_per_vertex[i] = (int)curr_num_cells_per_vertex;
5938 if (curr_num_cells_per_vertex == 0)
continue;
5941 yac_int min_global_cell_id = YAC_INT_MAX;
5942 size_t min_global_cell_id_idx = SIZE_MAX;
5943 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j) {
5945 ((global_cell_ids[j] =
5947 if (curr_global_cell_id < min_global_cell_id) {
5948 min_global_cell_id = curr_global_cell_id;
5949 min_global_cell_id_idx = j;
5956 ((min_global_cell_id_idx + curr_num_cells_per_vertex) - 1)%
5957 curr_num_cells_per_vertex] >
5959 (min_global_cell_id_idx + 1)%curr_num_cells_per_vertex])?-1:1;
5962 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j)
5965 ((
int)(min_global_cell_id_idx + curr_num_cells_per_vertex) +
5966 (
int)j * order)%(
int)curr_num_cells_per_vertex];
5969 *cells = result_cells;
5970 free(num_result_per_vertex);
5971 free(global_cell_ids);
5972 free(temp_vertex_cell);
5973 free(neigh_vertices);
5978 size_t * vertices,
size_t count,
size_t ** neigh_vertices_,
5989 size_t * cell_of_vertex;
5990 size_t * num_cells_per_vertex =
5993 grid_pair, grid_name, vertices,
count, &cell_of_vertex,
5994 num_cells_per_vertex, field);
5998 size_t total_num_neigh = 0;
5999 size_t max_num_neigh = 0;
6000 for (
size_t i = 0; i <
count; ++i) {
6004 total_num_neigh += num_cells_per_vertex[i] + 1;
6005 if (num_cells_per_vertex[i] > max_num_neigh) {
6006 max_num_neigh = num_cells_per_vertex[i];
6011 int const * vertex_mask = NULL;
6017 size_t * neigh_vertices =
6018 xmalloc(total_num_neigh *
sizeof(*neigh_vertices));
6019 size_t * temp_neigh_vertices =
6020 xmalloc(2 * max_num_neigh *
sizeof(*temp_neigh_vertices));
6021 total_num_neigh = 0;
6024 for (
size_t i = 0, offset = 0; i <
count; ++i) {
6027 size_t curr_vertex = vertices[i];
6028 size_t * curr_cells_of_vertex = cell_of_vertex + offset;
6029 size_t curr_num_cells_per_vertex = num_cells_per_vertex[i];
6031 size_t curr_num_neigh_vertices = 0;
6034 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j) {
6037 size_t curr_cell = curr_cells_of_vertex[j];
6038 size_t * curr_cell_vertices =
6044 size_t vertex_idx = 0;
6045 for (; vertex_idx < curr_cell_size; ++vertex_idx)
6046 if (curr_cell_vertices[vertex_idx] == curr_vertex)
break;
6049 vertex_idx != curr_cell_size,
6050 "ERROR(yac_dist_grid_pair_get_vertex_neighbours): "
6051 "internal error; cell %zu does not contain vertex %zu",
6052 curr_cell, curr_vertex)
6056 size_t neigh_vertex_idx =
6057 curr_cell_vertices[((vertex_idx + curr_cell_size) - 1)%curr_cell_size];
6058 if ((vertex_mask == NULL) || (vertex_mask[neigh_vertex_idx]))
6059 temp_neigh_vertices[curr_num_neigh_vertices++] = neigh_vertex_idx;
6061 curr_cell_vertices[(vertex_idx + 1)%curr_cell_size];
6062 if ((vertex_mask == NULL) || (vertex_mask[neigh_vertex_idx]))
6063 temp_neigh_vertices[curr_num_neigh_vertices++] = neigh_vertex_idx;
6068 qsort(temp_neigh_vertices, curr_num_neigh_vertices,
6071 temp_neigh_vertices, &curr_num_neigh_vertices);
6072 memcpy(neigh_vertices + total_num_neigh, temp_neigh_vertices,
6073 curr_num_neigh_vertices *
sizeof(*neigh_vertices));
6077 total_num_neigh += curr_num_neigh_vertices;
6078 num_neighs_per_vertex[i] = curr_num_neigh_vertices;
6080 offset += curr_num_cells_per_vertex;
6082 free(temp_neigh_vertices);
6084 free(cell_of_vertex);
6085 free(num_cells_per_vertex);
6089 xrealloc(neigh_vertices, total_num_neigh *
sizeof(*neigh_vertices));
6094 size_t * vertices,
size_t count,
size_t ** vertex_to_cell,
6095 size_t * num_cells_per_vertex) {
6103 .coordinates_idx = SIZE_MAX,
6104 .masks_idx = SIZE_MAX};
6106 grid_pair, grid_name, vertices, count, vertex_to_cell,
6107 num_cells_per_vertex, dummy_interp_field);
6109 size_t max_num_cells_per_vertex = 0;
6110 for (
size_t i = 0; i < count; ++i)
6111 if (num_cells_per_vertex[i] > max_num_cells_per_vertex)
6112 max_num_cells_per_vertex = num_cells_per_vertex[i];
6115 xmalloc(max_num_cells_per_vertex *
sizeof(*global_id_buffer));
6120 (count == 0) || (global_cell_ids != NULL),
6121 "ERROR(yac_dist_grid_pair_get_corner_cells): no global cell ids")
6124 for (
size_t i = 0, offset = 0; i < count; ++i) {
6126 size_t curr_num_cells_per_vertex = num_cells_per_vertex[i];
6127 size_t * curr_vertex_to_cell = *vertex_to_cell + offset;
6128 offset += curr_num_cells_per_vertex;
6131 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j)
6132 global_id_buffer[j] = global_cell_ids[curr_vertex_to_cell[j]];
6136 global_id_buffer, curr_num_cells_per_vertex, curr_vertex_to_cell);
6139 free(global_id_buffer);
6144 size_t * cells,
size_t count,
6145 size_t ** vertex_to_cell,
size_t ** vertex_to_cell_offsets_,
6152 size_t * temp_cells =
xmalloc(
count *
sizeof(*temp_cells));
6153 int * required_vertices =
6155 memcpy(temp_cells, cells,
count *
sizeof(*cells));
6157 for (
size_t i = 0, prev_cell = SIZE_MAX; i <
count; ++i) {
6158 size_t curr_cell = temp_cells[i];
6159 if (curr_cell == SIZE_MAX)
break;
6160 if (curr_cell != prev_cell) {
6161 prev_cell = curr_cell;
6163 size_t const * curr_vertices =
6165 for (
size_t j = 0; j < curr_num_vertices; ++j)
6166 required_vertices[curr_vertices[j]] = 1;
6172 size_t num_unique_vertices = 0;
6174 if (required_vertices[i]) ++num_unique_vertices;
6175 size_t * unique_vertices =
6176 xmalloc(num_unique_vertices *
sizeof(*unique_vertices));
6178 if (required_vertices[i]) unique_vertices[j++] = i;
6179 free(required_vertices);
6182 int * num_cells_per_vertex =
6183 xcalloc(num_unique_vertices,
sizeof(*num_cells_per_vertex));
6185 grid_pair, grid_name, unique_vertices, num_unique_vertices,
6186 vertex_to_cell, num_cells_per_vertex, field);
6188 int * grid_num_cells_per_vertex =
6191 sizeof(*grid_num_cells_per_vertex));
6193 for (
size_t i = 0; i < num_unique_vertices; ++i)
6194 grid_num_cells_per_vertex[unique_vertices[i]] =
6195 num_cells_per_vertex[i];
6196 free(num_cells_per_vertex);
6197 free(unique_vertices);
6199 size_t * vertex_to_cell_offsets =
6202 sizeof(*vertex_to_cell_offsets));
6205 vertex_to_cell_offsets[i] = offset;
6206 offset += grid_num_cells_per_vertex[i];
6209 *vertex_to_cell_offsets_ = vertex_to_cell_offsets;
6210 *num_cells_per_vertex_ = grid_num_cells_per_vertex;
6214 size_t ** points,
size_t * reorder_idx,
int * ranks,
size_t count,
6218 size_t * sendcounts,
size_t * sdispls,
size_t * recvcounts,
size_t * rdispls,
6219 MPI_Datatype single_remote_point_dt, MPI_Comm
comm,
6222 char const * routine =
"relocate_points";
6230 size_t * old_points = *points;
6231 size_t * new_points =
6232 xmalloc((local_count + recv_count) *
sizeof(*new_points));
6234 for (
size_t i = 0, j = 0, k = 0; i <
count; ++i) {
6235 size_t idx = reorder_idx[i];
6236 size_t curr_point = old_points[idx];
6237 int curr_rank = ranks[i];
6238 if (curr_rank == comm_rank) {
6239 new_points[j++] = curr_point;
6241 id_send_buffer[k].
global_id = global_ids[curr_point];
6242 id_send_buffer[k].
data.
rank = comm_rank;
6250 id_send_buffer, sendcounts, sdispls,
6251 id_recv_buffer, recvcounts, rdispls,
6252 sizeof(*id_send_buffer), single_remote_point_dt,
comm, routine, __LINE__);
6257 dist_grid, id_recv_buffer, recv_count,
location,
6258 new_points + local_count);
6260 *points = new_points;
6265 double ** weights,
size_t * reorder_idx,
int * ranks,
size_t count,
6266 size_t send_count,
size_t local_count,
size_t recv_count,
6267 size_t * sendcounts,
size_t * sdispls,
size_t * recvcounts,
size_t * rdispls,
6270 char const * routine =
"relocate_weights";
6275 double * old_weights = *weights;
6280 for (
size_t i = 0, j = 0, k = 0; i <
count; ++i) {
6281 size_t idx = reorder_idx[i];
6282 double curr_weight = old_weights[idx];
6283 int curr_rank = ranks[i];
6284 if (curr_rank == comm_rank)
recv_buffer[j++] = curr_weight;
6302 size_t * vertices,
size_t count,
int * ranks) {
6304 size_t * reorder_idx =
xmalloc(
count *
sizeof(*reorder_idx));
6305 for (
size_t i = 0; i <
count; ++i) reorder_idx[i] = i;
6309 for (valid_count = 0;
6310 (valid_count <
count) && (vertices[valid_count] != SIZE_MAX);
6313 for (
size_t i = valid_count; i <
count; ++i) ranks[reorder_idx[i]] = 0;
6315 size_t unique_count = 0;
6316 size_t prev_vertex = SIZE_MAX;
6317 for (
size_t i = 0; i < valid_count; ++i) {
6318 size_t curr_vertex = vertices[i];
6319 if (curr_vertex != prev_vertex) {
6320 prev_vertex = curr_vertex;
6327 xmalloc(unique_count *
sizeof(*search_coords));
6329 prev_vertex = SIZE_MAX;
6330 for (
size_t i = 0, j = 0; i < valid_count; ++i) {
6331 size_t curr_vertex = vertices[i];
6332 if (curr_vertex != prev_vertex) {
6333 prev_vertex = curr_vertex;
6335 search_coords[j++], grid_coords[curr_vertex], 3 *
sizeof(
double));
6339 int * temp_ranks =
xmalloc(unique_count *
sizeof(*temp_ranks));
6341 proc_sphere_part, search_coords, unique_count, temp_ranks);
6343 prev_vertex = SIZE_MAX;
6344 for (
size_t i = 0, j = 0; i < valid_count; ++i) {
6345 size_t curr_vertex = vertices[i];
6346 if (curr_vertex != prev_vertex) {
6347 prev_vertex = curr_vertex;
6350 ranks[reorder_idx[i]] = temp_ranks[j-1];
6355 free(search_coords);
6362 size_t * indices,
size_t count,
int * ranks,
6363 size_t (*get_ce_reference_vertex)(
struct yac_dist_grid *,
size_t)) {
6365 size_t * reorder_idx =
xmalloc(
count *
sizeof(*reorder_idx));
6366 for (
size_t i = 0; i <
count; ++i) reorder_idx[i] = i;
6369 size_t unique_count = 0;
6370 size_t prev_index = SIZE_MAX;
6371 for (
size_t i = 0; i <
count; ++i) {
6372 size_t curr_index = indices[i];
6373 if (curr_index != prev_index) {
6374 prev_index = curr_index;
6379 size_t * ref_vertices =
xmalloc(unique_count *
sizeof(*ref_vertices));
6380 prev_index = SIZE_MAX;
6381 for (
size_t i = 0, j = 0; i <
count; ++i) {
6382 size_t curr_index = indices[i];
6383 if (curr_index != prev_index) {
6384 prev_index = curr_index;
6386 get_ce_reference_vertex(dist_grid, curr_index);
6390 int * temp_ranks =
xmalloc(unique_count *
sizeof(*temp_ranks));
6392 dist_grid, proc_sphere_part, ref_vertices, unique_count, temp_ranks);
6395 prev_index = SIZE_MAX;
6396 for (
size_t i = 0, j = 0; i <
count; ++i) {
6397 size_t curr_index = indices[i];
6398 if (curr_index != prev_index) {
6399 prev_index = curr_index;
6402 ranks[reorder_idx[i]] = temp_ranks[j-1];
6413 size_t * cells,
size_t count,
int * ranks) {
6416 dist_grid, proc_sphere_part, cells,
count, ranks,
6423 size_t * edges,
size_t count,
int * ranks) {
6426 dist_grid, proc_sphere_part, edges,
count, ranks,
6439 void (*determine_dist_owner[3])(
6442 size_t * cells,
size_t count,
int * ranks) =
6462 for (
size_t i = 0; i <
count; ++i) {
6467 int curr_count = curr_orig_owner->
count;
6470 "ERROR(yac_dist_grid_pair_determine_orig_owner): "
6471 "owner count has to be > 0 (got %d)", curr_count)
6472 if (curr_count == 1) {
6476 for (
int j = 1; j < curr_count; ++j) {
6478 if (min_rank > curr_rank) min_rank = curr_rank;
6481 ranks[i] = min_rank;
6487 char const * grid_name_a,
size_t ** points_a,
enum yac_location location_a,
6488 char const * grid_name_b,
size_t ** points_b,
enum yac_location location_b,
6489 double ** weights,
size_t *
count) {
6491 CHECK_GRID_NAME(
"yac_dist_grid_pair_relocate_point_pairs", grid_name_a);
6492 CHECK_GRID_NAME(
"yac_dist_grid_pair_relocate_point_pairs", grid_name_b);
6494 size_t count_ = *
count;
6496 MPI_Comm comm = grid_pair->
comm;
6497 int comm_rank, comm_size;
6502 int weight_flag_local =
6503 (count_ > 0) && (weights != NULL) && (*weights != NULL);
6505 yac_mpi_call(MPI_Allreduce(&weight_flag_local, &weight_flag, 1,
6506 MPI_INT, MPI_MAX, comm), comm);
6510 (count_ <= 0) || weight_flag_local || !weight_flag,
6511 "ERROR(yac_dist_grid_pair_relocate_point_pairs): weights")
6514 int * ranks =
xmalloc(count_ *
sizeof(ranks));
6515 size_t * reorder_idx =
xmalloc(count_ *
sizeof(reorder_idx));
6517 char const * grid_name = (a_is_ref)?grid_name_a:grid_name_b;
6518 size_t * points = (a_is_ref)?*points_a:*points_b;
6522 grid_pair, grid_name, points, count_,
location, ranks);
6525 grid_pair, grid_name, points, count_,
location, ranks);
6527 for (
size_t i = 0; i < count_; ++i) reorder_idx[i] = i;
6530 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
6532 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
6533 for (
size_t i = 0; i < count_; ++i) sendcounts[ranks[i]]++;
6535 size_t local_count = sendcounts[comm_rank];
6536 sendcounts[comm_rank] = 0;
6539 1, sendcounts, recvcounts, sdispls, rdispls, comm);
6541 size_t send_count = sdispls[comm_size] + sendcounts[comm_size-1];
6542 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
6545 xmalloc((send_count + recv_count) *
6546 sizeof(*single_remote_point_buffer));
6551 MPI_Datatype single_remote_point_dt =
6555 points_a, reorder_idx, ranks, count_, location_a,
6556 local_count, recv_count, id_send_buffer, id_recv_buffer,
6557 sendcounts, sdispls + 1, recvcounts, rdispls,
6558 single_remote_point_dt, comm,
6561 points_b, reorder_idx, ranks, count_, location_b,
6562 local_count, recv_count, id_send_buffer, id_recv_buffer,
6563 sendcounts, sdispls + 1, recvcounts, rdispls,
6564 single_remote_point_dt, comm,
6566 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
6570 weights, reorder_idx, ranks, count_,
6571 send_count, local_count, recv_count,
6572 sendcounts, sdispls + 1, recvcounts, rdispls, comm);
6575 free(single_remote_point_buffer);
6579 *count = local_count + recv_count;
6596 xmalloc(num_edges *
sizeof(*edge_to_cell));
6598 for (
size_t i = 0; i < num_edges; ++i) {
6599 edge_to_cell[i][0] = SIZE_MAX;
6600 edge_to_cell[i][1] = SIZE_MAX;
6603 for (
size_t i = 0, offset = 0; i <
num_cells; ++i) {
6605 int curr_num_edges = num_edges_per_cell[i];
6607 offset += curr_num_edges;
6609 for (
int j = 0; j < curr_num_edges; ++j) {
6611 size_t curr_edge = curr_cell_to_edge[j];
6617 size_t * curr_edge_to_cell = edge_to_cell[curr_edge];
6618 curr_edge_to_cell += *curr_edge_to_cell != SIZE_MAX;
6620 *curr_edge_to_cell == SIZE_MAX,
6621 "ERROR(yac_dist_grid_generate_edge_to_cell): "
6622 "more than two cells point to a single edge "
6623 "(does the grid contain degenrated cells (less than 3 corners) "
6624 "or duplicated cells; "
6625 "these can be masked out using the core mask)\n"
6626 "(grid_name: \"%s\" num_cells: %zu cell_idx: %zu: num_cell_edge %d "
6627 "cell_ids(global): %" YAC_INT_FMT
", %" YAC_INT_FMT
", %" YAC_INT_FMT
" "
6628 "cell_ids(local): %zu, %zu, %zu)",
6629 grid_name,
num_cells, i, curr_num_edges,
6633 edge_to_cell[curr_edge][0], edge_to_cell[curr_edge][1], i)
6634 *curr_edge_to_cell = i;
6638 return edge_to_cell;
#define YAC_ASSERT(exp, msg)
struct yac_field_data * yac_basic_grid_get_field_data(struct yac_basic_grid *grid, enum yac_location location)
struct yac_basic_grid_data * yac_basic_grid_get_data(struct yac_basic_grid *grid)
char const * yac_basic_grid_get_name(struct yac_basic_grid *grid)
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
void yac_basic_grid_delete(struct yac_basic_grid *grid)
void yac_get_cell_bounding_circle(struct yac_grid_cell cell, struct bounding_circle *bnd_circle)
int yac_extents_overlap(struct bounding_circle *extent_a, struct bounding_circle *extent_b)
int yac_point_in_cell2(double point_coords[3], struct yac_grid_cell cell, struct bounding_circle bnd_circle)
static int compare_n_ids_reorder_ids(const void *a, const void *b)
#define CHECK_LOCATION(caller)
void yac_dist_grid_pair_do_point_search_gc(struct yac_dist_grid_pair *grid_pair, char const *grid_name, yac_coordinate_pointer search_coords, size_t count, size_t *cells)
void yac_dist_grid_pair_delete(struct yac_dist_grid_pair *grid_pair)
yac_const_coordinate_pointer yac_dist_grid_get_field_coords(struct yac_dist_grid *dist_grid, struct yac_interp_field field)
void yac_dist_grid_determine_dist_ce_owner(struct yac_dist_grid *dist_grid, struct proc_sphere_part_node *proc_sphere_part, size_t *indices, size_t count, int *ranks, size_t(*get_ce_reference_vertex)(struct yac_dist_grid *, size_t))
static int get_pack_size_base_cell(struct yac_field_data *cell_field_data, MPI_Datatype bnd_circle_dt, MPI_Comm comm)
static int compare_single_remote_point_reorder_global_id(const void *a, const void *b)
static void unpack_global_id(void *buffer, int buffer_size, int *position, yac_int *global_id, MPI_Comm comm)
size_t yac_dist_grid_get_unmasked_local_count(struct yac_dist_grid *dist_grid, struct yac_interp_field field)
static struct point_sphere_part_search * yac_dist_grid_get_field_sphere_part(struct yac_dist_grid *dist_grid, struct yac_interp_field field)
static void pack_grid_data_vertex(struct yac_dist_grid *dist_grid, size_t idx, void *buffer, int buffer_size, int *position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
static void ensure_temp_field_data_sizes(struct temp_field_data *temp_field_data, size_t size)
static void yac_dist_grid_get_cell_neighbours(struct yac_dist_grid *dist_grid, struct proc_sphere_part_node *proc_sphere_part, size_t *cells, size_t count, size_t *neighbours)
static int get_pack_size_base_edge(struct yac_field_data *edge_field_data, MPI_Comm comm)
void yac_dist_grid_pair_determine_dist_owner(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *points, size_t count, enum yac_location location, int *ranks)
void yac_dist_grid_pair_do_point_search(struct yac_dist_grid_pair *grid_pair, char const *grid_name, yac_coordinate_pointer search_coords, size_t count, size_t *cells)
static struct proc_sphere_part_node * generate_dist_grid_decomposition(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, int **vertex_ranks[2], MPI_Comm comm)
size_t yac_dist_grid_get_local_count(struct yac_dist_grid *dist_grid, enum yac_location location)
static void dist_grid_pair_do_point_search_local(struct yac_dist_grid_pair *grid_pair, char const *grid_name, yac_coordinate_pointer search_coords, size_t count, size_t *cells, int(*coord_in_cell)(double coord[3], struct yac_dist_grid *dist_grid, size_t cell_idx, struct yac_grid_cell *buffer_cell))
#define CHECK_GRID_NAME(caller, GRID_NAME)
static int * determine_edge_owner_mask(struct yac_dist_grid *dist_grid, int *vertex_owner_mask)
static void generate_dist_remote_points(struct proc_sphere_part_node *proc_sphere_part, struct yac_basic_grid *grid, int *vertex_ranks, int max_num_vertices_per_cell, MPI_Comm comm, struct remote_point_infos **dist_point_infos, yac_int **dist_global_ids, size_t *dist_count)
void yac_dist_grid_pair_do_nnn_search(struct yac_dist_grid_pair *grid_pair, char const *grid_name, yac_coordinate_pointer search_coords, size_t count, size_t *local_ids, size_t n, struct yac_interp_field field, double max_search_distance)
static int compare_size_t(const void *a, const void *b)
static void redistribute_vertex_data(struct yac_basic_grid *grid, struct remote_point_infos *dist_vertex_infos, size_t num_vertices, MPI_Comm comm, MPI_Datatype dt_coord, int *vertex_ranks, yac_coordinate_pointer *vertex_coordinates_, int **vertex_owner_, struct yac_field_data **vertex_field_data_)
static void temp_field_data_free(struct temp_field_data temp_field_data)
void yac_dist_grid_pair_get_vertex_neighbours(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *vertices, size_t count, size_t **neigh_vertices_, int *num_neighs_per_vertex, struct yac_interp_field field)
static struct yac_field_data * field_data_init(struct yac_field_data *orig_field_data, size_t dist_size, Xt_redist redist_mask, Xt_redist redist_coords, MPI_Comm comm)
static int * determine_cell_owner_mask(struct yac_dist_grid *dist_grid, int is_root, int *vertex_owner_mask)
static int compare_single_remote_point_reorder_reorder_idx(const void *a, const void *b)
void yac_dist_grid_determine_dist_cell_owner(struct yac_dist_grid *dist_grid, struct proc_sphere_part_node *proc_sphere_part, size_t *cells, size_t count, int *ranks)
static void unpack_field_data(void *buffer, int buffer_size, int *position, size_t idx, struct temp_field_data temp_field_data, MPI_Comm comm)
yac_size_t_2_pointer yac_dist_grid_generate_edge_to_cell(struct yac_dist_grid_pair *grid_pair, char const *grid_name)
static yac_size_t_2_pointer generate_edge_to_cell(const_size_t_pointer cell_to_edge, const_int_pointer num_edges_per_cell, int *core_cell_mask, size_t num_cells, size_t num_edges)
static int get_pack_size_field_data(struct yac_field_data *field_data, MPI_Comm comm)
static void generate_sorted_ids(yac_int *global_ids, size_t count, yac_int **sorted_global_ids, size_t **reorder_idx)
static void do_nnn_search_local(struct yac_dist_grid *dist_grid, struct yac_interp_field field, size_t count, yac_coordinate_pointer search_coords, size_t n, double cos_max_search_distance, size_t *result_points)
static MPI_Datatype yac_get_coordinate_mpi_datatype(MPI_Comm comm)
static int compute_bucket(yac_int value, int comm_size)
static size_t yac_dist_grid_get_count(struct yac_dist_grid *dist_grid, enum yac_location location)
static void add_field_data(struct yac_field_data *field_data, struct temp_field_data temp_field_data, void *reorder_idx, size_t reorder_idx_size, size_t old_count, size_t new_count)
static int get_single_remote_point_pack_size(MPI_Datatype single_remote_point_dt, MPI_Comm comm)
static void generate_global_ids(struct yac_basic_grid *grid, int *vertex_ranks, int max_num_vertices_per_cell, MPI_Comm comm)
static void generate_ce_ids(struct yac_basic_grid_data *grid_data, int *vertex_ranks, int max_num_vertices_per_cell, MPI_Comm comm)
static void get_pack_sizes_edge(struct yac_dist_grid *dist_grid, uint64_t *pos, size_t count, int *pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm)
static struct bounding_circle compute_dist_edge_bnd_circle(struct yac_dist_grid *dist_grid, size_t edge_id)
struct yac_dist_grid * yac_dist_grid_pair_get_dist_grid(struct yac_dist_grid_pair *grid_pair, char const *grid_name)
static int compare_single_remote_point_reorder_owner(const void *a, const void *b)
static size_t yac_dist_grid_get_total_count(struct yac_dist_grid *dist_grid, enum yac_location location)
void yac_dist_grid_pair_do_dnn_search(struct yac_dist_grid_pair *grid_pair, char const *grid_name, const_bounding_circle_pointer bnd_circles, size_t count, size_t **points, size_t *num_results_per_bnd_circle, struct yac_interp_field field)
static void insert_global_id(yac_int *ids, size_t n, yac_int id)
static void get_pack_sizes_vertex(struct yac_dist_grid *dist_grid, uint64_t *pos, size_t count, int *pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm)
static void relocate_weights(double **weights, size_t *reorder_idx, int *ranks, size_t count, size_t send_count, size_t local_count, size_t recv_count, size_t *sendcounts, size_t *sdispls, size_t *recvcounts, size_t *rdispls, MPI_Comm comm)
static struct yac_dist_grid generate_dist_grid(struct proc_sphere_part_node *proc_sphere_part, int *vertex_ranks, struct yac_basic_grid *grid, MPI_Comm comm)
static void setup_search_data(struct yac_dist_grid_pair *dist_grid_pair)
static struct temp_field_data temp_field_data_init(struct yac_field_data *field_data, size_t count)
struct yac_dist_grid_pair * yac_dist_grid_pair_new(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, MPI_Comm comm)
int const * yac_dist_grid_get_field_mask(struct yac_dist_grid *dist_grid, struct yac_interp_field field)
static void relocate_points(size_t **points, size_t *reorder_idx, int *ranks, size_t count, enum yac_location location, size_t local_count, size_t recv_count, struct single_remote_point *id_send_buffer, struct single_remote_point *id_recv_buffer, size_t *sendcounts, size_t *sdispls, size_t *recvcounts, size_t *rdispls, MPI_Datatype single_remote_point_dt, MPI_Comm comm, struct yac_dist_grid *dist_grid)
static void get_pack_sizes_cell(struct yac_dist_grid *dist_grid, uint64_t *pos, size_t count, int *pack_sizes, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
static int compare_single_remote_point_global_id(const void *a, const void *b)
static void generate_vertex_to_edge(yac_size_t_2_pointer edge_to_vertex, size_t num_edges, size_t num_vertices, size_t *vertex_to_edge, int *num_edges_per_vertex)
static void yac_dist_grid_add_vertices(struct yac_dist_grid *dist_grid, struct global_vertex_reorder *vertices, size_t count, size_t *idx, struct temp_field_data temp_vertex_field_data)
static int get_global_id_pack_size(MPI_Comm comm)
void yac_dist_grid_determine_dist_vertex_owner(struct yac_dist_grid *dist_grid, struct proc_sphere_part_node *proc_sphere_part, size_t *vertices, size_t count, int *ranks)
static void unpack_grid_data_edge(struct global_edge_reorder *edge, size_t idx, void *buffer, int buffer_size, int *position, struct temp_field_data temp_edge_field_data, MPI_Datatype point_info_dt, MPI_Comm comm)
static int get_pack_size_base_vertex(struct yac_field_data *vertex_field_data, MPI_Comm comm)
static void yac_dist_grid_get_n_unmasked_local_points(struct yac_dist_grid *dist_grid, struct yac_interp_field field, int comm_rank, size_t n, struct single_remote_point *points)
struct yac_dist_grid_pair * yac_dist_grid_pair_new_f2c(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, MPI_Fint comm)
static size_t get_cell_reference_vertex(struct yac_dist_grid *dist_grid, size_t cell_idx)
static void yac_single_remote_point_unpack(void *buffer, int buffer_size, int *position, struct single_remote_point *point, MPI_Datatype single_remote_point_dt, MPI_Comm comm)
void yac_dist_grid_pair_get_cell_neighbours(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *cells, size_t count, size_t *neighbours)
void yac_dist_grid_get_local_unmasked_points(struct yac_dist_grid *dist_grid, struct yac_interp_field field, size_t **indices, size_t *num_indices)
static void yac_remote_point_infos_single_free(struct remote_point_infos *point_infos)
static struct bounding_circle * generate_cell_bounding_circles(size_t num_cells, int max_num_vertices_per_cell, int *num_vertices_per_cell, size_t *cell_to_vertex, size_t *cell_to_vertex_offsets, yac_coordinate_pointer vertex_coordinates, size_t *cell_to_edge, size_t *cell_to_edge_offsets, enum yac_edge_type *edge_type)
void yac_dist_grid_determine_dist_edge_owner(struct yac_dist_grid *dist_grid, struct proc_sphere_part_node *proc_sphere_part, size_t *edges, size_t count, int *ranks)
static void get_dist_vertex_cells(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *vertices, size_t count, size_t **cells, size_t *num_cells_per_vertex, struct yac_interp_field field)
struct remote_point * yac_dist_grid_get_remote_points(struct yac_dist_grid *dist_grid, enum yac_location location, size_t *points, size_t count)
struct yac_const_basic_grid_data * yac_dist_grid_get_basic_grid_data(struct yac_dist_grid *dist_grid)
void yac_dist_grid_pair_relocate_point_pairs(struct yac_dist_grid_pair *grid_pair, int a_is_ref, int to_dist_owner, char const *grid_name_a, size_t **points_a, enum yac_location location_a, char const *grid_name_b, size_t **points_b, enum yac_location location_b, double **weights, size_t *count)
static void determine_dist_edge_ranks(struct proc_sphere_part_node *proc_sphere_part, struct yac_basic_grid *grid, MPI_Comm comm, size_t *dist_cell_rank_offsets, size_t *dist_edge_rank_offsets, int *num_cell_ranks, int *num_edge_ranks, int **rank_buffer, size_t *rank_buffer_array_size)
static int coord_in_cell(double coord[3], struct yac_dist_grid *dist_grid, size_t cell_idx, struct yac_grid_cell *buffer_cell)
static void check_core_masks(struct yac_basic_grid *grid)
static char const yac_dist_grid_dummy_name[]
static void pack_grid_data_edge(struct yac_dist_grid *dist_grid, size_t idx, void *buffer, int buffer_size, int *position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
static size_t get_edge_reference_vertex(struct yac_dist_grid *dist_grid, size_t edge_idx)
static void insert_rank(int *ranks, int *count, int rank)
static void pack_field_data(size_t idx, void *buffer, int buffer_size, int *position, struct yac_field_data *field_data, MPI_Comm comm)
static void yac_dist_grid_add_cells(struct yac_dist_grid *dist_grid, yac_int *cell_ids, int *num_vertices_per_cell, struct bounding_circle *cell_bnd_circles, size_t count, size_t *cell_to_vertex, size_t *cell_to_edge, struct remote_point_infos *cell_owners, struct temp_field_data temp_cell_field_data)
void yac_dist_grid_pair_do_bnd_circle_search(struct yac_dist_grid_pair *grid_pair, char const *grid_name, const_bounding_circle_pointer bnd_circles, size_t count, size_t **cells, size_t *num_results_per_bnd_circle, struct yac_interp_field field)
void yac_dist_grid_pair_do_cell_search(struct yac_dist_grid_pair *grid_pair, char const *search_grid_name, char const *result_grid_name, size_t *search_cells, size_t count, size_t **result_cells, size_t *num_results_per_search_cell, struct yac_interp_field result_field)
static void id2idx(char const *caller, yac_int *ids, size_t *idx, size_t num_ids, yac_int *ref_sorted_ids, size_t *ref_sorted_reorder_idx, size_t num_sorted_ids)
static int compare_n_ids_reorder_reorder(const void *a, const void *b)
static MPI_Datatype yac_get_id_pos_mpi_datatype(MPI_Comm comm)
static void pack_grid_data(struct yac_dist_grid *dist_grid, enum yac_location location, uint64_t *pos, size_t count, void **pack_data, int *pack_sizes, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
MPI_Comm yac_dist_grid_pair_get_MPI_Comm(struct yac_dist_grid_pair *grid_pair)
static void pack_global_id(yac_int global_id, void *buffer, int buffer_size, int *position, MPI_Comm comm)
static void yac_dist_grid_pair_get_aux_grid_cells(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *vertices, size_t count, size_t **cells, int *num_cells_per_vertex, struct yac_interp_field field)
static int compare_global_vertex_reorder_global_id(const void *a, const void *b)
static yac_int const * yac_dist_grid_get_global_ids(struct yac_dist_grid *dist_grid, enum yac_location location)
static void pack_grid_data_cell(struct yac_dist_grid *dist_grid, size_t idx, void *buffer, int buffer_size, int *position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
static struct bounding_circle compute_edge_bnd_circle(yac_size_t_2_pointer edge_to_vertex, const yac_coordinate_pointer vertex_coordinates, size_t edge_id)
static void unpack_grid_data_vertex(struct global_vertex_reorder *vertex, size_t idx, void *buffer, int buffer_size, int *position, struct temp_field_data temp_vertex_field_data, MPI_Datatype point_info_dt, MPI_Comm comm)
static void unpack_grid_data(struct yac_dist_grid *dist_grid, enum yac_location location, size_t count, void *buffer, int buffer_size, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_dist_grid_global_to_local(struct yac_dist_grid *dist_grid, enum yac_location location, yac_int *global_ids, size_t count, size_t *local_ids)
static void unpack_grid_data_vertices(struct yac_dist_grid *dist_grid, size_t count, void *buffer, int buffer_size, MPI_Datatype point_info_dt, MPI_Comm comm)
static void yac_remote_point_infos_free(struct remote_point_infos *point_infos, size_t count)
void yac_const_basic_grid_data_get_grid_cell(struct yac_const_basic_grid_data *grid_data, size_t cell_idx, struct yac_grid_cell *buffer_cell)
static int compare_nnn_search_results_cos_angle(void const *a, void const *b)
void yac_dist_grid_pair_determine_orig_owner(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *points, size_t count, enum yac_location location, int *ranks)
void yac_dist_grid_pair_get_aux_grid(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *cells, size_t count, size_t **vertex_to_cell, size_t **vertex_to_cell_offsets_, int **num_cells_per_vertex_, struct yac_interp_field field)
static void generate_owner_masks(struct yac_dist_grid *dist_grid, int comm_rank, int *vertex_owner)
static void unpack_grid_data_cells(struct yac_dist_grid *dist_grid, size_t count, void *buffer, int buffer_size, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_dist_grid_pair_do_point_search_(struct yac_dist_grid_pair *grid_pair, char const *grid_name, yac_coordinate_pointer search_coords, size_t count, size_t *cells, int(*coord_in_cell)(double coord[3], struct yac_dist_grid *dist_grid, size_t cell_idx, struct yac_grid_cell *buffer_cell))
static void yac_dist_grid_add_edges(struct yac_dist_grid *dist_grid, struct global_edge_reorder *edges, size_t count, size_t *idx, struct temp_field_data temp_edge_field_data)
static int coord_in_cell_gc(double coord[3], struct yac_dist_grid *dist_grid, size_t cell_idx, struct yac_grid_cell *buffer_cell)
static void yac_dist_grid_single_remote_point_to_local(struct yac_dist_grid *dist_grid, struct single_remote_point *ids, size_t count, enum yac_location location, size_t *idx)
static void redistribute_cell_data(struct yac_basic_grid *grid, struct remote_point_infos *dist_cell_infos, size_t num_cells, MPI_Comm comm, MPI_Datatype dt_coord, size_t num_edges, yac_int *sorted_edge_ids, size_t *sorted_edge_reorder_idx, size_t num_vertices, yac_int *sorted_vertex_ids, size_t *sorted_vertex_reorder_idx, int max_num_vertices_per_cell, size_t **cell_to_vertex_, size_t **cell_to_edge_, int **num_vertices_per_cell_, struct yac_field_data **cell_field_data_)
void yac_dist_grid_pair_get_corner_cells(struct yac_dist_grid_pair *grid_pair, char const *grid_name, size_t *vertices, size_t count, size_t **vertex_to_cell, size_t *num_cells_per_vertex)
static int const * yac_dist_grid_get_owner_mask(struct yac_dist_grid *dist_grid, enum yac_location location)
static int compare_global_edge_reorder_global_id(const void *a, const void *b)
static void redistribute_edge_data(struct yac_basic_grid *grid, struct remote_point_infos *dist_edge_infos, size_t num_edges, MPI_Comm comm, MPI_Datatype dt_coord, size_t num_vertices, yac_int *sorted_vertex_ids, size_t *sorted_vertex_reorder_idx, yac_size_t_2_pointer *edge_to_vertex_, enum yac_edge_type **edge_type_, struct yac_field_data **edge_field_data_)
static void determine_dist_vertex_ranks(int *vertex_ranks, struct yac_basic_grid *grid, MPI_Comm comm, size_t *dist_edge_rank_offsets, int *num_edge_ranks, int *num_vertex_ranks, int **rank_buffer, size_t *rank_buffer_array_size)
static void unpack_grid_data_edges(struct yac_dist_grid *dist_grid, size_t count, void *buffer, int buffer_size, MPI_Datatype point_info_dt, MPI_Comm comm)
static struct yac_field_data * yac_dist_grid_get_field_data(struct yac_dist_grid *dist_grid, enum yac_location location)
static void get_pack_sizes(struct yac_dist_grid *dist_grid, enum yac_location location, uint64_t *pos, size_t count, int *pack_sizes, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
static void determine_dist_cell_ranks(struct proc_sphere_part_node *proc_sphere_part, struct yac_basic_grid_data *grid_data, MPI_Comm comm, int **dist_cell_ranks, int *dist_cell_rank_counts, size_t *dist_cell_rank_offsets, int max_num_vertices_per_cell)
static void yac_single_remote_point_pack(struct single_remote_point *point, void *buffer, int buffer_size, int *position, MPI_Datatype single_remote_point_dt, MPI_Comm comm)
static MPI_Datatype yac_get_single_remote_point_mpi_datatype(MPI_Comm comm)
static struct bnd_sphere_part_search * dist_grid_pair_get_cell_sphere_part(struct yac_dist_grid_pair *grid_pair, char const *grid_name)
static int get_max_num_vertices_per_cell(struct yac_basic_grid_data *grid_data, MPI_Comm comm)
static void pack_grid_data_edge_(struct yac_dist_grid *dist_grid, size_t idx, void *buffer, int buffer_size, int *position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm)
static void yac_dist_grid_free(struct yac_dist_grid grid)
static void lookup_single_remote_point_reorder_locally(struct yac_dist_grid *dist_grid, enum yac_location location, struct single_remote_point_reorder *ids, size_t *count, size_t *idx)
int const * const_int_pointer
struct bounding_circle const *const const_bounding_circle_pointer
size_t const *const const_size_t_pointer
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
size_t yac_field_data_get_masks_count(struct yac_field_data *field_data)
void yac_field_data_set_mask_data(struct yac_field_data *field_data, size_t mask_idx, int *mask_data)
size_t yac_field_data_get_coordinates_count(struct yac_field_data *field_data)
yac_const_coordinate_pointer yac_field_data_get_coordinates_data(struct yac_field_data *field_data, size_t coordinates_idx)
int const * yac_field_data_get_mask_data(struct yac_field_data *field_data, size_t mask_idx)
char const * yac_field_data_get_mask_name(struct yac_field_data *field_data, size_t mask_idx)
void yac_field_data_set_coordinates_data(struct yac_field_data *field_data, size_t coordinates_idx, yac_coordinate_pointer coordinates_data)
size_t yac_field_data_add_mask_nocpy(struct yac_field_data *field_data, int const *mask, char const *mask_name)
struct yac_field_data * yac_field_data_empty_new()
size_t yac_field_data_add_coordinates_nocpy(struct yac_field_data *field_data, yac_coordinate_pointer coordinates)
struct yac_field_data_set * yac_field_data_set_new(struct yac_field_data *cell_field_data, struct yac_field_data *vertex_field_data, struct yac_field_data *edge_field_data)
void yac_field_data_set_delete(struct yac_field_data_set *field_data_set)
struct yac_field_data * yac_field_data_set_get_field_data(struct yac_field_data_set *field_data_set, enum yac_location location)
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
static const struct sin_cos_angle SIN_COS_ZERO
static int compare_angles(struct sin_cos_angle a, struct sin_cos_angle b)
static void normalise_vector(double v[])
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
static struct sin_cos_angle half_angle(struct sin_cos_angle angle)
void yac_init_grid_cell(struct yac_grid_cell *cell)
void yac_free_grid_cell(struct yac_grid_cell *cell)
@ YAC_GREAT_CIRCLE_EDGE
great circle
void yac_proc_sphere_part_get_neigh_ranks(struct proc_sphere_part_node *node, uint64_t *leaf_sizes, uint64_t min_size, int *send_flags, int *recv_flags, int comm_rank, int comm_size)
void yac_proc_sphere_part_do_bnd_circle_search(struct proc_sphere_part_node *node, struct bounding_circle bnd_circle, int *ranks, int *rank_count)
void yac_proc_sphere_part_do_point_search(struct proc_sphere_part_node *node, yac_coordinate_pointer search_coords, size_t count, int *ranks)
void yac_proc_sphere_part_node_delete(struct proc_sphere_part_node *node)
void yac_proc_sphere_part_new(yac_coordinate_pointer vertex_coordinates[2], size_t *num_vertices, struct proc_sphere_part_node **proc_sphere_part, yac_int **global_vertex_ids_[2], int **vertex_ranks[2], MPI_Comm comm)
struct Xt_redist_ * Xt_redist
char const * yac_loc2str(enum yac_location location)
#define xrealloc(ptr, size)
#define xcalloc(nmemb, size)
void yac_remote_point_infos_unpack(void *buffer, int buffer_size, int *position, struct remote_point_infos *infos, MPI_Datatype point_info_dt, MPI_Comm comm)
int yac_remote_point_infos_get_pack_size(struct remote_point_infos const *infos, MPI_Datatype point_info_dt, MPI_Comm comm)
MPI_Datatype yac_get_remote_point_info_mpi_datatype(MPI_Comm comm)
void yac_remote_point_infos_pack(struct remote_point_infos const *infos, void *buffer, int buffer_size, int *position, MPI_Datatype point_info_dt, MPI_Comm comm)
void yac_point_sphere_part_search_NNN_ubound(struct point_sphere_part_search *search, size_t num_points, yac_coordinate_pointer coordinates_xyz, size_t n, struct sin_cos_angle *angles)
void yac_bnd_sphere_part_search_do_bnd_circle_search(struct bnd_sphere_part_search *search, struct bounding_circle *bnd_circles, size_t count, size_t **cells, size_t *num_cells_per_bnd_circle)
void yac_point_sphere_part_search_NNN_bnd_circle(struct point_sphere_part_search *search, size_t num_bnd_circles, struct bounding_circle *bnd_circles, size_t n, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t *num_local_point_ids)
struct bnd_sphere_part_search * yac_bnd_sphere_part_search_new(struct bounding_circle *circles, size_t num_circles)
void yac_delete_point_sphere_part_search(struct point_sphere_part_search *search)
struct point_sphere_part_search * yac_point_sphere_part_search_mask_new(size_t num_points, yac_const_coordinate_pointer coordinates_xyz, yac_int const *ids, int const *mask)
void yac_bnd_sphere_part_search_delete(struct bnd_sphere_part_search *search)
struct point_sphere_part_search * yac_point_sphere_part_search_new(size_t num_points, yac_const_coordinate_pointer coordinates_xyz, yac_int const *ids)
void yac_bnd_sphere_part_search_do_point_search(struct bnd_sphere_part_search *search, yac_coordinate_pointer coordinates_xyz, size_t count, size_t **cells, size_t *num_cells_per_coordinate)
void yac_point_sphere_part_search_bnd_circle(struct point_sphere_part_search *search, size_t num_bnd_circles, const_bounding_circle_pointer bnd_circles, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t *num_local_point_ids)
void yac_point_sphere_part_search_NNN(struct point_sphere_part_search *search, size_t num_points, double(*coordinates_xyz)[3], size_t n, double **cos_angles, size_t *cos_angles_array_size, double(**result_coordinates_xyz)[3], size_t *result_coordinates_xyz_array_size, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t *num_local_point_ids)
algorithm for searching cells and points on a grid
struct sin_cos_angle inc_angle
angle between the middle point and the boundary of the spherical cap
enum yac_edge_type edge_type
struct remote_point_infos owners
yac_int edge_to_vertex[2]
struct remote_point_infos owners
int * num_vertices_per_cell
struct missing_edge_neighbour::@12 cell
struct missing_edge_neighbour::@12 edge
struct point_id_xyz * points
Inner node of the process sphere partition tree.
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 * data
struct single_remote_point data
struct remote_point_info data
yac_coordinate_pointer * coordinates
size_t * masks_array_sizes
size_t * coordinates_array_sizes
yac_coordinate_pointer vertex_coordinates
size_t * cell_to_edge_offsets
yac_size_t_2_pointer edge_to_vertex
enum yac_edge_type * edge_type
int * num_vertices_per_cell
const const_yac_int_pointer ids[3]
struct point_sphere_part_search * vertex_sphere_part[2]
struct proc_sphere_part_node * proc_sphere_part
struct yac_dist_grid dist_grid[2]
struct bnd_sphere_part_search * cell_sphere_part[2]
size_t * sorted_reorder_idx[3]
struct yac_field_data_set * field_data
struct bounding_circle * cell_bnd_circles
struct remote_point_infos * owners[3]
enum yac_edge_type * edge_type
yac_coordinate_pointer vertex_coordinates
size_t * cell_to_edge_offsets
size_t * cell_to_vertex_offsets
yac_size_t_2_pointer edge_to_vertex
int * num_vertices_per_cell
enum yac_edge_type * edge_type
double(* coordinates_xyz)[3]
enum yac_location location
void yac_quicksort_index_yac_int_size_t(yac_int *a, size_t n, size_t *idx)
void yac_quicksort_index_int_size_t(int *a, size_t n, size_t *idx)
static void yac_remove_duplicates_size_t(size_t *array, size_t *n)
void yac_quicksort_index_size_t_size_t(size_t *a, size_t n, size_t *idx)
#define YAC_ASSERT_F(exp, format,...)
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)
MPI_Datatype yac_get_bounding_circle_mpi_datatype(MPI_Comm comm)
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)
double const (* yac_const_coordinate_pointer)[3]
size_t(* yac_size_t_2_pointer)[2]
double(* yac_coordinate_pointer)[3]
yac_xmap yac_xmap_from_point_infos(struct remote_point_infos *point_infos, size_t count, MPI_Comm comm)
void yac_xmap_delete(yac_xmap xmap)
Xt_redist yac_xmap_generate_redist(yac_xmap xmap, MPI_Datatype base_type)