27#define CHECK_LOCATION(caller) \
29 (location == YAC_LOC_CELL) || \
30 (location == YAC_LOC_CORNER) || \
31 (location == YAC_LOC_EDGE), \
32 "ERROR(%s): \"%d\" is not a invalid location", \
33 caller, (int)location)
149 char const * caller,
yac_int * ids,
size_t * idx,
size_t num_ids,
150 yac_int * ref_sorted_ids,
size_t * ref_sorted_reorder_idx,
151 size_t num_sorted_ids) {
153 size_t * reorder =
xmalloc(num_ids *
sizeof(*reorder));
154 for (
size_t i = 0; i < num_ids; ++i) reorder[i] = i;
158 for (
size_t i = 0, j = 0; i < num_ids; ++i) {
161 while ((j < num_sorted_ids) && (ref_sorted_ids[j] < curr_id)) ++j;
163 (j < num_sorted_ids) && (ref_sorted_ids[j] == curr_id),
164 "ERROR(%s): id %" XT_INT_FMT
" not found", caller, curr_id)
165 idx[reorder[i]] = ref_sorted_reorder_idx[j];
176 if (num_vertices == 0)
return SIZE_MAX;
181 size_t min_idx = vertices[0];
182 yac_int min_global_id = grid_vertex_ids[min_idx];
183 for (
int j = 1; j < num_vertices; ++j) {
184 size_t curr_vertex = vertices[j];
185 yac_int curr_global_id = grid_vertex_ids[curr_vertex];
186 if (min_global_id > curr_global_id) {
187 min_global_id = curr_global_id;
188 min_idx = curr_vertex;
197 struct yac_dist_grid * dist_grid,
int is_root,
int * vertex_owner_mask) {
200 int * cell_owner_mask =
xmalloc(num_cells *
sizeof(*cell_owner_mask));
205 for (
size_t i = 0; i < num_cells; ++i) {
208 (ref_vertex != SIZE_MAX)?(vertex_owner_mask[ref_vertex]):is_root;
211 return cell_owner_mask;
219 size_t * edge_vertices = &(dist_grid->
edge_to_vertex[edge_idx][0]);
221 return edge_vertices[
222 (vertex_ids[edge_vertices[0]] > vertex_ids[edge_vertices[1]])?1:0];
232 int * edge_owner_mask =
xmalloc(num_edges *
sizeof(*edge_owner_mask));
237 for (
size_t i = 0; i < num_edges; ++i)
241 return edge_owner_mask;
247 struct yac_dist_grid * dist_grid,
int comm_rank,
int * vertex_owner) {
251 int * vertex_owner_mask =
254 vertex_owner_mask[i] = vertex_owner_mask[i] == comm_rank;
268 MPI_Datatype id_pos_dt;
269 int array_of_blocklengths[] = {1,1};
270 const MPI_Aint array_of_displacements[] =
271 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
global_id) -
272 (MPI_Aint)(intptr_t)(
const void *)&dummy,
273 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
orig_pos) -
274 (MPI_Aint)(intptr_t)(
const void *)&dummy};
275 const MPI_Datatype array_of_types[] = {
yac_int_dt, MPI_UINT64_T};
277 MPI_Type_create_struct(
278 2, array_of_blocklengths, array_of_displacements,
279 array_of_types, &id_pos_dt), comm);
287 for (i = 0; i < n; ++i)
if (ids[i] >=
id)
break;
289 if (n != i) memmove(ids + i + 1, ids + i, (n - i) *
sizeof(*ids));
300 for (i = 0; i < n; ++i)
if (ranks[i] >= rank)
break;
304 if (ranks[i] == rank)
return;
305 else memmove(ranks + i + 1, ranks + i, ((
size_t)(n - i)) *
sizeof(*ranks));
312 const void * a,
const void * b) {
318 int ret = count_a - count_b;
319 for (
int i = 0; !ret && (i < count_a); ++i)
320 ret = (a_ids[i] > b_ids[i]) - (a_ids[i] < b_ids[i]);
325 const void * a,
const void * b) {
339 int * dist_cell_rank_counts,
size_t * dist_cell_rank_offsets,
340 int max_num_vertices_per_cell) {
346 int * ranks_buffer =
xmalloc((
size_t)comm_size *
sizeof(*ranks_buffer));
347 size_t dist_cell_ranks_array_size = num_cells;
348 int * dist_cell_ranks_ =
xmalloc(num_cells *
sizeof(*dist_cell_ranks_));
371 for (
size_t i = 0; i < num_cells; ++i) {
376 if ((core_cell_mask == NULL) || core_cell_mask[i]) {
384 size_t * curr_cell_to_vertex =
385 cell_to_vertex + cell_to_vertex_offsets[i];
386 size_t * curr_cell_to_edge =
387 cell_to_edge + cell_to_edge_offsets[i];
388 for (
int j = 0; j < num_vertices_per_cell[i]; ++j) {
390 vertex_coordinates + curr_cell_to_vertex[j];
391 for (
int k = 0; k < 3; ++k)
404 proc_sphere_part, bnd_circle, ranks_buffer, &rank_count);
417 offset + (
size_t)rank_count);
418 memcpy(dist_cell_ranks_ + offset, ranks_buffer,
419 (
size_t)rank_count *
sizeof(*ranks_buffer));
421 dist_cell_rank_counts[i] = rank_count;
422 dist_cell_rank_offsets[i] = offset;
423 offset += (size_t)rank_count;
427 dist_cell_rank_offsets[num_cells] = offset;
433 *dist_cell_ranks = dist_cell_ranks_;
439 MPI_Datatype coord_dt;
440 int array_of_blocklengths[] = {3};
441 const MPI_Aint array_of_displacements[] =
442 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
coord) -
443 (MPI_Aint)(intptr_t)(
const void *)&dummy};
444 const MPI_Datatype array_of_types[] = {MPI_DOUBLE};
446 MPI_Type_create_struct(1, array_of_blocklengths, array_of_displacements,
447 array_of_types, &coord_dt), comm);
454 MPI_Datatype global_id_dt;
455 int array_of_blocklengths[] = {1};
456 const MPI_Aint array_of_displacements[] =
457 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
global_id) -
458 (MPI_Aint)(intptr_t)(
const void *)&dummy};
459 const MPI_Datatype array_of_types[] = {
yac_int_dt};
461 MPI_Type_create_struct(1, array_of_blocklengths, array_of_displacements,
462 array_of_types, &global_id_dt), comm);
467 const void * a,
const void * b) {
474 const void * a,
const void * b) {
489 char const * routine =
"generate_vertex_ids";
500 int ids_available_local =
502 int ids_available_global;
504 &ids_available_local, &ids_available_global, 1,
505 MPI_INT, MPI_MAX, comm), comm);
510 ids_available_local || !ids_available_global,
511 "ERROR(%s): inconsistent global ids", routine)
515 if (ids_available_global)
return vertex_ranks;
520 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
522 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
525 sendcounts[vertex_ranks[i]]++;
528 1, sendcounts, recvcounts, sdispls, rdispls, comm);
531 size_t dist_vertex_count =
532 recvcounts[comm_size - 1] + rdispls[comm_size - 1];
535 xmalloc((orig_vertex_count + dist_vertex_count) *
536 sizeof(*id_reorder_coord_buffer));
538 id_reorder_coord_send_buffer = id_reorder_coord_buffer;
540 id_reorder_coord_recv_buffer =
541 id_reorder_coord_buffer + orig_vertex_count;
544 for (
size_t i = 0; i < orig_vertex_count; ++i) {
545 size_t pos = sdispls[vertex_ranks[i] + 1]++;
547 for (
int j = 0; j < 3; ++j)
548 id_reorder_coord_send_buffer[pos].
coord[j] =
552 MPI_Datatype id_reorder_coord_coord_dt =
557 id_reorder_coord_send_buffer, sendcounts, sdispls,
558 id_reorder_coord_recv_buffer, recvcounts, rdispls,
559 sizeof(*id_reorder_coord_send_buffer), id_reorder_coord_coord_dt, comm,
562 yac_mpi_call(MPI_Type_free(&id_reorder_coord_coord_dt), comm);
564 for (
size_t i = 0; i < dist_vertex_count; ++i)
569 id_reorder_coord_recv_buffer, dist_vertex_count,
572 size_t unique_count = dist_vertex_count > 0;
576 for (
size_t i = 0; i < dist_vertex_count; ++i) {
586 unique_count <= (
size_t)XT_INT_MAX,
587 "ERROR(%s): global_id out of bounds", routine)
595 MPI_SUM, comm), comm);
598 if (comm_rank == 0) id_offset = 0;
601 ((
size_t)id_offset + unique_count) <= (
size_t)XT_INT_MAX,
602 "ERROR(%s): global_id out of bounds", routine)
605 for (
size_t i = 0; i < dist_vertex_count; ++i)
606 id_reorder_coord_recv_buffer[i].
global_id += id_offset;
609 qsort(id_reorder_coord_recv_buffer, dist_vertex_count,
610 sizeof(*id_reorder_coord_recv_buffer),
613 MPI_Datatype id_reorder_coord_id_dt =
618 id_reorder_coord_recv_buffer, recvcounts, rdispls,
619 id_reorder_coord_send_buffer, sendcounts, sdispls,
620 sizeof(*id_reorder_coord_send_buffer), id_reorder_coord_id_dt, comm,
623 yac_mpi_call(MPI_Type_free(&id_reorder_coord_id_dt), comm);
631 vertex_ids[id_reorder_coord_send_buffer[i].
reorder_idx] =
632 id_reorder_coord_send_buffer[i].
global_id;
634 free(id_reorder_coord_buffer);
643 int max_num_vertices_per_cell, MPI_Comm comm) {
645 char const * routine =
"generate_ce_ids";
654 int comm_rank, comm_size;
660 int ids_available_local[2], ids_available_global[2];
661 ids_available_local[0] =
663 ids_available_local[1] =
665 yac_mpi_call(MPI_Allreduce(ids_available_local, ids_available_global, 2,
666 MPI_INT, MPI_MAX, comm), comm);
670 (ids_available_local[0] == ids_available_global[0]),
671 "ERROR(%s): inconsistent global ids", routine)
675 (ids_available_local[1] == ids_available_global[1]),
676 "ERROR(%s): inconsistent global ids", routine)
679 if (ids_available_global[0] && ids_available_global[1])
return;
683 (((ids_available_global[0])?0:(
num_cells)) +
684 ((ids_available_global[1])?0:(
num_edges))) *
685 sizeof(*rank_buffer));
686 int * cell_ranks = rank_buffer;
688 rank_buffer + ((ids_available_global[0])?0:(
num_cells));
690 size_t * size_t_buffer =
691 xmalloc((8 * (
size_t)comm_size + 1) *
sizeof(*size_t_buffer));
692 size_t * sendcounts = size_t_buffer + 0 * comm_size;
693 size_t * recvcounts = size_t_buffer + 2 * comm_size;
694 size_t * total_sendcounts = size_t_buffer + 4 * comm_size;
695 size_t * total_recvcounts = size_t_buffer + 5 * comm_size;
696 size_t * total_sdispls = size_t_buffer + 6 * comm_size;
697 size_t * total_rdispls = size_t_buffer + 7 * comm_size + 1;
698 memset(sendcounts, 0, 2 * (
size_t)comm_size *
sizeof(*sendcounts));
700 yac_int * cell_to_vertex_ids = NULL;
702 if (!ids_available_global[0]) {
710 sizeof(*cell_to_vertex_ids));
715 yac_int * curr_cell_to_vertex_ids =
716 cell_to_vertex_ids + i * max_num_vertices_per_cell;
719 if (curr_num_vertices > 0) {
720 size_t * curr_cell_vertices =
722 size_t min_vertex = curr_cell_vertices[0];
723 curr_cell_to_vertex_ids[0] =
vertex_ids[min_vertex];
724 for (
int j = 1; j < curr_num_vertices; ++j) {
725 size_t curr_vertex_idx = curr_cell_vertices[j];
728 if (curr_cell_to_vertex_ids[0] == curr_vertex_id)
729 min_vertex = curr_vertex_idx;
731 cell_rank = vertex_ranks[min_vertex];
735 for (
int j = curr_num_vertices; j < max_num_vertices_per_cell; ++j)
736 curr_cell_to_vertex_ids[j] = XT_INT_MAX;
738 sendcounts[2 * ((cell_ranks[i] = cell_rank)) + 0]++;
742 yac_int * edge_to_vertex_ids = NULL;
744 if (!ids_available_global[1]) {
753 yac_int * curr_edge_vertex_ids = edge_to_vertex_ids + 2 * i;
754 curr_edge_vertex_ids[0] =
vertex_ids[curr_edge_to_vertex[0]];
755 curr_edge_vertex_ids[1] =
vertex_ids[curr_edge_to_vertex[1]];
757 if (curr_edge_vertex_ids[0] > curr_edge_vertex_ids[1]) {
758 yac_int temp = curr_edge_vertex_ids[0];
759 curr_edge_vertex_ids[0] = curr_edge_vertex_ids[1];
760 curr_edge_vertex_ids[1] = temp;
762 2 * ((edge_ranks[i] = vertex_ranks[curr_edge_to_vertex[1]])) + 1]++;
765 2 * ((edge_ranks[i] = vertex_ranks[curr_edge_to_vertex[0]])) + 1]++;
774 total_sdispls[0] = 0;
775 size_t recv_counts[2] = {0,0};
776 size_t saccu = 0, raccu = 0;
777 for (
int i = 0; i < comm_size; ++i) {
778 total_sdispls[i+1] = saccu;
779 total_rdispls[i] = raccu;
780 recv_counts[0] += recvcounts[2 * i + 0];
781 recv_counts[1] += recvcounts[2 * i + 1];
782 total_sendcounts[i] = sendcounts[2 * i + 0] *
783 (size_t)max_num_vertices_per_cell +
784 sendcounts[2 * i + 1] * 2;
785 total_recvcounts[i] = recvcounts[2 * i + 0] *
786 (size_t)max_num_vertices_per_cell +
787 recvcounts[2 * i + 1] * 2;
788 saccu += total_sendcounts[i];
789 raccu += total_recvcounts[i];
791 size_t local_data_count = total_sendcounts[comm_size - 1] +
792 total_sdispls[comm_size];
793 size_t recv_count = total_recvcounts[comm_size - 1] +
794 total_rdispls[comm_size - 1];
797 xcalloc((local_data_count + recv_count),
sizeof(*yac_int_buffer));
798 yac_int * send_buffer = yac_int_buffer;
799 yac_int * recv_buffer = yac_int_buffer + local_data_count;
802 if (!ids_available_global[0])
804 for (
int j = 0; j < max_num_vertices_per_cell; ++j)
805 send_buffer[total_sdispls[cell_ranks[i] + 1]++] =
806 cell_to_vertex_ids[i * max_num_vertices_per_cell + j];
807 if (!ids_available_global[1])
809 for (
int j = 0; j < 2; ++j)
810 send_buffer[total_sdispls[edge_ranks[i] + 1]++] =
811 edge_to_vertex_ids[2 * i + j];
813 free(edge_to_vertex_ids);
814 free(cell_to_vertex_ids);
817 yac_alltoallv_yac_int_p2p(
818 send_buffer, total_sendcounts, total_sdispls,
819 recv_buffer, total_recvcounts, total_rdispls, comm, routine, __LINE__);
822 xmalloc((recv_counts[0] + recv_counts[1]) *
sizeof(*n_ids_reorder_buffer));
824 {n_ids_reorder_buffer, n_ids_reorder_buffer + recv_counts[0]};
827 int index_counts[2] = {max_num_vertices_per_cell, 2};
831 for (
int i = 0; i < comm_size; ++i) {
832 for (
int j = 0; j < 2; ++j) {
833 size_t curr_count = recvcounts[2 * i + j];
834 for (
size_t k = 0; k < curr_count;
839 offset += index_counts[j];
844 for (
int i = 0; i < 2; ++i) {
846 if (ids_available_global[i])
continue;
851 size_t unique_count = recv_counts[i] > 0;
855 for (
size_t j = 0; j < recv_counts[i]; ++j, ++curr) {
864 unique_count <= (
size_t)XT_INT_MAX,
865 "ERROR(%s): global_id out of bounds", routine)
872 MPI_SUM, comm), comm);
873 if (comm_rank == 0) id_offset = 0;
876 ((
size_t)id_offset + unique_count) <= (
size_t)XT_INT_MAX,
877 "ERROR(%s): global_id out of bounds", routine)
880 for (
size_t j = 0; j < recv_counts[i]; ++j)
883 free(yac_int_buffer);
885 qsort(n_ids_reorder_buffer, recv_counts[0] + recv_counts[1],
889 xmalloc((recv_counts[0] + recv_counts[1] +
890 ((ids_available_global[0])?0:(num_cells)) +
891 ((ids_available_global[1])?0:(num_edges))) *
892 sizeof(*global_ids_buffer));
893 yac_int * send_global_ids = global_ids_buffer;
895 global_ids_buffer + recv_counts[0] + recv_counts[1];
897 for (
size_t i = 0; i < recv_counts[0] + recv_counts[1]; ++i)
898 send_global_ids[i] = n_ids_reorder_buffer[i].
global_id;
899 free(n_ids_reorder_buffer);
902 saccu = 0, raccu = 0;
903 for (
int i = 0; i < comm_size; ++i) {
904 total_sdispls[i] = saccu;
905 total_rdispls[i] = raccu;
907 ((total_sendcounts[i] = recvcounts[2 * i + 0] + recvcounts[2 * i + 1]));
909 ((total_recvcounts[i] = sendcounts[2 * i + 0] + sendcounts[2 * i + 1]));
913 yac_alltoallv_yac_int_p2p(
914 send_global_ids, total_sendcounts, total_sdispls,
915 recv_global_ids, total_recvcounts, total_rdispls, comm,
918 if ((!ids_available_global[0]) && (num_cells > 0))
921 if ((!ids_available_global[1]) && (num_edges > 0))
926 if (!ids_available_global[0])
927 for (
size_t i = 0; i < num_cells; ++i)
929 recv_global_ids[total_rdispls[cell_ranks[i]]++];
930 if (!ids_available_global[1])
931 for (
size_t i = 0; i < num_edges; ++i)
933 recv_global_ids[total_rdispls[edge_ranks[i]]++];
937 free(global_ids_buffer);
981 "ERROR: inconsistent edge core mask for grid \"%s\" "
982 "(edge %" XT_INT_FMT
" is valid but one of its vertices is not)",
1017 for (
size_t j = 0; j <
num_cells; ++j) {
1024 for (
int k = 0; k < curr_num_edges; ++k) {
1027 "ERROR: inconsistent cell core mask for grid \"%s\" "
1028 "(cell %" XT_INT_FMT
" is valid but edge %" XT_INT_FMT
" is not)",
1039 for (
size_t j = 0; j <
num_cells; ++j) {
1043 for (
int k = 0; k < curr_num_edges; ++k)
1055 int max_num_vertices_per_cell, MPI_Comm comm) {
1058 int * vertex_ranks =
1066 *vertex_ranks_ = vertex_ranks;
1078 for (
size_t i = 0; i <
num_edges; ++i) {
1079 edge_to_cell[i][0] = SIZE_MAX;
1080 edge_to_cell[i][1] = SIZE_MAX;
1083 for (
size_t i = 0, offset = 0; i <
num_cells; ++i) {
1085 size_t curr_num_edges = num_edges_per_cell[i];
1087 offset += curr_num_edges;
1091 for (
size_t j = 0; j < curr_num_edges; ++j) {
1093 size_t curr_edge = curr_cell_to_edge[j];
1094 size_t * curr_edge_to_cell = edge_to_cell[curr_edge];
1095 curr_edge_to_cell += *curr_edge_to_cell != SIZE_MAX;
1097 *curr_edge_to_cell == SIZE_MAX,
1098 "ERROR(generate_edge_to_cell): "
1099 "more than two cells point to a single edge "
1100 "(does the grid contain degenrated cells (less than 3 corners) "
1101 "or duplicated cells; "
1102 "these can be masked out using the core mask)\n"
1103 "(num_cells: %zu cell_idx: %zu: num_cell_edge %zu)",
1105 *curr_edge_to_cell = i;
1110 return edge_to_cell;
1119 size_t * curr_edge_to_vertex = edge_to_vertex[edge_id];
1120 double * vertices[2] =
1121 {vertex_coordinates[curr_edge_to_vertex[0]],
1122 vertex_coordinates[curr_edge_to_vertex[1]]};
1124 bnd_circle.
base_vector[0] = vertices[0][0] + vertices[1][0];
1125 bnd_circle.
base_vector[1] = vertices[0][1] + vertices[1][1];
1126 bnd_circle.
base_vector[2] = vertices[0][2] + vertices[1][2];
1130 bnd_circle.
sq_crd = DBL_MAX;
1138 size_t * dist_cell_rank_offsets,
size_t * dist_edge_rank_offsets,
1139 int * num_cell_ranks,
int * num_edge_ranks,
1140 int ** rank_buffer,
size_t * rank_buffer_array_size) {
1150 size_t dist_edge_rank_offset = dist_cell_rank_offsets[
num_cells];
1160 for (
size_t i = 0; i <
num_edges; ++i) {
1162 int edge_rank_count = 0;
1167 int cell_rank_counts[2] = {0, 0};
1168 size_t * curr_edge_cells = edge_to_cell[i];
1170 for (
int j = 0; j < 2; ++j)
1171 if (curr_edge_cells[j] != SIZE_MAX)
1173 ((cell_rank_counts[j] = num_cell_ranks[curr_edge_cells[j]]));
1176 if (edge_rank_count > 0) {
1179 *rank_buffer, *rank_buffer_array_size,
1180 dist_edge_rank_offset + edge_rank_count);
1182 int * curr_edge_ranks = *rank_buffer + dist_edge_rank_offset;
1185 edge_rank_count = 0;
1186 for (
int j = 0; j < 2; ++j) {
1187 if (cell_rank_counts[j] > 0) {
1189 *rank_buffer + dist_cell_rank_offsets[curr_edge_cells[j]];
1190 for (
int k = 0; k < cell_rank_counts[j]; ++k)
1192 curr_edge_ranks, &edge_rank_count, cell_ranks[k]);
1199 *rank_buffer, *rank_buffer_array_size,
1200 dist_edge_rank_offset + comm_size);
1202 int * curr_edge_ranks = *rank_buffer + dist_edge_rank_offset;
1210 curr_edge_ranks, &edge_rank_count);
1214 dist_edge_rank_offset += (size_t)edge_rank_count;
1215 num_edge_ranks[i] = edge_rank_count;
1217 dist_edge_rank_offsets[i+1] = dist_edge_rank_offset;
1225 size_t * vertex_to_edge,
int * num_edges_per_vertex) {
1228 num_edges_per_vertex, 0,
num_vertices *
sizeof(*num_edges_per_vertex));
1230 for (
size_t i = 0; i <
num_edges; ++i) {
1235 size_t * vertex_edges_offsets =
1238 vertex_edges_offsets[0] = 0;
1239 for (
size_t i = 0, offset = 0; i <
num_vertices; ++i) {
1240 vertex_edges_offsets[i + 1] = offset;
1241 offset += (size_t)(num_edges_per_vertex[i]);
1244 for (
size_t i = 0; i <
num_edges; ++i) {
1245 for (
int j = 0; j < 2; ++j) {
1247 vertex_to_edge[vertex_edges_offsets[curr_vertex+1]] = i;
1248 vertex_edges_offsets[curr_vertex+1]++;
1252 free(vertex_edges_offsets);
1257 size_t * dist_edge_rank_offsets,
int * num_edge_ranks,
int * num_vertex_ranks,
1258 int ** rank_buffer,
size_t * rank_buffer_array_size) {
1267 size_t vertex_rank_offset = dist_edge_rank_offsets[
num_edges];
1271 size_t * vertex_to_edge =
xmalloc(2 *
num_edges *
sizeof(*vertex_to_edge));
1272 int * num_edges_per_vertex =
1276 vertex_to_edge, num_edges_per_vertex);
1277 size_t * curr_edges = vertex_to_edge;
1282 int vertex_rank_count = 0;
1283 int curr_num_edges = num_edges_per_vertex[i];
1288 for (
int j = 0; j < curr_num_edges; ++j)
1289 vertex_rank_count += num_edge_ranks[curr_edges[j]];
1292 if (vertex_rank_count > 0) {
1295 *rank_buffer, *rank_buffer_array_size,
1296 vertex_rank_offset + vertex_rank_count);
1298 int * curr_vertex_ranks = *rank_buffer + vertex_rank_offset;
1301 vertex_rank_count = 0;
1302 for (
int j = 0; j < curr_num_edges; ++j) {
1303 size_t curr_edge = curr_edges[j];
1304 int curr_num_edge_ranks = num_edge_ranks[curr_edge];
1305 int * curr_edge_ranks =
1306 *rank_buffer + dist_edge_rank_offsets[curr_edge];
1307 for (
int k = 0; k < curr_num_edge_ranks; ++k)
1309 curr_vertex_ranks, &vertex_rank_count, curr_edge_ranks[k]);
1315 *rank_buffer, *rank_buffer_array_size, vertex_rank_offset + 1);
1317 int * curr_vertex_ranks = *rank_buffer + vertex_rank_offset;
1319 *curr_vertex_ranks = vertex_ranks[i];
1320 vertex_rank_count = 1;
1324 vertex_rank_offset += (size_t)vertex_rank_count;
1325 num_vertex_ranks[i] = vertex_rank_count;
1326 curr_edges += curr_num_edges;
1329 free(num_edges_per_vertex);
1330 free(vertex_to_edge);
1334 const void * a,
const void * b) {
1348 int max_num_vertices_per_cell, MPI_Comm comm,
1350 size_t * dist_count) {
1352 char const * routine =
"generate_dist_remote_points";
1361 int * num_ranks_buffer =
1364 int * num_cell_ranks = num_ranks_buffer;
1365 int * num_vertex_ranks = num_ranks_buffer +
num_cells;
1367 size_t * dist_rank_offsets =
1369 size_t * dist_cell_rank_offsets = dist_rank_offsets;
1370 size_t * dist_edge_rank_offsets = dist_rank_offsets +
num_cells;
1380 proc_sphere_part, grid_data, comm,
1381 &rank_buffer, num_cell_ranks, dist_cell_rank_offsets, max_num_vertices_per_cell);
1383 size_t rank_buffer_array_size = dist_cell_rank_offsets[
num_cells];
1391 proc_sphere_part, grid, comm, dist_cell_rank_offsets, dist_edge_rank_offsets,
1392 num_cell_ranks, num_edge_ranks, &rank_buffer, &rank_buffer_array_size);
1400 vertex_ranks, grid, comm, dist_edge_rank_offsets,
1401 num_edge_ranks, num_vertex_ranks, &rank_buffer, &rank_buffer_array_size);
1403 int * dist_cell_ranks = rank_buffer;
1404 int * dist_vertex_ranks = rank_buffer + dist_edge_rank_offsets[
num_edges];
1405 int * dist_edge_ranks = rank_buffer + dist_cell_rank_offsets[
num_cells];
1407 free(dist_rank_offsets);
1417 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1419 3, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1420 size_t * size_t_buffer =
1421 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
1422 size_t * total_sendcounts = size_t_buffer + 0 * comm_size;
1423 size_t * total_recvcounts = size_t_buffer + 1 * comm_size;
1424 size_t * total_sdispls = size_t_buffer + 2 * comm_size;
1425 size_t * total_rdispls = size_t_buffer + 3 * comm_size;
1433 {{.count = num_cells,
1434 .ranks = dist_cell_ranks,
1435 .num_ranks = num_cell_ranks,
1437 {.count = num_vertices,
1438 .ranks = dist_vertex_ranks,
1439 .num_ranks = num_vertex_ranks,
1441 {.count = num_edges,
1442 .ranks = dist_edge_ranks,
1443 .num_ranks = num_edge_ranks,
1448 for (
int location = 0; location < 3; ++location) {
1449 size_t count = cve_data[location].count;
1450 int * ranks = cve_data[location].ranks;
1451 int * num_ranks = cve_data[location].num_ranks;
1452 for (
size_t i = 0, k = 0; i < count; ++i) {
1453 int curr_num_ranks = num_ranks[i];
1454 for (
int j = 0; j < curr_num_ranks; ++j, ++k)
1455 sendcounts[3 * ranks[k] + location]++;
1460 3, sendcounts, recvcounts, sdispls, rdispls, comm);
1462 size_t receive_counts[3] = {0,0,0};
1463 size_t saccu = 0, raccu = 0;
1464 for (
int i = 0; i < comm_size; ++i) {
1465 total_sdispls[i] = saccu;
1466 total_rdispls[i] = raccu;
1467 total_sendcounts[i] = 0;
1468 total_recvcounts[i] = 0;
1469 for (
int location = 0; location < 3; ++location) {
1470 total_sendcounts[i] += sendcounts[3 * i + location];
1471 total_recvcounts[i] += recvcounts[3 * i + location];
1472 receive_counts[location] += recvcounts[3 * i + location];
1474 saccu += total_sendcounts[i];
1475 raccu += total_recvcounts[i];
1477 size_t local_data_count = total_sendcounts[comm_size - 1] +
1478 total_sdispls[comm_size - 1];
1479 size_t recv_count = total_recvcounts[comm_size - 1] +
1480 total_rdispls[comm_size - 1];
1482 struct id_pos * id_pos_buffer =
1483 xcalloc((local_data_count + recv_count),
sizeof(*id_pos_buffer));
1484 struct id_pos * id_pos_send_buffer = id_pos_buffer;
1485 struct id_pos * id_pos_recv_buffer =
1486 id_pos_buffer + local_data_count;
1489 for (
int location = 0; location < 3; ++location) {
1490 size_t count = cve_data[location].count;
1491 int * ranks = cve_data[location].ranks;
1492 int * num_ranks = cve_data[location].num_ranks;
1493 yac_int * ids = cve_data[location].ids;
1494 for (
size_t i = 0, k = 0; i < count; ++i) {
1495 int curr_num_ranks = num_ranks[i];
1497 for (
int j = 0; j < curr_num_ranks; ++j, ++k) {
1498 size_t pos = sdispls[3 * ranks[k] + location + 1]++;
1500 id_pos_send_buffer[pos].
orig_pos = i;
1504 free(num_ranks_buffer);
1511 id_pos_send_buffer, total_sendcounts, total_sdispls,
1512 id_pos_recv_buffer, total_recvcounts, total_rdispls,
1513 sizeof(*id_pos_send_buffer), id_pos_dt, comm,
1518 size_t dist_owner_counts[3] = {0, 0, 0};
1519 for (
int i = 0; i < comm_size; ++i)
1520 for (
int location = 0; location < 3; ++location)
1521 dist_owner_counts[location] += recvcounts[3 * i + location];
1522 size_t max_dist_owner_count =
1523 MAX(
MAX(dist_owner_counts[0], dist_owner_counts[1]), dist_owner_counts[2]);
1525 xcalloc(max_dist_owner_count,
sizeof(*temp_buffer));
1530 for (
int location = 0; location < 3; ++location) {
1533 for (
int i = 0; i < comm_size; ++i) {
1534 size_t curr_recvcount = recvcounts[3 * i + location];
1535 struct id_pos * curr_id_pos =
1536 id_pos_recv_buffer + rdispls[3 * i + location];
1537 for (
size_t k = 0; k < curr_recvcount; ++k, ++count) {
1545 qsort(temp_buffer, count,
sizeof(*temp_buffer),
1548 unique_ids =
xrealloc(unique_ids, count *
sizeof(*unique_ids));
1549 size_t num_unique_ids = 0;
1553 for (
size_t i = 0; i < count; ++i) {
1556 if (curr_id != prev_id) {
1558 unique_ids[num_unique_ids].
global_id = curr_id;
1559 unique_ids[num_unique_ids].
data.
count = 1;
1562 unique_ids[num_unique_ids-1].
data.
count++;
1567 ((dist_point_infos[location] =
1568 xmalloc(num_unique_ids *
sizeof(*(dist_point_infos[location])))));
1570 ((dist_global_ids[location] =
1571 xmalloc(num_unique_ids *
sizeof(*(dist_global_ids[location])))));
1572 dist_count[location] = num_unique_ids;
1577 for (
size_t i = 0, l = 0; i < num_unique_ids; ++i) {
1578 global_ids[i] = unique_ids[i].
global_id;
1579 int curr_count = unique_ids[i].
data.
count;
1580 point_infos[i].
count = curr_count;
1581 if (curr_count == 1) {
1587 (
size_t)curr_count *
1589 for (
int k = 0; k < curr_count; ++k, ++l) {
1597 free(id_pos_buffer);
1599 free(size_t_buffer);
1605 yac_int ** sorted_global_ids,
size_t ** reorder_idx) {
1607 *sorted_global_ids =
xmalloc(
count *
sizeof(**sorted_global_ids));
1608 memcpy(*sorted_global_ids, global_ids,
count *
sizeof(**sorted_global_ids));
1610 for (
size_t i = 0; i <
count; ++i) (*reorder_idx)[i] = i;
1619 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1621 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1623 for (
size_t i = 0; i <
count; ++i) {
1625 (point_infos[i].
count > 1)?
1626 (point_infos[i].data.
multi):
1628 sendcounts[curr_info->
rank]++;
1632 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1633 size_t num_src_msg = 0, num_dst_msg = 0;
1634 for (
int i = 0; i < comm_size; ++i) {
1635 num_src_msg += (recvcounts[i] > 0);
1636 num_dst_msg += (sendcounts[i] > 0);
1640 rdispls[comm_size-1] + recvcounts[comm_size-1];
1643 xmalloc((recv_count + 2 * count) *
sizeof(*pos_buffer));
1644 int * src_pos_buffer = pos_buffer;
1645 int * dst_pos_buffer = pos_buffer + recv_count;
1646 int * send_pos_buffer = pos_buffer + recv_count + count;
1649 for (
size_t i = 0; i < count; ++i) {
1651 (point_infos[i].
count > 1)?
1652 (point_infos[i].data.
multi):
1654 size_t pos = sdispls[curr_info->
rank+1]++;
1655 dst_pos_buffer[pos] = i;
1656 send_pos_buffer[pos] = (int)(curr_info->
orig_pos);
1660 yac_alltoallv_int_p2p(
1661 send_pos_buffer, sendcounts, sdispls,
1662 src_pos_buffer, recvcounts, rdispls, comm,
1663 "generate_xmap_data", __LINE__);
1665 struct Xt_com_pos * com_pos =
1666 xmalloc(((
size_t)num_src_msg + (
size_t)num_dst_msg) *
sizeof(*com_pos));
1667 struct Xt_com_pos * src_com = com_pos;
1668 struct Xt_com_pos * dst_com = com_pos + num_src_msg;
1673 for (
int i = 0; i < comm_size; ++i) {
1674 if (recvcounts[i] > 0) {
1675 src_com[num_src_msg].transfer_pos = src_pos_buffer;
1676 src_com[num_src_msg].num_transfer_pos = recvcounts[i];
1677 src_com[num_src_msg].rank = i;
1678 src_pos_buffer += recvcounts[i];
1681 if (sendcounts[i] > 0) {
1682 dst_com[num_dst_msg].transfer_pos = dst_pos_buffer;
1683 dst_com[num_dst_msg].num_transfer_pos = sendcounts[i];
1684 dst_com[num_dst_msg].rank = i;
1685 dst_pos_buffer += sendcounts[i];
1692 xt_xmap_intersection_pos_new(
1693 num_src_msg, src_com, num_dst_msg, dst_com, comm);
1702 const void * a,
const void * b) {
1711 const void * a,
const void * b) {
1721 MPI_Datatype coord_dt;
1722 yac_mpi_call(MPI_Type_contiguous(3, MPI_DOUBLE, &coord_dt), comm);
1729 Xt_redist redist_mask, Xt_redist redist_coords, MPI_Comm comm) {
1733 uint64_t counts[2], max_counts[2];
1734 if (orig_field_data != NULL) {
1743 counts, max_counts, 2, MPI_UINT64_T, MPI_MAX, comm), comm);
1745 (orig_field_data == NULL) ||
1746 ((counts[0] == max_counts[0]) && (counts[1] == max_counts[1])),
1747 "ERROR(field_data_init): inconsistent number of masks or coordinates")
1749 int * data_available_flag =
1750 xcalloc(2 * max_counts[0] + max_counts[1],
sizeof(*data_available_flag));
1752 for (
size_t i = 0; i < counts[0]; ++i) {
1753 data_available_flag[i] =
1755 data_available_flag[i + counts[0]] =
1759 for (
size_t i = 0; i < counts[1]; ++i)
1760 data_available_flag[i + 2 * counts[0]] =
1765 MPI_IN_PLACE, data_available_flag,
1766 (
int)(2 * max_counts[0] + max_counts[1]), MPI_INT, MPI_MAX, comm), comm);
1768 for (
size_t i = 0; i < counts[0]; ++i) {
1770 data_available_flag[i] ==
1772 "ERROR(field_data_init): inconsistent availability of masks")
1777 data_available_flag[i + counts[0]] ==
1779 "ERROR(field_data_init): inconsistent mask names")
1782 for (
size_t i = 0; i < counts[1]; ++i)
1784 data_available_flag[i + 2 * counts[0]] ==
1786 "ERROR(field_data_init): inconsistent availability of coordinates")
1788 for (uint64_t i = 0; i < max_counts[0]; ++i) {
1789 int * dist_mask = NULL;
1790 if (data_available_flag[i]) {
1791 dist_mask =
xmalloc(dist_size *
sizeof(*dist_mask));
1792 int const * orig_mask =
1793 (orig_field_data != NULL)?
1795 xt_redist_s_exchange1(redist_mask, orig_mask, dist_mask);
1798 int mask_name_len = data_available_flag[i + max_counts[0]];
1799 char * mask_name = NULL;
1800 if (mask_name_len > 0) {
1801 mask_name =
xmalloc((
size_t)mask_name_len *
sizeof(*mask_name));
1802 if ((orig_field_data != NULL) &&
1806 (
size_t)mask_name_len);
1808 memset(mask_name, 0, (
size_t)mask_name_len *
sizeof(*mask_name));
1811 MPI_IN_PLACE, mask_name, mask_name_len, MPI_CHAR, MPI_MAX, comm),
1814 (orig_field_data == NULL) ||
1818 (
size_t)mask_name_len *
sizeof(*mask_name)),
1819 "ERROR(field_data_init): inconsistent mask names")
1824 for (uint64_t i = 0; i < max_counts[1]; ++i) {
1826 if (data_available_flag[i + 2 * max_counts[0]]) {
1827 dist_coordinates =
xmalloc(dist_size *
sizeof(*dist_coordinates));
1829 (orig_field_data != NULL)?
1831 xt_redist_s_exchange1(redist_coords, orig_coordinates, dist_coordinates);
1836 free(data_available_flag);
1838 return dist_field_data;
1844 MPI_Comm comm, MPI_Datatype dt_coord,
int * vertex_ranks,
1854 Xt_redist redist_vertex_coords = xt_redist_p2p_new(xmap, dt_coord);
1855 Xt_redist redist_vertex_int = xt_redist_p2p_new(xmap, MPI_INT);
1856 xt_xmap_delete(xmap);
1861 xt_redist_s_exchange1(
1866 xt_redist_s_exchange1(redist_vertex_int, vertex_ranks, vertex_owner);
1872 redist_vertex_int, redist_vertex_coords, comm);
1874 xt_redist_delete(redist_vertex_int);
1875 xt_redist_delete(redist_vertex_coords);
1877 *vertex_coordinates_ = vertex_coordinates;
1878 *vertex_owner_ = vertex_owner;
1879 *vertex_field_data_ = vertex_field_data;
1885 MPI_Datatype dt_coord,
size_t num_vertices,
yac_int * sorted_vertex_ids,
1886 size_t * sorted_vertex_reorder_idx,
1896 MPI_Datatype dt_2yac_int;
1899 Xt_redist redist_edge_int = xt_redist_p2p_new(xmap, MPI_INT);
1900 Xt_redist redist_edge_coords = xt_redist_p2p_new(xmap, dt_coord);
1901 Xt_redist redist_edge_2yac_int = xt_redist_p2p_new(xmap, dt_2yac_int);
1903 xt_xmap_delete(xmap);
1907 int * temp_edge_type_src, * temp_edge_type_dst;
1908 if (
sizeof(*
edge_type) ==
sizeof(
int)) {
1909 temp_edge_type_src = (
int*)(grid_data->
edge_type);
1912 temp_edge_type_src =
1914 for (
size_t i = 0; i < grid_data->
num_edges; ++i)
1915 temp_edge_type_src[i] = (
int)(grid_data->
edge_type[i]);
1918 temp_edge_type_dst[i] = (
int)(
edge_type[i]);
1921 xt_redist_s_exchange1(
1922 redist_edge_int, temp_edge_type_src, temp_edge_type_dst);
1924 if (
sizeof(*
edge_type) !=
sizeof(
int)) {
1929 free(temp_edge_type_src);
1930 free(temp_edge_type_dst);
1940 yac_int * grid_edge_vertex_ids = vertex_id_buffer;
1943 size_t * grid_edge_to_vertex = &(grid_data->
edge_to_vertex[0][0]);
1945 for (
size_t i = 0; i < 2 * grid_data->
num_edges; ++i)
1946 grid_edge_vertex_ids[i] =
1947 grid_data->
vertex_ids[grid_edge_to_vertex[i]];
1949 xt_redist_s_exchange1(
1950 redist_edge_2yac_int, grid_edge_vertex_ids, edge_vertex_ids);
1953 "redistribute_edge_data", edge_vertex_ids,
1955 sorted_vertex_ids, sorted_vertex_reorder_idx,
num_vertices);
1957 free(vertex_id_buffer);
1964 redist_edge_int, redist_edge_coords, comm);
1966 xt_redist_delete(redist_edge_2yac_int);
1967 xt_redist_delete(redist_edge_coords);
1968 xt_redist_delete(redist_edge_int);
1970 *edge_to_vertex_ = edge_to_vertex;
1971 *edge_type_ = edge_type;
1972 *edge_field_data_ = edge_field_data;
1978 MPI_Datatype dt_coord,
1979 size_t num_edges,
yac_int * sorted_edge_ids,
1980 size_t * sorted_edge_reorder_idx,
1981 size_t num_vertices,
yac_int * sorted_vertex_ids,
1982 size_t * sorted_vertex_reorder_idx,
int max_num_vertices_per_cell,
1983 size_t ** cell_to_vertex_,
size_t ** cell_to_edge_,
1984 int ** num_vertices_per_cell_,
struct yac_field_data ** cell_field_data_) {
1992 MPI_Datatype dt_yac_ints;
1994 MPI_Type_contiguous(
1995 max_num_vertices_per_cell,
yac_int_dt, &dt_yac_ints), comm);
1997 Xt_redist redist_cell_int = xt_redist_p2p_new(xmap, MPI_INT);
1998 Xt_redist redist_cell_yac_ints = xt_redist_p2p_new(xmap, dt_yac_ints);
1999 Xt_redist redist_cell_coords = xt_redist_p2p_new(xmap, dt_coord);
2001 xt_xmap_delete(xmap);
2009 (
size_t)max_num_vertices_per_cell *
2012 id_buffer + (size_t)max_num_vertices_per_cell *
num_cells;
2013 size_t total_num_ids = 0;
2015 size_t grid_num_cells = grid_data->
num_cells;
2021 yac_int * sorted_ve_ids = sorted_vertex_ids;
2022 size_t * sorted_ve_reorder_idx = sorted_vertex_reorder_idx;
2026 for (
int location = 0; location < 2; ++location) {
2029 for (
size_t i = 0, k = 0; i < grid_num_cells; ++i) {
2030 int curr_num_ve_per_cell = grid_num_ve_per_cell[i];
2031 size_t * curr_cell_to_ve = grid_cell_to_ve + grid_cell_to_ve_offests[i];
2032 for (
int j = 0; j < curr_num_ve_per_cell; ++j, ++k)
2033 grid_id_buffer[k] = grid_ids[curr_cell_to_ve[j]];
2034 for (
int j = curr_num_ve_per_cell; j < max_num_vertices_per_cell; ++j, ++k)
2035 grid_id_buffer[k] = XT_INT_MAX;
2039 xt_redist_s_exchange1(
2040 redist_cell_yac_ints, grid_id_buffer, id_buffer);
2046 for (
size_t i = 0; i <
num_cells; ++i) {
2049 id_buffer + i * (size_t)max_num_vertices_per_cell;
2050 for (vertex_count = 0; vertex_count < max_num_vertices_per_cell;
2052 if (
vertex_ids[vertex_count] == XT_INT_MAX)
break;
2053 compact_flag |= vertex_count != max_num_vertices_per_cell;
2055 total_num_ids += (size_t)vertex_count;
2061 for (
size_t i = 0, j = 0; j < total_num_ids; ++i) {
2062 yac_int curr_id = id_buffer[i];
2063 if (curr_id != XT_INT_MAX) {
2064 id_buffer[j] = curr_id;
2071 size_t * cell_to_ve =
2072 ((*cell_to_ve_ =
xmalloc(total_num_ids *
sizeof(*cell_to_ve))));
2074 "redistribute_cell_data", id_buffer, cell_to_ve, total_num_ids,
2075 sorted_ve_ids, sorted_ve_reorder_idx, num_ve);
2082 sorted_ve_ids = sorted_edge_ids;
2083 sorted_ve_reorder_idx = sorted_edge_reorder_idx;
2094 redist_cell_int, redist_cell_coords, comm);
2096 xt_redist_delete(redist_cell_coords);
2097 xt_redist_delete(redist_cell_yac_ints);
2098 xt_redist_delete(redist_cell_int);
2100 *cell_to_vertex_ = cell_to_vertex;
2101 *cell_to_edge_ = cell_to_edge;
2102 *num_vertices_per_cell_ = num_vertices_per_cell;
2103 *cell_field_data_ = cell_field_data;
2107 size_t num_cells,
int max_num_vertices_per_cell,
int * num_vertices_per_cell,
2108 size_t * cell_to_vertex,
size_t * cell_to_vertex_offsets,
2110 size_t * cell_to_edge,
size_t * cell_to_edge_offsets,
2114 xmalloc(num_cells *
sizeof(*cell_bnd_circles));
2122 for (
size_t i = 0; i < num_cells; ++i) {
2123 size_t * curr_cell_to_vertex =
2124 cell_to_vertex + cell_to_vertex_offsets[i];
2125 size_t * curr_cell_to_edge =
2126 cell_to_edge + cell_to_edge_offsets[i];
2127 for (
int j = 0; j < num_vertices_per_cell[i]; ++j) {
2129 vertex_coordinates + curr_cell_to_vertex[j];
2130 for (
int k = 0; k < 3; ++k)
2138 cell_bnd_circles[i] =
2148 return cell_bnd_circles;
2158 size_t num_cells = grid_data->
num_cells;
2162 int max_num_vertices_per_cell = 0;
2165 if (core_cell_mask) {
2166 for (
size_t i = 0; i < num_cells; ++i)
2167 if (core_cell_mask[i] &&
2168 (num_vertices_per_cell[i] > max_num_vertices_per_cell))
2169 max_num_vertices_per_cell = num_vertices_per_cell[i];
2171 for (
size_t i = 0; i < num_cells; ++i)
2172 if (num_vertices_per_cell[i] > max_num_vertices_per_cell)
2173 max_num_vertices_per_cell = num_vertices_per_cell[i];
2178 MPI_IN_PLACE, &max_num_vertices_per_cell, 1, MPI_INT, MPI_MAX, comm),
2181 return max_num_vertices_per_cell;
2194 int max_num_vertices_per_cell =
2208 proc_sphere_part, grid, &vertex_ranks, max_num_vertices_per_cell, comm);
2215 size_t dist_count[3];
2217 proc_sphere_part, grid, vertex_ranks, max_num_vertices_per_cell, comm,
2218 dist_point_infos, dist_global_ids, dist_count);
2228 yac_int * sorted_cell_ids, * sorted_vertex_ids, * sorted_edge_ids;
2229 size_t * sorted_cell_reorder_idx, * sorted_vertex_reorder_idx,
2230 * sorted_edge_reorder_idx;
2232 cell_ids, num_cells, &sorted_cell_ids, &sorted_cell_reorder_idx);
2234 vertex_ids, num_vertices, &sorted_vertex_ids,
2235 &sorted_vertex_reorder_idx);
2237 edge_ids, num_edges, &sorted_edge_ids, &sorted_edge_reorder_idx);
2248 comm, dt_coord, vertex_ranks,
2249 &vertex_coordinates, &vertex_owner, &vertex_field_data);
2258 grid, dist_point_infos[
YAC_LOC_EDGE], num_edges, comm, dt_coord,
2259 num_vertices, sorted_vertex_ids, sorted_vertex_reorder_idx,
2260 &edge_to_vertex, &edge_type, &edge_field_data);
2264 size_t * cell_to_vertex;
2265 size_t * cell_to_edge;
2266 int * num_vertices_per_cell;
2269 grid, dist_point_infos[
YAC_LOC_CELL], num_cells, comm, dt_coord,
2270 num_edges, sorted_edge_ids, sorted_edge_reorder_idx,
2271 num_vertices, sorted_vertex_ids, sorted_vertex_reorder_idx,
2272 max_num_vertices_per_cell, &cell_to_vertex, &cell_to_edge,
2273 &num_vertices_per_cell, &cell_field_data);
2278 size_t * cell_to_vertex_offsets =
2279 xmalloc(num_cells *
sizeof(*cell_to_vertex_offsets));
2280 size_t * cell_to_edge_offsets = cell_to_vertex_offsets;
2281 for (
size_t i = 0, accu = 0; i < num_cells; ++i) {
2282 cell_to_vertex_offsets[i] = accu;
2283 accu += (size_t)(num_vertices_per_cell[i]);
2289 .ids = {cell_ids, vertex_ids, edge_ids},
2290 .total_count = {num_cells, num_vertices, num_edges},
2291 .count = {num_cells, num_vertices, num_edges},
2304 .owner_mask = {NULL, NULL, NULL},
2305 .sorted_ids = {sorted_cell_ids, sorted_vertex_ids, sorted_edge_ids},
2306 .sorted_reorder_idx =
2307 {sorted_cell_reorder_idx, sorted_vertex_reorder_idx,
2308 sorted_edge_reorder_idx},
2311 cell_field_data, vertex_field_data, edge_field_data),
2326 for (
int i = 0; i < 2; ++i)
2335 for (
int i = 0; i < 2; ++i) {
2353 for (
size_t i = 0, k = 0; i < 2; ++i) {
2355 for (
size_t j = 0; j < grid_data[i]->
num_vertices; ++j, ++k)
2357 vertices[k].
coord, vertex_coordinates[j],
sizeof(*vertex_coordinates));
2367 return proc_sphere_part;
2374 char const * routine =
"yac_dist_grid_pair_new";
2377 grid_a,
"ERROR(%s): NULL is not a valid value for parameter grid_a",
2380 grid_b,
"ERROR(%s): NULL is not a valid value for parameter grid_b",
2385 "ERROR(%s): identical grid names", routine)
2436 return grid_pair->
comm;
2443 for (
int i = 0; (i < 2) && (dist_grid == NULL); ++i)
2444 if (!strcmp(grid_name, grid_pair->
grid_names[i]))
2447 dist_grid,
"ERROR(yac_dist_grid_pair_get_dist_grid): invalid grid_name")
2463 size_t local_count = 0;
2465 int * owner_mask = dist_grid->
owner_mask[location];
2466 for (
size_t i = 0; i <
count; ++i)
if (owner_mask[i]) ++local_count;
2478 return total_count[location];
2488 return count[location];
2496 return owner_mask[location];
2504 return ids[location];
2512 size_t ** indices,
size_t * num_indices) {
2517 int const * owner_mask =
2520 size_t * temp_indices =
xmalloc(
count *
sizeof(*temp_indices));
2522 size_t num_indices_ = 0;
2524 if (field_mask != NULL) {
2525 for (
size_t i = 0; i <
count; ++i)
2526 if (owner_mask[i] && field_mask[i]) temp_indices[num_indices_++] = i;
2528 for (
size_t i = 0; i <
count; ++i)
2529 if (owner_mask[i]) temp_indices[num_indices_++] = i;
2532 *indices =
xrealloc(temp_indices, num_indices_ *
sizeof(**indices));
2533 *num_indices = num_indices_;
2546 if (field.masks_idx == SIZE_MAX)
return NULL;
2549 (field.masks_idx != SIZE_MAX)?
2552 field.masks_idx):NULL;
2559 (field.coordinates_idx != SIZE_MAX)?
2562 field.coordinates_idx):NULL;
2578 if (field_mask == NULL)
2581 int const * owner_mask =
2584 size_t unmasked_local_count = 0;
2585 for (
size_t i = 0; i < count; ++i)
2586 if (owner_mask[i] && field_mask[i]) ++unmasked_local_count;
2587 return unmasked_local_count;
2593 for (
size_t i = 0; i < count; ++i)
2594 if (point_infos[i].count > 1) free(point_infos[i].
data.multi);
2608 for (
int i = 0; i < 3; ++i) {
2620 if (grid_pair == NULL)
return;
2625 for (
int i = 0; i < 2; ++i) {
2651 for (
size_t i = 0; i < buffer_cell->
num_corners; ++i)
2674 *buffer_cell = cell;
2677 for (
size_t i = 0; i < num_vertices; ++i) {
2696 for (
int i = 0; (i < 2) && (search == NULL); ++i)
2697 if (!strcmp(grid_name, grid_pair->
grid_names[i]))
2701 "ERROR(yac_dist_grid_pair_get_cell_sphere_part): invalid grid_name")
2709 double coord[3],
struct yac_dist_grid * dist_grid,
size_t cell_idx,
2717 size_t * temp_cells;
2718 size_t * num_cells_per_coord =
2723 cell_sphere_part, search_coords,
count, &temp_cells,
2724 num_cells_per_coord);
2731 for (
size_t i = 0, k = 0; i < count; ++i) {
2732 size_t curr_num_cells = num_cells_per_coord[i];
2733 if (curr_num_cells == 0) {
2734 cells[i] = SIZE_MAX;
2735 }
else if (curr_num_cells == 1) {
2737 search_coords[i], dist_grid, temp_cells[k], &buffer_cell))
2738 cells[i] = temp_cells[k];
2740 cells[i] = SIZE_MAX;
2743 size_t cell_idx = SIZE_MAX;
2745 for (
size_t j = 0; j < curr_num_cells; ++j, ++k) {
2746 size_t curr_cell_idx = temp_cells[k];
2749 search_coords[i], dist_grid, curr_cell_idx, &buffer_cell))
2751 if (curr_cell_id < cell_id) {
2752 cell_idx = curr_cell_idx;
2753 cell_id = curr_cell_id;
2756 cells[i] = cell_idx;
2761 free(num_cells_per_coord);
2773 size_t num_ids = dist_grid->
total_count[location];
2775 size_t count_ = *count;
2776 size_t new_count = 0;
2779 qsort(ids, count_,
sizeof(*ids),
2782 for (
size_t i = 0, j = 0; i < count_; ++i) {
2784 while ((j < num_ids) && (sorted_ids[j] < curr_id)) ++j;
2785 if ((j < num_ids) && (sorted_ids[j] == curr_id)) {
2788 if (i != new_count) ids[new_count] = ids[i];
2799 int pack_size_field_coord, pack_size_field_mask;
2802 MPI_Pack_size(3, MPI_DOUBLE, comm, &pack_size_field_coord), comm);
2803 pack_size_field_coord *=
2807 MPI_Pack_size(1, MPI_INT, comm, &pack_size_field_mask), comm);
2808 pack_size_field_mask *=
2811 return pack_size_field_coord + pack_size_field_mask;
2816 MPI_Datatype bnd_circle_dt, MPI_Comm comm) {
2819 pack_size_num_vertices,
2820 pack_size_bnd_circle;
2825 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &pack_size_num_vertices), comm);
2828 MPI_Pack_size(1, bnd_circle_dt, comm, &pack_size_bnd_circle), comm);
2830 return pack_size_id + pack_size_num_vertices + pack_size_bnd_circle +
2838 pack_size_vertex_coords;
2843 MPI_Pack_size(3, MPI_DOUBLE, comm, &pack_size_vertex_coords), comm);
2845 return pack_size_id + pack_size_vertex_coords +
2853 pack_size_edge_to_vertex,
2854 pack_size_edge_type;
2858 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &pack_size_edge_type), comm);
2861 MPI_Pack_size(2,
yac_int_dt, comm, &pack_size_edge_to_vertex), comm);
2863 return pack_size_id + pack_size_edge_type + pack_size_edge_to_vertex +
2868 struct yac_dist_grid * dist_grid, uint64_t * pos,
size_t count,
2869 int * pack_sizes, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
2872 int pack_size_base_cell =
2876 bnd_circle_dt, comm);
2877 int pack_size_base_vertex =
2881 int pack_size_base_edge =
2886 for (
size_t i = 0; i < count; ++i) {
2887 size_t idx = (size_t)(pos[i]);
2889 size_t * curr_vertices =
2891 size_t * curr_edges =
2894 pack_size_base_cell +
2895 num_vertices * (pack_size_base_vertex + pack_size_base_edge) +
2898 for (
int j = 0; j < num_vertices; ++j) {
2902 point_info_dt, comm) +
2906 pack_sizes[i] = pack_size;
2911 struct yac_dist_grid * dist_grid, uint64_t * pos,
size_t count,
2912 int * pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm) {
2914 int pack_size_base_vertex =
2918 for (
size_t i = 0; i < count; ++i)
2920 pack_size_base_vertex +
2926 struct yac_dist_grid * dist_grid, uint64_t * pos,
size_t count,
2927 int * pack_sizes, MPI_Datatype point_info_dt, MPI_Comm comm) {
2929 int pack_size_base_vertex =
2933 int pack_size_base_edge =
2937 for (
size_t i = 0; i < count; ++i) {
2940 pack_size_base_edge +
2941 2 * pack_size_base_vertex +
2946 point_info_dt, comm) +
2949 point_info_dt, comm);
2955 size_t count,
int * pack_sizes, MPI_Datatype bnd_circle_dt,
2956 MPI_Datatype point_info_dt, MPI_Comm comm) {
2964 dist_grid, pos, count, pack_sizes, bnd_circle_dt, point_info_dt, comm);
2968 dist_grid, pos, count, pack_sizes, point_info_dt, comm);
2972 dist_grid, pos, count, pack_sizes, point_info_dt, comm);
2978 size_t idx,
void * buffer,
int buffer_size,
int * position,
2981 size_t coordinates_count =
2983 size_t masks_count =
2987 for (
size_t i = 0; i < coordinates_count; ++i)
2991 3, MPI_DOUBLE, buffer, buffer_size, position, comm), comm);
2994 for (
size_t i = 0; i < masks_count; ++i)
2998 buffer_size, position, comm), comm);
3002 struct yac_dist_grid * dist_grid,
size_t idx,
void * buffer,
int buffer_size,
3003 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
3011 position, comm), comm);
3015 buffer_size, position, comm), comm);
3019 point_info_dt, comm);
3022 idx, buffer, buffer_size, position,
3027 struct yac_dist_grid * dist_grid,
size_t idx,
void * buffer,
int buffer_size,
3028 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
3043 &
edge_type, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
3050 edge_to_vertex, 2,
yac_int_dt, buffer, buffer_size, position, comm),
3055 point_info_dt, comm);
3058 idx, buffer, buffer_size, position,
3063 struct yac_dist_grid * dist_grid,
size_t idx,
void * buffer,
int buffer_size,
3064 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
3068 dist_grid, idx, buffer, buffer_size, position,
3069 bnd_circle_dt, point_info_dt, comm);
3072 for (
int i = 0; i < 2; ++i)
3075 buffer, buffer_size, position, bnd_circle_dt, point_info_dt, comm);
3079 struct yac_dist_grid * dist_grid,
size_t idx,
void * buffer,
int buffer_size,
3080 int * position, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
3092 idx, buffer, buffer_size, position,
3096 MPI_Pack(&num_vertices, 1, MPI_INT, buffer,
3097 buffer_size, position, comm), comm);
3101 buffer_size, position, comm), comm);
3105 point_info_dt, comm);
3107 for (
int i = 0; i < num_vertices; ++i) {
3111 buffer, buffer_size, position, bnd_circle_dt, point_info_dt, comm);
3115 buffer, buffer_size, position, bnd_circle_dt, point_info_dt, comm);
3121 size_t count,
void ** pack_data,
int * pack_sizes,
3122 MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt, MPI_Comm comm) {
3125 bnd_circle_dt, point_info_dt, comm);
3127 size_t pack_size = 0;
3128 for (
size_t i = 0; i < count; ++i) pack_size += (
size_t)(pack_sizes[i]);
3130 void * pack_data_ =
xmalloc(pack_size);
3134 void (*func_pack[3])(
3135 struct yac_dist_grid * dist_grid,
size_t idx,
void * buffer,
3136 int buffer_size,
int * position, MPI_Datatype bnd_circle_dt,
3137 MPI_Datatype point_info_dt, MPI_Comm
comm) =
3140 for (
size_t i = 0, offset = 0; i <
count; ++i) {
3142 func_pack[location](
3143 dist_grid, pos[i], (
char*)pack_data_ + offset, pack_sizes[i],
3144 &position, bnd_circle_dt, point_info_dt,
comm);
3145 pack_sizes[i] = position;
3146 offset += (size_t)position;
3149 *pack_data = pack_data_;
3153 void * buffer,
int buffer_size,
int * position,
size_t idx,
3164 MPI_Unpack(buffer, buffer_size, position,
3170 int buffer_size,
int * position,
3172 MPI_Datatype point_info_dt, MPI_Comm
comm) {
3176 MPI_Unpack(buffer, buffer_size, position, &(vertex[idx].global_id), 1,
3180 MPI_Unpack(buffer, buffer_size, position, &(vertex[idx].coord[0]), 3,
3184 buffer, buffer_size, position, &(vertex[idx].
owners), point_info_dt,
comm);
3187 buffer, buffer_size, position, idx, temp_vertex_field_data,
comm);
3192 int buffer_size,
int * position,
3194 MPI_Datatype point_info_dt, MPI_Comm
comm) {
3200 MPI_Unpack(buffer, buffer_size, position, &(edge[idx].global_id), 1,
3204 MPI_Unpack(buffer, buffer_size, position, &
edge_type, 1,
3209 MPI_Unpack(buffer, buffer_size, position, edge[idx].
edge_to_vertex, 2,
3216 buffer, buffer_size, position, idx, temp_edge_field_data,
comm);
3220 const void * a,
const void * b) {
3231 size_t old_count,
size_t new_count) {
3233 size_t add_count = new_count - old_count;
3240 new_count *
sizeof(*mask));
3242 for (
size_t i = 0, j = old_count; i < add_count; ++i, ++j) {
3244 *(
size_t*)((
unsigned char*)
reorder_idx + i * reorder_idx_size);
3245 mask[j] = temp_mask[idx];
3254 new_count *
sizeof(*coordinates));
3256 for (
size_t i = 0, j = old_count; i < add_count; ++i, ++j) {
3258 *(
size_t*)((
unsigned char*)
reorder_idx + i * reorder_idx_size);
3259 coordinates[j][0] = temp_coordinates[idx][0];
3260 coordinates[j][1] = temp_coordinates[idx][1];
3261 coordinates[j][2] = temp_coordinates[idx][2];
3274 size_t count,
size_t * idx,
3277 if (count == 0)
return;
3280 qsort(vertices, count,
sizeof(*vertices),
3285 size_t * sorted_vertex_reorder_idx =
3289 size_t prev_idx = 0;
3290 size_t add_count = 0;
3294 for (
size_t i = 0, j = 0; i < count; ++i) {
3297 size_t curr_reorder_idx = vertices[i].
reorder_idx;
3300 if (prev_global_id == curr_global_id) {
3301 if (idx != NULL) idx[curr_reorder_idx] = prev_idx;
3305 prev_global_id = curr_global_id;
3309 while ((j < num_total_vertices) && (sorted_vertex_ids[j] < curr_global_id))
3313 if ((j < num_total_vertices) && (sorted_vertex_ids[j] == curr_global_id)) {
3315 if (idx != NULL) idx[curr_reorder_idx] = sorted_vertex_reorder_idx[j];
3316 prev_idx = sorted_vertex_reorder_idx[j];
3322 if (idx != NULL) idx[curr_reorder_idx] = num_total_vertices + add_count;
3323 prev_idx = num_total_vertices + add_count;
3324 if (add_count != i) vertices[add_count] = vertices[i];
3329 size_t new_num_total_vertices = num_total_vertices + add_count;
3332 sizeof(*vertex_coordinates));
3335 new_num_total_vertices *
sizeof(*vertex_ids));
3336 int * vertex_owner_mask =
3338 sizeof(*vertex_owner_mask));
3341 sizeof(*vertex_owners));
3344 sorted_vertex_ids, new_num_total_vertices *
sizeof(*sorted_vertex_ids));
3345 sorted_vertex_reorder_idx =
3347 sorted_vertex_reorder_idx, new_num_total_vertices *
3348 sizeof(*sorted_vertex_reorder_idx));
3351 for (
size_t i = 0, j = num_total_vertices; i < add_count; ++i, ++j) {
3353 vertex_coordinates[j][0] = vertices[i].
coord[0];
3354 vertex_coordinates[j][1] = vertices[i].
coord[1];
3355 vertex_coordinates[j][2] = vertices[i].
coord[2];
3357 vertex_owner_mask[j] = 0;
3358 vertex_owners[j] = vertices[i].
owners;
3359 sorted_vertex_ids[j] = vertices[i].
global_id;
3360 sorted_vertex_reorder_idx[j] = j;
3365 temp_vertex_field_data, vertices,
sizeof(*vertices),
3366 num_total_vertices, new_num_total_vertices);
3368 sorted_vertex_ids, new_num_total_vertices, sorted_vertex_reorder_idx);
3380 const void * a,
const void * b) {
3390 size_t count,
size_t * idx,
struct temp_field_data temp_edge_field_data) {
3392 if (count == 0)
return;
3401 size_t prev_idx = 0;
3402 size_t add_count = 0;
3406 for (
size_t i = 0, j = 0; i < count; ++i) {
3412 if (prev_global_id == curr_global_id) {
3413 if (idx != NULL) idx[curr_reorder_idx] = prev_idx;
3417 prev_global_id = curr_global_id;
3421 while ((j < num_total_edges) && (sorted_edge_ids[j] < curr_global_id)) ++j;
3424 if ((j < num_total_edges) && (sorted_edge_ids[j] == curr_global_id)) {
3426 if (idx != NULL) idx[curr_reorder_idx] = sorted_edge_reorder_idx[j];
3427 prev_idx = sorted_edge_reorder_idx[j];
3433 if (idx != NULL) idx[curr_reorder_idx] = num_total_edges + add_count;
3434 prev_idx = num_total_edges + add_count;
3435 if (add_count != i) edges[add_count] = edges[i];
3440 size_t new_num_total_edges = num_total_edges + add_count;
3443 new_num_total_edges *
sizeof(*edge_ids));
3446 new_num_total_edges *
sizeof(*
edge_type));
3452 new_num_total_edges *
sizeof(*edge_owners));
3453 int * edge_owner_mask =
3455 sizeof(*edge_owner_mask));
3458 sorted_edge_ids, new_num_total_edges *
sizeof(*sorted_edge_ids));
3459 sorted_edge_reorder_idx =
3461 sorted_edge_reorder_idx, new_num_total_edges *
3462 sizeof(*sorted_edge_reorder_idx));
3464 yac_int * vertex_ids =
xmalloc(2 * add_count *
sizeof(*vertex_ids));
3465 size_t * reorder =
xmalloc(2 * add_count *
sizeof(*reorder));
3468 for (
size_t i = 0, j = num_total_edges; i < add_count; ++i, ++j) {
3472 edge_owner_mask[j] = 0;
3473 edge_owners[j] = edges[i].
owners;
3474 sorted_edge_ids[j] = edges[i].
global_id;
3475 sorted_edge_reorder_idx[j] = j;
3479 reorder[2 * i + 0] = 2 * num_total_edges + 2 * i + 0;
3480 reorder[2 * i + 1] = 2 * num_total_edges + 2 * i + 1;
3485 temp_edge_field_data, edges,
sizeof(*edges),
3486 num_total_edges, new_num_total_edges);
3488 sorted_edge_ids, new_num_total_edges, sorted_edge_reorder_idx);
3493 size_t * sorted_vertex_reorder_idx =
3496 size_t * edge_to_vertex_ = (
size_t*)&(edge_to_vertex[0][0]);
3498 for (
size_t i = 0, j = 0; i < 2 * add_count; ++i) {
3499 yac_int curr_id = vertex_ids[i];
3500 while ((j < total_num_vertices) && (sorted_vertex_ids[j] < curr_id)) ++j;
3502 (j < total_num_vertices) && (sorted_vertex_ids[j] == curr_id),
3503 "ERROR(yac_dist_grid_add_edges): vertex id not found")
3504 edge_to_vertex_[reorder[i]] = sorted_vertex_reorder_idx[j];
3523 int * num_vertices_per_cell,
struct bounding_circle * cell_bnd_circles,
3524 size_t count,
size_t * cell_to_vertex,
size_t * cell_to_edge,
3528 if (
count == 0)
return;
3530 size_t * reorder_idx =
xmalloc(
count *
sizeof(reorder_idx));
3531 for (
size_t i = 0; i <
count; ++i) reorder_idx[i] = i;
3534 for (
size_t i = 0, accu = 0; i <
count;
3535 accu += (size_t)(num_vertices_per_cell[i++])) prescan[i] = accu;
3541 size_t * sorted_cell_reorder_idx =
3544 yac_int prev_global_id = cell_ids[0] - 1;
3545 size_t cell_add_count = 0;
3546 size_t relations_add_count = 0;
3550 for (
size_t i = 0, j = 0; i <
count; ++i) {
3552 yac_int curr_global_id = cell_ids[i];
3553 size_t curr_reorder_idx = reorder_idx[i];
3556 if (prev_global_id == curr_global_id) {
3560 prev_global_id = curr_global_id;
3564 while ((j < num_total_cells) && (sorted_cell_ids[j] < curr_global_id)) ++j;
3567 if ((j >= num_total_cells) || (sorted_cell_ids[j] != curr_global_id)) {
3569 if (cell_add_count != i) {
3570 cell_ids[cell_add_count] = curr_global_id;
3571 reorder_idx[cell_add_count] = curr_reorder_idx;
3574 relations_add_count += (size_t)(num_vertices_per_cell[curr_reorder_idx]);
3578 size_t new_num_total_cells = num_total_cells + cell_add_count;
3579 size_t num_total_relations =
3580 (num_total_cells > 0)?
3583 size_t new_num_total_relations = num_total_relations + relations_add_count;
3586 new_num_total_cells *
sizeof(*new_cell_ids));
3587 int * new_num_vertices_per_cell =
3589 sizeof(*new_num_vertices_per_cell));
3590 size_t * new_cell_to_vertex =
3592 sizeof(*new_cell_to_vertex));
3593 size_t * cell_to_vertex_offsets =
3595 sizeof(*cell_to_vertex_offsets));
3596 size_t * new_cell_to_edge =
3598 sizeof(*new_cell_to_edge));
3601 sizeof(*new_cell_bnd_circles));
3602 int * cell_owner_mask =
3604 new_num_total_cells *
sizeof(*cell_owner_mask));
3607 new_num_total_cells *
sizeof(*cell_owners));
3610 sorted_cell_ids, new_num_total_cells *
sizeof(*sorted_cell_ids));
3611 sorted_cell_reorder_idx =
3613 sorted_cell_reorder_idx, new_num_total_cells *
3614 sizeof(*sorted_cell_reorder_idx));
3617 for (
size_t i = 0, j = num_total_cells; i < cell_add_count;
3620 size_t curr_reorder_idx = reorder_idx[i];
3621 int curr_num_vertices = num_vertices_per_cell[curr_reorder_idx];
3622 size_t curr_relation_idx = prescan[curr_reorder_idx];
3624 new_cell_ids[j] = cell_ids[i];
3625 new_num_vertices_per_cell[j] = curr_num_vertices;
3626 cell_to_vertex_offsets[j] = num_total_relations;
3627 for (
int j = 0; j < curr_num_vertices;
3628 ++j, ++num_total_relations, ++curr_relation_idx) {
3629 new_cell_to_vertex[num_total_relations] =
3630 cell_to_vertex[curr_relation_idx];
3631 new_cell_to_edge[num_total_relations] = cell_to_edge[curr_relation_idx];
3633 cell_owner_mask[j] = 0;
3634 sorted_cell_ids[j] = cell_ids[i];
3635 sorted_cell_reorder_idx[j] = j;
3636 new_cell_bnd_circles[j] = cell_bnd_circles[curr_reorder_idx];
3637 new_cell_owners[j] = cell_owners[curr_reorder_idx];
3642 temp_cell_field_data, reorder_idx,
sizeof(*reorder_idx),
3643 num_total_cells, new_num_total_cells);
3645 sorted_cell_ids, new_num_total_cells, sorted_cell_reorder_idx);
3724 struct yac_dist_grid * dist_grid,
size_t count,
void * buffer,
3725 int buffer_size, MPI_Datatype bnd_circle_dt, MPI_Datatype point_info_dt,
3729 int * num_vertices_per_cell =
xmalloc(count *
sizeof(*num_vertices_per_cell));
3731 xmalloc(count *
sizeof(*cell_bnd_circles));
3736 size_t vertices_array_size = 0;
3737 size_t total_num_vertices = 0;
3740 size_t edges_array_size = 0;
3755 for (
size_t i = 0, buffer_offset = 0; i < count; ++i) {
3758 void * curr_buffer = (
char*)buffer + buffer_offset;
3763 MPI_Unpack(curr_buffer, buffer_size, &position, cell_ids + i, 1,
3767 curr_buffer, buffer_size, &position, i, temp_cell_field_data, comm);
3770 MPI_Unpack(curr_buffer, buffer_size, &position, &num_vertices, 1,
3771 MPI_INT, comm), comm);
3774 MPI_Unpack(curr_buffer, buffer_size, &position, cell_bnd_circles + i, 1,
3775 bnd_circle_dt, comm), comm);
3778 curr_buffer, buffer_size, &position, cell_owners + i,
3779 point_info_dt, comm);
3781 num_vertices_per_cell[i] = num_vertices;
3784 vertices, vertices_array_size, total_num_vertices + (
size_t)num_vertices);
3786 edges, edges_array_size, total_num_vertices + (
size_t)num_vertices);
3788 &temp_vertex_field_data, total_num_vertices + (
size_t)num_vertices);
3790 &temp_edge_field_data, total_num_vertices + (
size_t)num_vertices);
3792 for (
int j = 0; j < num_vertices; ++j, ++total_num_vertices) {
3794 vertices, total_num_vertices, curr_buffer, buffer_size, &position,
3795 temp_vertex_field_data, point_info_dt, comm);
3797 edges, total_num_vertices, curr_buffer, buffer_size, &position,
3798 temp_edge_field_data, point_info_dt, comm);
3799 vertices[total_num_vertices].
reorder_idx = total_num_vertices;
3800 edges[total_num_vertices].
reorder_idx = total_num_vertices;
3803 buffer_offset += (size_t)position;
3804 buffer_size -= position;
3807 size_t * cell_to_vertex =
xmalloc(total_num_vertices *
sizeof(*cell_to_vertex));
3808 size_t * cell_to_edge =
xmalloc(total_num_vertices *
sizeof(*cell_to_edge));
3811 dist_grid, vertices, total_num_vertices, cell_to_vertex,
3812 temp_vertex_field_data);
3814 dist_grid, edges, total_num_vertices, cell_to_edge,
3815 temp_edge_field_data);
3817 dist_grid, cell_ids, num_vertices_per_cell, cell_bnd_circles, count,
3818 cell_to_vertex, cell_to_edge, cell_owners, temp_cell_field_data);
3824 free(cell_to_vertex);
3828 free(cell_bnd_circles);
3829 free(num_vertices_per_cell);
3834 struct yac_dist_grid * dist_grid,
size_t count,
void * buffer,
3835 int buffer_size, MPI_Datatype point_info_dt, MPI_Comm comm) {
3844 for (
size_t i = 0, buffer_offset = 0; i < count; ++i) {
3847 void * curr_buffer = (
char*)buffer + buffer_offset;
3850 vertices, i, curr_buffer, buffer_size, &position,
3851 temp_vertex_field_data, point_info_dt, comm);
3854 buffer_offset += (size_t)position;
3855 buffer_size -= position;
3859 dist_grid, vertices, count, NULL, temp_vertex_field_data);
3867 struct yac_dist_grid * dist_grid,
size_t count,
void * buffer,
3868 int buffer_size, MPI_Datatype point_info_dt, MPI_Comm comm) {
3872 xmalloc(2 * count *
sizeof(*vertices));
3883 for (
size_t i = 0, buffer_offset = 0; i < count; ++i) {
3886 void * curr_buffer = (
char*)buffer + buffer_offset;
3889 edges, i, curr_buffer, buffer_size, &position,
3890 temp_edge_field_data, point_info_dt, comm);
3893 for (
size_t j = 0; j < 2; ++j)
3895 vertices, 2 * i + j, curr_buffer, buffer_size, &position,
3896 temp_vertex_field_data, point_info_dt, comm);
3898 buffer_offset += (size_t)position;
3899 buffer_size -= position;
3903 dist_grid, vertices, 2 * count, NULL, temp_vertex_field_data);
3905 dist_grid, edges, count, NULL, temp_edge_field_data);
3916 void * buffer,
int buffer_size, MPI_Datatype bnd_circle_dt,
3917 MPI_Datatype point_info_dt, MPI_Comm comm) {
3925 dist_grid, count, buffer, buffer_size, bnd_circle_dt,
3926 point_info_dt, comm);
3930 dist_grid, count, buffer, buffer_size, point_info_dt, comm);
3934 dist_grid, count, buffer, buffer_size, point_info_dt, comm);
3940 const void * a,
const void * b) {
3948 size_t count,
enum yac_location location,
size_t * idx) {
3950 MPI_Comm comm = dist_grid->
comm;
3951 int comm_rank, comm_size;
3955 size_t remote_count = 0;
3957 for (
size_t i = 0; i < count; ++i) {
3958 if (ids[i].global_id == XT_INT_MAX) idx[i] = SIZE_MAX;
3959 else if (ids[i].
data.rank != comm_rank) ++remote_count;
3964 xmalloc(remote_count *
sizeof(*missing_ids));
3966 for (
size_t i = 0, j = 0; i < count; ++i) {
3967 if ((ids[i].
data.rank != comm_rank) &&
3969 missing_ids[j].
data = ids[i];
3977 dist_grid, location, missing_ids, &remote_count, idx);
3980 qsort(missing_ids, remote_count,
sizeof(*missing_ids),
3983 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
3985 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
3987 for (
size_t i = 0; i < remote_count; ++i)
3991 1, sendcounts, recvcounts, sdispls, rdispls, comm);
3993 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
3995 uint64_t * uint64_t_buffer =
3996 xmalloc((remote_count + recv_count) *
sizeof(*uint64_t_buffer));
3997 uint64_t * orig_pos_send_buffer = uint64_t_buffer;
3998 uint64_t * orig_pos_recv_buffer = uint64_t_buffer + remote_count;
4001 for (
size_t i = 0; i < remote_count; ++i) {
4003 if (rank != comm_rank)
4004 orig_pos_send_buffer[sdispls[rank+1]++] =
4009 yac_alltoallv_uint64_p2p(
4010 orig_pos_send_buffer, sendcounts, sdispls,
4011 orig_pos_recv_buffer, recvcounts, rdispls, comm,
4012 "yac_dist_grid_single_remote_point_to_local", __LINE__);
4019 void * packed_send_data = NULL;
4020 int * pack_sizes =
xmalloc(recv_count *
sizeof(*pack_sizes));
4024 dist_grid, location, orig_pos_recv_buffer, recv_count,
4025 &packed_send_data, pack_sizes,
4026 bnd_circle_dt, point_info_dt, comm);
4027 free(uint64_t_buffer);
4029 memset(sendcounts, 0, (
size_t)comm_size *
sizeof(*sendcounts));
4030 for (
int i = 0, k = 0; i < comm_size; ++i)
4031 for (
size_t j = 0; j < recvcounts[i]; ++j, ++k)
4032 sendcounts[i] += (
size_t)(pack_sizes[k]);
4037 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4039 recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4041 void * packed_recv_data =
xmalloc(recv_count);
4044 yac_alltoallv_packed_p2p(
4045 packed_send_data, sendcounts, sdispls+1,
4046 packed_recv_data, recvcounts, rdispls, comm,
4047 "yac_dist_grid_single_remote_point_to_local", __LINE__);
4051 dist_grid, location, remote_count, packed_recv_data, (
int)recv_count,
4052 bnd_circle_dt, point_info_dt, comm);
4059 dist_grid, location, missing_ids, &remote_count, idx);
4062 free(packed_recv_data);
4063 free(packed_send_data);
4070 MPI_Datatype single_id_owner_dt;
4071 int array_of_blocklengths[] = {1, 1, 1};
4072 const MPI_Aint array_of_displacements[] =
4073 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
global_id) -
4074 (MPI_Aint)(intptr_t)(
const void *)&dummy,
4075 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
data.
rank) -
4076 (MPI_Aint)(intptr_t)(
const void *)&dummy,
4077 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
data.
orig_pos) -
4078 (MPI_Aint)(intptr_t)(
const void *)&dummy};
4079 const MPI_Datatype array_of_types[] =
4082 MPI_Type_create_struct(3, array_of_blocklengths, array_of_displacements,
4083 array_of_types, &single_id_owner_dt), comm);
4092 double coord[3],
struct yac_dist_grid * dist_grid,
size_t cell_idx,
4095 char const * routine =
"yac_dist_grid_pair_do_point_search_";
4097 MPI_Comm comm = grid_pair->
comm;
4098 int comm_rank, comm_size;
4102 int * ranks =
xmalloc(count *
sizeof(ranks));
4117 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4119 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
4120 for (
size_t i = 0; i < count; ++i) sendcounts[ranks[i]]++;
4122 size_t local_count = sendcounts[comm_rank];
4123 sendcounts[comm_rank] = 0;
4126 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4128 size_t remote_count = sdispls[comm_size] + sendcounts[comm_size-1];
4129 size_t request_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4132 xmalloc((remote_count + request_count + local_count) *
4133 sizeof(*coord_buffer));
4137 coord_buffer + remote_count + request_count;
4140 for (
size_t i = 0, k = 0; i < count; ++i) {
4141 if (ranks[i] == comm_rank) {
4142 coord_local_buffer[k][0] = search_coords[i][0];
4143 coord_local_buffer[k][1] = search_coords[i][1];
4144 coord_local_buffer[k][2] = search_coords[i][2];
4147 size_t displ = sdispls[ranks[i]+1]++;
4148 coord_send_buffer[displ][0] = search_coords[i][0];
4149 coord_send_buffer[displ][1] = search_coords[i][1];
4150 coord_send_buffer[displ][2] = search_coords[i][2];
4154 MPI_Datatype dt_coord;
4155 yac_mpi_call(MPI_Type_contiguous(3, MPI_DOUBLE, &dt_coord), comm);
4160 coord_send_buffer, sendcounts, sdispls,
4161 coord_recv_buffer, recvcounts, rdispls,
4162 sizeof(*coord_send_buffer), dt_coord, comm, routine, __LINE__);
4166 size_t * local_cells =
4167 xmalloc((request_count + local_count) *
sizeof(*local_cells));
4176 grid_pair, grid_name, coord_recv_buffer, request_count + local_count,
4186 xmalloc((remote_count + request_count) *
4187 sizeof(*single_remote_point_buffer));
4196 for (
size_t i = 0; i < request_count; ++i) {
4197 size_t cell_idx = local_cells[i];
4198 id_send_buffer[i].
data.
rank = comm_rank;
4199 if (cell_idx != SIZE_MAX) {
4203 id_send_buffer[i].
global_id = XT_INT_MAX;
4208 MPI_Datatype single_remote_point_dt =
4213 id_send_buffer, recvcounts, rdispls, id_recv_buffer, sendcounts, sdispls,
4214 sizeof(*id_send_buffer), single_remote_point_dt,
comm, routine, __LINE__);
4218 size_t * new_local_cells =
4219 xmalloc(remote_count *
sizeof(*new_local_cells));
4230 dist_grid, id_recv_buffer, remote_count,
YAC_LOC_CELL, new_local_cells);
4233 for (
size_t i = 0, k = 0; i <
count; ++i) {
4234 if (ranks[i] == comm_rank) {
4235 cells[i] = local_cells[request_count + k];
4238 size_t displ = sdispls[ranks[i]]++;
4239 cells[i] = new_local_cells[displ];
4243 free(new_local_cells);
4244 free(single_remote_point_buffer);
4278 size_t total_count =
4284 total_count, field_coords, global_ids);
4288 total_count, field_coords, global_ids, mask);
4302 int const * owner_mask =
4307 if (field_mask == NULL) {
4309 for (
size_t i = 0, j = 0; i < count; ++i) {
4310 if (owner_mask[i]) {
4311 points[j].global_id = global_ids[i];
4312 points[j].data.rank = comm_rank;
4313 points[j].data.orig_pos = i;
4314 if (n == ++j)
return;
4320 for (
size_t i = 0, j = 0; i < count; ++i) {
4321 if (owner_mask[i] && field_mask[i]) {
4322 points[j].global_id = global_ids[i];
4323 points[j].data.rank = comm_rank;
4324 points[j].data.orig_pos = i;
4325 if (n == ++j)
return;
4332 void const * a,
void const * b) {
4341 if (ret)
return ret;
4350 double cos_max_search_distance,
size_t * result_points) {
4356 double * cos_angles = NULL;
4357 size_t cos_angles_array_size = 0;
4358 size_t * temp_result_points = NULL;
4359 size_t temp_result_points_array_size = 0;
4360 size_t * num_temp_results =
xmalloc(count *
sizeof(*num_temp_results));
4362 sphere_part, count, search_coords, n, &cos_angles,
4363 &cos_angles_array_size, NULL, NULL, &temp_result_points,
4364 &temp_result_points_array_size, num_temp_results);
4370 size_t max_num_results = 0;
4371 for (
size_t i = 0; i < count; ++i)
4372 if (max_num_results < num_temp_results[i])
4373 max_num_results = num_temp_results[i];
4376 xmalloc(max_num_results *
sizeof(*temp_results));
4382 for (
size_t i = 0, k = 0; i < count; ++i) {
4384 size_t curr_num_search_results = num_temp_results[i];
4385 size_t curr_num_results = 0;
4388 for (
size_t j = 0; j < curr_num_search_results; ++j, ++k) {
4391 if (cos_angles[k] >= cos_max_search_distance) {
4394 size_t curr_local_id = temp_result_points[k];
4395 temp_results[curr_num_results].
local_id = curr_local_id;
4396 temp_results[curr_num_results].
global_id = global_ids[curr_local_id];
4397 temp_results[curr_num_results].
cos_angle = cos_angles[k];
4404 temp_results, curr_num_results,
sizeof(*temp_results),
4407 if (curr_num_results > n) curr_num_results = n;
4409 for (
size_t l = 0; l < curr_num_results; ++l)
4410 result_points[i * n + l] = temp_results[l].
local_id;
4411 for (
size_t l = curr_num_results; l < n; ++l)
4412 result_points[i * n + l] = UINT64_MAX;
4415 free(num_temp_results);
4418 free(temp_result_points);
4423 size_t const * a_ = a, * b_ = b;
4425 return (*a_ > *b_) - (*b_ > *a_);
4433 char const * routine =
"yac_dist_grid_pair_do_nnn_search";
4435 MPI_Comm comm = grid_pair->
comm;
4436 int comm_rank, comm_size;
4441 (max_search_distance >= 0.0) && (max_search_distance <= M_PI),
4442 "ERROR(%s): invalid max_search_distance (%lf)",
4443 routine, max_search_distance)
4458 uint64_t unmasked_local_count =
4461 uint64_t * unmasked_local_counts =
4462 xmalloc((
size_t)comm_size *
sizeof(*unmasked_local_counts));
4467 &unmasked_local_count, 1, MPI_UINT64_T,
4468 unmasked_local_counts, 1, MPI_UINT64_T,
comm),
comm);
4472 for (
int i = 0; i < comm_size; ++i)
4473 flag |= unmasked_local_counts[i] < (uint64_t)n;
4478 uint64_t global_num_unmasked_count = 0;
4479 for (
int i = 0; i < comm_size; ++i)
4480 global_num_unmasked_count += unmasked_local_counts[i];
4483 (
size_t)global_num_unmasked_count >= n,
"ERROR(%s): "
4484 "insufficient number of unmasked points (available: %zu required: %zu",
4485 routine, (
size_t)global_num_unmasked_count, n)
4487 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4489 1, &sendcounts, &recvcounts, &sdispls, &rdispls,
comm);
4493 int * flag_buffer =
xcalloc(2 * (
size_t)comm_size,
sizeof(*flag_buffer));
4494 int * send_flags = flag_buffer;
4495 int * recv_flags = flag_buffer + comm_size;
4498 send_flags, recv_flags, comm_rank, comm_size);
4499 for (
int i = 0; i < comm_size; ++i) {
4500 sendcounts[i] = (size_t)send_flags[i];
4501 recvcounts[i] = (size_t)recv_flags[i];
4505 size_t local_send_count = (size_t)(
MIN(unmasked_local_count, n));
4508 for (
int i = 0; i < comm_size; ++i) {
4511 sendcounts[i] *= local_send_count;
4512 raccu += (recvcounts[i] *= (int)(
MIN(unmasked_local_counts[i], n)));
4515 size_t recv_count = recvcounts[comm_size-1] + rdispls[comm_size-1];
4519 (local_send_count + recv_count) *
sizeof(*single_remote_point_buffer));
4522 single_remote_point_buffer + local_send_count;
4526 dist_grid, field, comm_rank, local_send_count, local_send_ids);
4528 MPI_Datatype single_remote_point_dt =
4533 local_send_ids, sendcounts, sdispls, recv_ids, recvcounts, rdispls,
4534 sizeof(*local_send_ids), single_remote_point_dt, comm,
4537 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4539 size_t * dummy =
xmalloc(recv_count *
sizeof(*dummy));
4544 dist_grid, recv_ids, recv_count, field.location, dummy);
4547 free(single_remote_point_buffer);
4550 free(unmasked_local_counts);
4563 sphere_part, count, search_coords, n, ubounds);
4570 int * request_ranks = NULL;
4571 size_t request_ranks_array_size = 0;
4572 size_t num_request_ranks = 0;
4573 int * num_requests =
xmalloc(count *
sizeof(*num_requests));
4576 for (
size_t i = 0; i < count; ++i) {
4581 3 *
sizeof(search_coords[0][0]));
4583 ubounds[i] = max_search_distance_angle;
4588 num_request_ranks + (
size_t)comm_size);
4592 int * curr_request_ranks = request_ranks + num_request_ranks;
4595 curr_request_ranks, num_requests + i);
4598 int new_num_requests = 0;
4599 for (
int j = 0; j < num_requests[i]; ++j) {
4600 if (curr_request_ranks[j] == comm_rank)
continue;
4601 if (new_num_requests != j)
4602 curr_request_ranks[new_num_requests] = curr_request_ranks[j];
4606 num_request_ranks += (size_t)(num_requests[i] = new_num_requests);
4615 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4617 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
4619 for (
size_t i = 0; i < num_request_ranks; ++i) sendcounts[request_ranks[i]]++;
4622 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4624 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4627 xmalloc((num_request_ranks + recv_count) *
sizeof(*bnd_circles));
4629 struct bounding_circle * recv_bnd_circles = bnd_circles + num_request_ranks;
4632 for (
size_t i = 0, k = 0; i < count; ++i) {
4633 for (
int j = 0; j < num_requests[i]; ++j, ++k) {
4635 send_bnd_circles + sdispls[request_ranks[k]+1];
4636 sdispls[request_ranks[k]+1]++;
4637 memcpy(curr_bnd_circle->
base_vector, search_coords[i],
4638 3 *
sizeof(search_coords[0][0]));
4639 curr_bnd_circle->
inc_angle = ubounds[i];
4644 free(request_ranks);
4651 send_bnd_circles, sendcounts, sdispls,
4652 recv_bnd_circles, recvcounts, rdispls,
4653 sizeof(*send_bnd_circles), bnd_circle_dt, comm, routine, __LINE__);
4662 size_t * result_points = NULL;
4663 size_t result_points_array_size = 0;
4664 size_t * num_results_points =
4665 xmalloc(recv_count *
sizeof(*num_results_points));
4667 sphere_part, recv_count, recv_bnd_circles, n, &result_points,
4668 &result_points_array_size, num_results_points);
4674 size_t total_num_result_points = 0;
4675 size_t offset = 0, k = 0;
4676 for (
int i = 0; i < comm_size; ++i) {
4677 size_t curr_num_result_points = 0;
4678 for (
size_t j = 0; j < recvcounts[i]; ++j, ++k)
4679 curr_num_result_points += num_results_points[k];
4680 size_t new_num_result_points = curr_num_result_points;
4682 result_points + offset,
4685 result_points + offset, &new_num_result_points);
4687 result_points + total_num_result_points,
4688 result_points + offset, new_num_result_points *
4689 sizeof(*result_points));
4690 total_num_result_points += new_num_result_points;
4691 offset += curr_num_result_points;
4692 sendcounts[i] = new_num_result_points;
4694 free(num_results_points);
4697 1, sendcounts, recvcounts, sdispls, rdispls, comm);
4698 recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4704 xmalloc((total_num_result_points + recv_count) *
4705 sizeof(*single_remote_point_buffer));
4708 total_num_result_points;
4709 for (
size_t i = 0; i < total_num_result_points; ++i) {
4710 size_t orig_pos = result_points[i];
4711 id_send_buffer[i].
global_id = global_ids[orig_pos];
4712 id_send_buffer[i].
data.
rank = comm_rank;
4715 free(result_points);
4717 MPI_Datatype single_remote_point_dt =
4722 id_send_buffer, sendcounts, sdispls+1, id_recv_buffer, recvcounts, rdispls,
4723 sizeof(*id_send_buffer), single_remote_point_dt, comm, routine, __LINE__);
4724 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4733 size_t * temp_idx =
xmalloc(recv_count *
sizeof(*temp_idx));
4735 dist_grid, id_recv_buffer, recv_count, field.location, temp_idx);
4737 free(single_remote_point_buffer);
4744 dist_grid, field, count, search_coords, n, max_search_distance_angle.
cos,
4753 char const * routine =
"yac_dist_grid_pair_do_bnd_circle_search";
4755 MPI_Comm comm = grid_pair->
comm;
4756 int comm_rank, comm_size;
4768 int * rank_buffer = NULL;
4769 size_t rank_buffer_size = 0;
4770 size_t rank_buffer_array_size = 0;
4772 for (
size_t i = 0; i <
count; ++i) {
4775 rank_buffer_size + (
size_t)comm_size);
4783 rank_buffer + rank_buffer_size, num_ranks + i);
4784 rank_buffer_size += (size_t)(num_ranks[i]);
4791 size_t * size_t_buffer =
4792 xmalloc(4 * (
size_t)comm_size *
sizeof(*size_t_buffer));
4793 size_t * result_sendcounts = size_t_buffer + 0 * comm_size;
4794 size_t * result_recvcounts = size_t_buffer + 1 * comm_size;
4795 size_t * result_sdispls = size_t_buffer + 2 * comm_size;
4796 size_t * result_rdispls = size_t_buffer + 3 * comm_size;
4798 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
4800 1, &sendcounts, &recvcounts, &sdispls, &rdispls,
comm);
4802 for (
size_t i = 0, offset = 0; i <
count; ++i) {
4803 int curr_num_ranks = num_ranks[i];
4804 int * ranks = rank_buffer + offset;
4805 offset += (size_t)curr_num_ranks;
4806 for (
int j = 0; j < curr_num_ranks; ++j) sendcounts[ranks[j]]++;
4810 size_t local_count = sendcounts[comm_rank];
4811 sendcounts[comm_rank] = 0;
4814 1, sendcounts, recvcounts, sdispls, rdispls,
comm);
4816 size_t send_count = sdispls[comm_size] + sendcounts[comm_size-1];
4817 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
4820 xmalloc((send_count + recv_count + local_count) *
4821 sizeof(*bnd_circle_buffer));
4823 struct bounding_circle * recv_buffer = bnd_circle_buffer + send_count;
4825 bnd_circle_buffer + send_count + recv_count;
4828 for (
size_t i = 0, offset = 0, local_offset = 0; i < count; ++i) {
4829 int curr_num_ranks = num_ranks[i];
4830 int * ranks = rank_buffer + offset;
4831 offset += (size_t)curr_num_ranks;
4832 for (
int j = 0; j < curr_num_ranks; ++j) {
4833 int rank = ranks[j];
4834 if (rank == comm_rank)
4835 local_buffer[local_offset++] = bnd_circles[i];
4837 send_buffer[sdispls[rank + 1]++] = bnd_circles[i];
4846 send_buffer, sendcounts, sdispls, recv_buffer, recvcounts, rdispls,
4847 sizeof(*send_buffer), bnd_circle_dt, comm, routine, __LINE__);
4858 size_t * local_cells = NULL;
4859 size_t * num_local_cells_per_bnd_circle =
4860 xmalloc((recv_count + local_count) *
4861 sizeof(*num_local_cells_per_bnd_circle));
4863 uint64_t * uint64_t_buffer =
4864 xmalloc((send_count + recv_count + local_count) *
4865 sizeof(*uint64_t_buffer));
4866 uint64_t * num_local_cells_per_bnd_circle_uint64_t = uint64_t_buffer;
4867 uint64_t * num_remote_cells_per_bnd_circle =
4868 uint64_t_buffer + recv_count + local_count;
4872 cell_sphere_part, recv_buffer, recv_count + local_count, &local_cells,
4873 num_local_cells_per_bnd_circle);
4880 int const * field_mask =
4887 for (
size_t i = 0, offset = 0, new_offset = 0;
4888 i < recv_count + local_count; ++i) {
4891 size_t curr_num_results = num_local_cells_per_bnd_circle[i];
4894 uint64_t new_num_results = 0;
4895 for (
size_t j = 0; j < curr_num_results; ++j, ++offset) {
4896 size_t local_cell_id = local_cells[offset];
4898 cell_bnd_circles + local_cell_id))
continue;
4899 if ((field_mask == NULL) || (field_mask[local_cell_id])) {
4900 if (offset != new_offset) local_cells[new_offset] = local_cell_id;
4905 num_local_cells_per_bnd_circle_uint64_t[i] = new_num_results;
4907 free(num_local_cells_per_bnd_circle);
4908 free(bnd_circle_buffer);
4916 num_local_cells_per_bnd_circle_uint64_t, recvcounts, rdispls,
4917 num_remote_cells_per_bnd_circle, sendcounts, sdispls,
4918 sizeof(*num_local_cells_per_bnd_circle_uint64_t), MPI_UINT64_T, comm,
4921 size_t saccu = 0, raccu = 0, soffset = 0, roffset = 0;
4922 for (
int i = 0; i < comm_size; ++i) {
4924 result_sdispls[i] = saccu;
4925 result_rdispls[i] = raccu;
4927 size_t sendcount = recvcounts[i];
4928 size_t recvcount = sendcounts[i];
4930 result_sendcounts[i] = 0;
4931 result_recvcounts[i] = 0;
4932 for (
size_t j = 0; j < sendcount; ++j, ++soffset)
4933 result_sendcounts[i] +=
4934 (
size_t)(num_local_cells_per_bnd_circle_uint64_t[soffset]);
4935 for (
size_t j = 0; j < recvcount; ++j, ++roffset)
4936 result_recvcounts[i] +=
4937 (
size_t)(num_remote_cells_per_bnd_circle[roffset]);
4939 saccu += result_sendcounts[i];
4940 raccu += result_recvcounts[i];
4945 size_t result_local_count = 0;
4946 for (
size_t i = recv_count; i < recv_count + local_count; ++i)
4947 result_local_count += (
size_t)(num_local_cells_per_bnd_circle_uint64_t[i]);
4949 size_t result_send_count = (size_t)(result_sdispls[comm_size-1]) +
4950 (size_t)(result_sendcounts[comm_size-1]);
4951 size_t result_recv_count = (size_t)(result_rdispls[comm_size-1]) +
4952 (size_t)(result_recvcounts[comm_size-1]);
4955 xmalloc((result_recv_count + result_send_count) *
4956 sizeof(*single_remote_point_buffer));
4963 for (
size_t i = 0; i < result_send_count; ++i) {
4964 size_t local_cell_id = local_cells[i];
4965 id_send_buffer[i].
global_id = cell_ids[local_cell_id];
4966 id_send_buffer[i].
data.
rank = comm_rank;
4970 MPI_Datatype single_remote_point_dt =
4975 id_send_buffer, result_sendcounts, result_sdispls,
4976 id_recv_buffer, result_recvcounts, result_rdispls,
4977 sizeof(*id_send_buffer), single_remote_point_dt, comm,
4980 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
4982 size_t * new_local_cells =
4983 xmalloc((result_recv_count + result_local_count) *
4984 sizeof(*new_local_cells));
4986 memcpy(new_local_cells + result_recv_count,
4987 local_cells + result_send_count,
4988 result_local_count *
sizeof(*new_local_cells));
4999 dist_grid, id_recv_buffer, result_recv_count,
YAC_LOC_CELL, new_local_cells);
5001 free(single_remote_point_buffer);
5003 size_t * reorder_idx =
5004 xmalloc((result_recv_count + result_local_count) *
sizeof(*reorder_idx));
5007 num_results_per_bnd_circle, 0, count *
sizeof(*num_results_per_bnd_circle));
5009 for (
size_t i = 0, offset = 0, reorder = 0, local_search_idx = recv_count,
5010 local_offset = result_recv_count; i < count; ++i) {
5011 int curr_num_ranks = num_ranks[i];
5012 int * ranks = rank_buffer + offset;
5013 offset += (size_t)curr_num_ranks;
5014 for (
int j = 0; j < curr_num_ranks; ++j) {
5015 int rank = ranks[j];
5016 if (rank == comm_rank) {
5017 uint64_t curr_num_results =
5018 num_local_cells_per_bnd_circle_uint64_t[local_search_idx++];
5019 num_results_per_bnd_circle[i] += (size_t)curr_num_results;
5020 for (uint64_t k = 0; k < curr_num_results; ++k, ++reorder)
5021 reorder_idx[local_offset++] = reorder;
5023 size_t rank_pos = sdispls[rank]++;
5024 uint64_t curr_num_results = num_remote_cells_per_bnd_circle[rank_pos];
5025 num_results_per_bnd_circle[i] += (size_t)curr_num_results;
5026 for (uint64_t k = 0; k < curr_num_results; ++k, ++reorder)
5027 reorder_idx[result_rdispls[rank]++] = reorder;
5031 free(uint64_t_buffer);
5034 free(size_t_buffer);
5038 reorder_idx, result_recv_count + result_local_count, new_local_cells);
5042 for (
size_t i = 0, offset = 0, new_offset = 0; i < count; ++i) {
5044 size_t * curr_local_cells = new_local_cells + offset;
5045 size_t curr_num_results_per_bnd_circle = num_results_per_bnd_circle[i];
5046 size_t new_num_results_per_bnd_circle = 0;
5047 size_t prev_cell = SIZE_MAX;
5048 offset += curr_num_results_per_bnd_circle;
5051 curr_local_cells, curr_num_results_per_bnd_circle, NULL);
5053 for (
size_t j = 0; j < curr_num_results_per_bnd_circle; ++j) {
5054 size_t curr_cell = curr_local_cells[j];
5055 if (curr_cell != prev_cell) {
5056 new_local_cells[new_offset++] = (prev_cell = curr_cell);
5057 ++new_num_results_per_bnd_circle;
5060 num_results_per_bnd_circle[i] = new_num_results_per_bnd_circle;
5063 *cells = new_local_cells;
5068 char const * search_grid_name,
char const * result_grid_name,
5069 size_t * search_cells,
size_t count,
size_t ** result_cells,
5070 size_t * num_results_per_search_cell,
struct yac_interp_field result_field) {
5073 xmalloc(count *
sizeof(*search_bnd_circles));
5083 for (
size_t i = 0; i <
count; ++i)
5084 search_bnd_circles[i] = search_grid_cell_bnd_circles[search_cells[i]];
5087 grid_pair, result_grid_name, search_bnd_circles,
count, result_cells,
5088 num_results_per_search_cell, result_field);
5090 size_t total_num_result_cells = 0;
5098 for (
size_t i = 0, offset = 0; i <
count; ++i) {
5100 size_t curr_num_results_per_bnd_circle = num_results_per_search_cell[i];
5101 size_t new_num_results_per_search_cell = 0;
5102 size_t * curr_result_cells = *result_cells + offset;
5103 offset += curr_num_results_per_bnd_circle;
5109 for (
size_t j = 0; j < curr_num_results_per_bnd_circle; ++j) {
5111 size_t curr_result_cell = curr_result_cells[j];
5121 search_bnd_circles + i,
5124 (*result_cells)[total_num_result_cells++] = curr_result_cell;
5125 ++new_num_results_per_search_cell;
5129 num_results_per_search_cell[i] = new_num_results_per_search_cell;
5137 free(search_bnd_circles);
5145 dist_grid->edge_to_vertex, dist_grid->vertex_coordinates, edge_id);
5151 size_t * cells,
size_t count,
size_t * neighbours) {
5153 char const * routine =
"yac_dist_grid_get_cell_neighbours";
5163 int max_num_edges_per_cell = 0;
5165 if (max_num_edges_per_cell < dist_grid->num_vertices_per_cell[i])
5169 xmalloc((
size_t)max_num_edges_per_cell *
sizeof(*edge_vertices));
5171 size_t neigh_idx = 0;
5174 size_t missing_edge_neighbour_array_size = 0;
5175 size_t num_missing_neighbours = 0;
5178 for (
size_t i = 0; i < count; ++i) {
5180 size_t curr_cell = cells[i];
5184 size_t const * cell_edges =
5186 for (
size_t j = 0; j < curr_num_edges; ++j) {
5187 size_t const * curr_edge_to_vertex =
5189 edge_vertices[j][0] = curr_edge_to_vertex[0];
5190 edge_vertices[j][1] = curr_edge_to_vertex[1];
5195 num_missing_neighbours + curr_num_edges);
5199 size_t prev_vertex = edge_vertices[0][0];
5200 for (
size_t j = 0, edge_idx = 0; j < curr_num_edges; ++j, ++
neigh_idx) {
5203 size_t curr_edge = cell_edges[edge_idx];
5204 size_t * curr_edge_cells = edge_to_cell[curr_edge];
5205 size_t other_cell = curr_edge_cells[curr_edge_cells[0] == curr_cell];
5208 if (other_cell == SIZE_MAX) {
5221 size_t new_edge_idx = SIZE_MAX;
5222 for (
size_t k = 0; k < curr_num_edges; ++k) {
5223 if (k == edge_idx)
continue;
5224 else if (edge_vertices[k][0] == prev_vertex) {
5226 prev_vertex = edge_vertices[k][1];
5228 }
else if (edge_vertices[k][1] == prev_vertex) {
5230 prev_vertex = edge_vertices[k][0];
5235 new_edge_idx < SIZE_MAX,
5236 "ERROR(%s): inconsistent cell_to_edge/edge_to_vertex data", routine)
5237 edge_idx = new_edge_idx;
5242 prev_vertex == edge_vertices[0][0],
5243 "ERROR(%s): inconsistent cell_to_edge/edge_to_vertex data", routine)
5247 MPI_Comm comm = dist_grid->
comm;
5248 int comm_rank, comm_size;
5252 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
5254 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
5257 ((
size_t)comm_size + num_missing_neighbours) *
sizeof(*int_buffer));
5258 int * temp_ranks = int_buffer;
5259 int * num_ranks = int_buffer + comm_size;
5260 memset(num_ranks, 0, num_missing_neighbours *
sizeof(*num_ranks));
5262 int * rank_buffer = NULL;
5263 size_t rank_buffer_array_size = 0;
5264 size_t rank_buffer_size = 0;
5266 for (
size_t i = 0; i < num_missing_neighbours; ++i) {
5274 temp_ranks, &curr_num_ranks);
5277 rank_buffer_size + (
size_t)curr_num_ranks);
5279 for (
int j = 0; j < curr_num_ranks; ++j) {
5280 int curr_rank = temp_ranks[j];
5281 if (curr_rank != comm_rank) {
5282 sendcounts[curr_rank] += 2;
5284 rank_buffer[rank_buffer_size++] = curr_rank;
5290 1, sendcounts, recvcounts, sdispls, rdispls, comm);
5293 (sdispls[comm_size] + sendcounts[comm_size-1])/2;
5295 (rdispls[comm_size-1] + recvcounts[comm_size-1])/2;
5298 xmalloc(2 * (send_count + recv_count) *
sizeof(*yac_int_buffer));
5299 yac_int * send_buffer = yac_int_buffer;
5300 yac_int * recv_buffer = yac_int_buffer + 2 * send_count;
5301 size_t * result_reorder_idx =
5302 xmalloc(send_count *
sizeof(*result_reorder_idx));
5305 for (
size_t i = 0, k = 0, rank_offset = 0; i < num_missing_neighbours; ++i) {
5307 int * curr_rank_buffer = rank_buffer + rank_offset;
5308 int curr_num_ranks = num_ranks[i];
5309 rank_offset += (size_t)curr_num_ranks;
5311 for (
int j = 0; j < curr_num_ranks; ++j, ++k) {
5313 int rank = curr_rank_buffer[j];
5315 if (rank == comm_rank)
continue;
5317 size_t pos = sdispls[rank + 1];
5318 sdispls[rank + 1] += 2;
5329 yac_alltoallv_yac_int_p2p(
5330 send_buffer, sendcounts, sdispls,
5331 recv_buffer, recvcounts, rdispls, comm, routine, __LINE__);
5334 xmalloc(recv_count *
sizeof(*request_edge_ids));
5335 size_t * reorder_idx =
xmalloc(recv_count *
sizeof(*reorder_idx));
5338 (send_count + recv_count) *
sizeof(*point_info_buffer));
5341 point_info_buffer + recv_count;
5342 for (
size_t i = 0; i < recv_count; ++i) {
5343 request_edge_ids[i] = recv_buffer[2 * i + 0];
5348 request_edge_ids, recv_count, reorder_idx);
5350 size_t * sorted_edge_reorder_idx =
5356 for (
size_t i = 0, j = 0; i < recv_count; ++i) {
5358 yac_int curr_edge_id = request_edge_ids[i];
5359 size_t curr_reorder_idx = reorder_idx[i];
5361 while ((j < num_edges) && (sorted_edge_ids[j] < curr_edge_id)) ++j;
5364 if ((j >= num_edges) || (sorted_edge_ids[j] != curr_edge_id)) {
5365 point_send_buffer[curr_reorder_idx] =
5368 .data = {.rank = comm_rank, .orig_pos = UINT64_MAX}};
5373 yac_int available_edge_cell_id = recv_buffer[2 * curr_reorder_idx + 1];
5375 size_t * local_edge_cell_ids = edge_to_cell[sorted_edge_reorder_idx[j]];
5376 yac_int global_edge_cell_ids[2];
5377 for (
int k = 0; k < 2; ++k)
5378 global_edge_cell_ids[k] =
5379 (local_edge_cell_ids[k] == SIZE_MAX)?
5380 XT_INT_MAX:cell_ids[local_edge_cell_ids[k]];
5382 int missing_idx = global_edge_cell_ids[0] == available_edge_cell_id;
5386 (global_edge_cell_ids[missing_idx^1] == available_edge_cell_id) ||
5387 (global_edge_cell_ids[missing_idx^1] == XT_INT_MAX),
5388 "ERROR(%s): inconsistent cell edge grid data", routine)
5390 point_send_buffer[curr_reorder_idx].
global_id =
5391 global_edge_cell_ids[missing_idx];
5392 point_send_buffer[curr_reorder_idx].
data.
rank = comm_rank;
5394 (local_edge_cell_ids[missing_idx] == SIZE_MAX)?
5395 (uint64_t)UINT64_MAX:local_edge_cell_ids[missing_idx];
5398 free(request_edge_ids);
5399 free(yac_int_buffer);
5401 for (
int i = 0; i < comm_size; ++i) {
5408 MPI_Datatype single_remote_point_dt =
5412 point_send_buffer, recvcounts, rdispls,
5413 point_recv_buffer, sendcounts, sdispls,
5414 sizeof(*point_send_buffer), single_remote_point_dt, comm,
5417 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
5420 xmalloc(send_count *
sizeof(*results));
5422 for (
size_t i = 0; i < send_count; ++i) {
5423 results[i].
data = point_recv_buffer[i];
5427 qsort(results, send_count,
sizeof(*results),
5431 size_t result_count = 0;
5432 yac_int prev_global_id = XT_INT_MAX;
5433 for (
size_t i = 0, prev_reorder_idx = SIZE_MAX; i < send_count; ++i) {
5437 if (curr_global_id == XT_INT_MAX)
continue;
5440 if (curr_reorder_idx != prev_reorder_idx){
5442 results[result_count++] = results[i];
5443 prev_reorder_idx = curr_reorder_idx;
5444 prev_global_id = curr_global_id;
5449 prev_global_id == curr_global_id,
5450 "ERROR(%s): inconsistent cell edge data", routine)
5453 for (
size_t i = 0; i < result_count; ++i) {
5454 point_send_buffer[i] = results[i].
data;
5459 size_t * local_ids =
xmalloc(result_count *
sizeof(*local_ids));
5462 dist_grid, point_send_buffer, result_count,
YAC_LOC_CELL, local_ids);
5464 for (
size_t i = 0; i < result_count; ++i)
5465 neighbours[result_reorder_idx[i]] = local_ids[i];
5468 free(result_reorder_idx);
5469 free(point_send_buffer);
5474 free(edge_vertices);
5480 size_t * cells,
size_t count,
size_t * neighbours) {
5489 size_t *
points,
size_t count) {
5494 yac_int * global_ids = dist_grid->
ids[location];
5497 for (
size_t i = 0; i <
count; ++i) {
5507 return (
int)(
value / 128) % comm_size;
5512 int global_id_pack_size;
5515 MPI_Pack_size(1,
yac_int_dt, comm, &global_id_pack_size), comm);
5517 return global_id_pack_size;
5521 yac_int global_id,
void * buffer,
int buffer_size,
int * position,
5526 buffer_size, position, comm), comm);
5530 void * buffer,
int buffer_size,
int * position,
yac_int * global_id,
5534 MPI_Unpack(buffer, buffer_size, position, global_id, 1,
5539 MPI_Datatype single_remote_point_dt, MPI_Comm comm) {
5544 MPI_Pack_size(1, single_remote_point_dt, comm, &pack_size), comm);
5551 void * buffer,
int buffer_size,
int * position,
5552 MPI_Datatype single_remote_point_dt, MPI_Comm comm) {
5555 MPI_Pack(point, 1, single_remote_point_dt, buffer,
5556 buffer_size, position, comm), comm);
5560 void * buffer,
int buffer_size,
int * position,
5565 MPI_Unpack(buffer, buffer_size, position, point, 1,
5566 single_remote_point_dt, comm), comm);
5571 yac_int * global_ids,
size_t count,
size_t * local_ids) {
5573 char const * routine =
"yac_dist_grid_global_to_local";
5575 MPI_Comm comm = dist_grid->
comm;
5576 int comm_rank, comm_size;
5580 size_t * size_t_buffer =
5581 xmalloc((8 * (
size_t)comm_size + 1) *
sizeof(*size_t_buffer));
5582 size_t * sendcounts = size_t_buffer + 0 * comm_size;
5583 size_t * recvcounts = size_t_buffer + 2 * comm_size;
5584 size_t * sdispls = size_t_buffer + 4 * comm_size;
5585 size_t * rdispls = size_t_buffer + 5 * comm_size + 1;
5586 size_t * total_sendcounts = size_t_buffer + 6 * comm_size + 1;
5587 size_t * total_recvcounts = size_t_buffer + 7 * comm_size + 1;
5588 memset(sendcounts, 0, 2 * (
size_t)comm_size *
sizeof(*sendcounts));
5590 size_t * core_points, core_count;
5593 .coordinates_idx = SIZE_MAX,
5594 .masks_idx = SIZE_MAX};
5596 dist_grid, dummy_interp_field, &core_points, &core_count);
5597 yac_int const * grid_global_ids =
5600 int * rank_buffer =
xmalloc((count + core_count) *
sizeof(*rank_buffer));
5601 int * core_point_ranks = rank_buffer;
5602 int * global_id_ranks = rank_buffer + core_count;
5604 size_t * global_id_reorder_idx =
5605 xmalloc(count *
sizeof(*global_id_reorder_idx));
5607 for (
size_t i = 0; i < count; ++i) {
5610 sendcounts[2 * rank + 0]++;
5611 global_id_reorder_idx[i] = i;
5616 for (
size_t i = 0; i < core_count; ++i) {
5617 size_t point_idx = core_points[i];
5619 (core_point_ranks[i] =
5621 sendcounts[2 * rank + 1]++;
5632 size_t recv_core_count = 0;
5633 for (
int i = 0; i < comm_size; ++i)
5634 recv_core_count += recvcounts[2*i+1];
5636 MPI_Datatype single_remote_point_dt =
5639 int core_point_pack_size =
5642 for (
int i = 0; i < comm_size; ++i) {
5643 total_sendcounts[i] = sendcounts[2*i+0] * (size_t)global_id_pack_size +
5644 sendcounts[2*i+1] * (
size_t)core_point_pack_size;
5645 total_recvcounts[i] = recvcounts[2*i+0] * (size_t)global_id_pack_size +
5646 recvcounts[2*i+1] * (
size_t)core_point_pack_size;
5649 size_t saccu = 0, raccu = 0;
5651 for (
int i = 0; i < comm_size; ++i) {
5652 sdispls[i+1] = saccu;
5654 saccu += total_sendcounts[i];
5655 raccu += total_recvcounts[i];
5658 size_t send_size = sdispls[comm_size] + total_sendcounts[comm_size-1];
5659 size_t recv_size = rdispls[comm_size-1] + total_recvcounts[comm_size-1];
5660 void * pack_buffer =
xmalloc(send_size + recv_size);
5661 void * send_buffer = pack_buffer;
5662 void * recv_buffer = (
void*)((
unsigned char *)pack_buffer + send_size);
5665 for (
size_t i = 0; i < count; ++i) {
5666 yac_int curr_global_id = global_ids[global_id_reorder_idx[i]];
5667 int rank = global_id_ranks[i];
5668 size_t pos = sdispls[rank + 1];
5671 curr_global_id, (
void*)((
unsigned char*)send_buffer + pos),
5672 global_id_pack_size, &position, comm);
5673 sdispls[rank + 1] += global_id_pack_size;
5675 for (
size_t i = 0; i < core_count; ++i) {
5676 size_t point_idx = core_points[i];
5677 int rank = core_point_ranks[i];
5678 size_t pos = sdispls[rank + 1];
5680 curr_core_point.
global_id = grid_global_ids[point_idx];
5681 curr_core_point.
data.
rank = comm_rank;
5686 (
void*)((
unsigned char*)send_buffer + pos),
5687 core_point_pack_size, &position, single_remote_point_dt, comm);
5688 sdispls[rank + 1] += core_point_pack_size;
5694 yac_alltoallv_packed_p2p(
5695 send_buffer, total_sendcounts, sdispls,
5696 recv_buffer, total_recvcounts, rdispls, comm, routine, __LINE__);
5698 size_t num_requested_ids = 0;
5699 for(
int i = 0; i < comm_size; ++i)
5700 num_requested_ids += recvcounts[2*i+0];
5702 yac_int * request_global_ids =
5703 xmalloc(num_requested_ids *
sizeof(*request_global_ids));
5704 size_t * reorder_idx =
5705 xmalloc(num_requested_ids *
sizeof(*reorder_idx));
5707 xmalloc((recv_core_count + num_requested_ids + count) *
5708 sizeof(*point_info_buffer));
5711 point_info_buffer + recv_core_count;
5713 point_info_buffer + recv_core_count + num_requested_ids;
5716 num_requested_ids = 0;
5717 recv_core_count = 0;
5718 for (
int i = 0; i < comm_size; ++i) {
5720 size_t curr_num_requested_ids = recvcounts[2*i+0];
5721 size_t curr_num_core_points = recvcounts[2*i+1];
5723 for (
size_t j = 0; j < curr_num_requested_ids; ++j, ++num_requested_ids) {
5727 recv_buffer, global_id_pack_size, &position,
5728 request_global_ids + num_requested_ids, comm);
5729 reorder_idx[num_requested_ids] = num_requested_ids;
5730 recv_buffer = (
void*)((
unsigned char*)recv_buffer + global_id_pack_size);
5732 for (
size_t j = 0; j < curr_num_core_points; ++j, ++recv_core_count) {
5736 recv_buffer, core_point_pack_size, &position,
5737 recv_core_points + recv_core_count, single_remote_point_dt, comm);
5738 recv_buffer = (
void*)((
unsigned char*)recv_buffer + core_point_pack_size);
5745 request_global_ids, num_requested_ids, reorder_idx);
5748 qsort(recv_core_points, recv_core_count,
sizeof(*recv_core_points),
5752 for (
size_t i = 0, j = 0; i < num_requested_ids; ++i) {
5754 yac_int curr_global_id = request_global_ids[i];
5755 while ((j < recv_core_count) &&
5756 (recv_core_points[j].
global_id < curr_global_id)) ++j;
5759 (j < recv_core_count) &&
5760 (recv_core_points[j].
global_id == curr_global_id),
5761 "ERROR(%s): no matching core point found for global id %zu",
5762 routine, (
size_t)curr_global_id)
5764 send_point_info[reorder_idx[i]] = recv_core_points[j];
5767 free(request_global_ids);
5769 saccu = 0, raccu = 0;
5770 for (
int i = 0; i < comm_size; ++i) {
5774 int recvcount = sendcounts[2*i+0];
5775 int sendcount = recvcounts[2*i+0];
5776 saccu += (sendcounts[i] = sendcount);
5777 raccu += (recvcounts[i] = recvcount);
5782 send_point_info, sendcounts, sdispls,
5783 recv_point_info, recvcounts, rdispls,
5784 sizeof(*send_point_info), single_remote_point_dt, comm,
5787 free(size_t_buffer);
5788 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
5791 dist_grid, recv_point_info, count, location, local_ids);
5795 free(global_id_reorder_idx);
5796 free(point_info_buffer);
5801 size_t * vertices,
size_t count,
size_t ** cells,
5809 xmalloc(count *
sizeof(*vertex_bnd_circles));
5814 for (
size_t i = 0; i < count; ++i) {
5815 memcpy(vertex_bnd_circles[i].base_vector,
5817 vertex_bnd_circles[i].
inc_angle = sin_cos_high_tol;
5818 vertex_bnd_circles[i].
sq_crd = DBL_MAX;
5823 grid_pair, grid_name, vertex_bnd_circles, count,
5824 cells, num_cells_per_vertex, field);
5825 free(vertex_bnd_circles);
5828 size_t total_num_cells = 0;
5829 for (
size_t i = 0, k = 0; i < count; ++i) {
5831 size_t curr_vertex = vertices[i];
5832 size_t curr_num_cells_per_vertex = num_cells_per_vertex[i];
5834 size_t new_num_cells_per_vertex = 0;
5837 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j, ++k) {
5839 size_t curr_cell = (*cells)[k];
5840 size_t * curr_cell_vertices =
5845 size_t vertex_idx = 0;
5846 for (; vertex_idx < curr_cell_size; ++vertex_idx)
5847 if (curr_cell_vertices[vertex_idx] == curr_vertex)
break;
5850 if (vertex_idx == curr_cell_size)
continue;
5852 if (total_num_cells != k)
5853 (*cells)[total_num_cells] = curr_cell;
5854 ++new_num_cells_per_vertex;
5858 num_cells_per_vertex[i] = new_num_cells_per_vertex;
5861 *cells =
xrealloc(*cells, total_num_cells *
sizeof(**cells));
5887 size_t * vertices,
size_t count,
size_t ** cells,
5894 size_t * result_cells;
5895 size_t * num_result_per_vertex =
5898 grid_pair, grid_name, vertices,
count,
5899 &result_cells, num_result_per_vertex, field);
5901 size_t max_num_cell_per_vertex = 0;
5902 for (
size_t i = 0; i <
count; ++i)
5903 if (num_result_per_vertex[i] > max_num_cell_per_vertex)
5904 max_num_cell_per_vertex = num_result_per_vertex[i];
5905 size_t (*neigh_vertices)[2] =
5906 xmalloc(max_num_cell_per_vertex *
sizeof(*neigh_vertices));
5907 size_t * temp_vertex_cell =
5908 xmalloc(max_num_cell_per_vertex *
sizeof(*temp_vertex_cell));
5910 xmalloc(max_num_cell_per_vertex *
sizeof(*global_cell_ids));
5913 for (
size_t i = 0, offset = 0, new_offset = 0; i <
count; ++i) {
5915 size_t curr_vertex = vertices[i];
5916 size_t * curr_cells = result_cells + offset;
5917 size_t curr_num_cells_per_vertex = num_result_per_vertex[i];
5920 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j) {
5922 size_t curr_cell = curr_cells[j];
5923 size_t * curr_cell_vertices =
5927 size_t vertex_idx = 0;
5928 for (; vertex_idx < curr_cell_size; ++vertex_idx)
5929 if (curr_cell_vertices[vertex_idx] == curr_vertex)
break;
5932 neigh_vertices[j][0] =
5933 curr_cell_vertices[((vertex_idx + curr_cell_size) - 1)%curr_cell_size];
5934 neigh_vertices[j][1] =
5935 curr_cell_vertices[(vertex_idx + 1)%curr_cell_size];
5937 if (new_offset != offset) result_cells[new_offset + j] = curr_cell;
5940 offset += curr_num_cells_per_vertex;
5941 curr_cells = result_cells + new_offset;
5943 if (curr_num_cells_per_vertex > 0) {
5946 temp_vertex_cell[0] = curr_cells[0];
5947 size_t start_neigh_vertex = neigh_vertices[0][0];
5948 size_t prev_vertex = neigh_vertices[0][1];
5949 for (
size_t j = 1, prev_cell_idx = 0; j < curr_num_cells_per_vertex; ++j) {
5952 for (k = 0; k < curr_num_cells_per_vertex; ++k) {
5954 if (k == prev_cell_idx)
continue;
5956 int flag = neigh_vertices[k][0] == prev_vertex;
5957 if (flag || (neigh_vertices[k][1] == prev_vertex)) {
5958 temp_vertex_cell[j] = curr_cells[k];
5960 prev_vertex = neigh_vertices[k][flag];
5967 if (k == curr_num_cells_per_vertex) {
5968 curr_num_cells_per_vertex = 0;
5972 if ((prev_vertex != start_neigh_vertex) ||
5973 (curr_num_cells_per_vertex < 3))
5974 curr_num_cells_per_vertex = 0;
5977 new_offset += curr_num_cells_per_vertex;
5978 num_cells_per_vertex[i] = (int)curr_num_cells_per_vertex;
5980 if (curr_num_cells_per_vertex == 0)
continue;
5983 yac_int min_global_cell_id = XT_INT_MAX;
5984 size_t min_global_cell_id_idx = SIZE_MAX;
5985 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j) {
5987 ((global_cell_ids[j] =
5989 if (curr_global_cell_id < min_global_cell_id) {
5990 min_global_cell_id = curr_global_cell_id;
5991 min_global_cell_id_idx = j;
5998 ((min_global_cell_id_idx + curr_num_cells_per_vertex) - 1)%
5999 curr_num_cells_per_vertex] >
6001 (min_global_cell_id_idx + 1)%curr_num_cells_per_vertex])?-1:1;
6004 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j)
6007 ((
int)(min_global_cell_id_idx + curr_num_cells_per_vertex) +
6008 (
int)j * order)%(
int)curr_num_cells_per_vertex];
6011 *cells = result_cells;
6012 free(num_result_per_vertex);
6013 free(global_cell_ids);
6014 free(temp_vertex_cell);
6015 free(neigh_vertices);
6020 size_t * vertices,
size_t count,
size_t ** neigh_vertices_,
6026 size_t * result_cells;
6027 size_t * num_result_per_vertex =
6030 grid_pair, grid_name, vertices,
count, &result_cells,
6031 num_result_per_vertex, field);
6033 size_t total_num_neigh = 0;
6034 size_t max_num_neigh = 0;
6035 for (
size_t i = 0; i <
count; ++i) {
6036 total_num_neigh += num_result_per_vertex[i];
6037 if (num_result_per_vertex[i] > max_num_neigh)
6038 max_num_neigh = num_result_per_vertex[i];
6041 int const * vertex_mask = NULL;
6045 size_t * neigh_vertices =
6046 xmalloc(total_num_neigh *
sizeof(*neigh_vertices));
6047 size_t * temp_neigh_vertices =
6048 xmalloc(2 * max_num_neigh *
sizeof(*temp_neigh_vertices));
6049 total_num_neigh = 0;
6052 for (
size_t i = 0, offset = 0; i <
count; ++i) {
6054 size_t curr_vertex = vertices[i];
6055 size_t * curr_cells = result_cells + offset;
6056 size_t curr_num_cells_per_vertex = num_result_per_vertex[i];
6058 size_t curr_num_neigh_vertices = 0;
6061 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j) {
6063 size_t curr_cell = curr_cells[j];
6064 size_t * curr_cell_vertices =
6069 size_t vertex_idx = 0;
6070 for (; vertex_idx < curr_cell_size; ++vertex_idx)
6071 if (curr_cell_vertices[vertex_idx] == curr_vertex)
break;
6074 size_t neigh_vertex_idx =
6075 curr_cell_vertices[((vertex_idx + curr_cell_size) - 1)%curr_cell_size];
6076 if ((vertex_mask != NULL) && (vertex_mask[neigh_vertex_idx]))
6077 temp_neigh_vertices[curr_num_neigh_vertices++] = neigh_vertex_idx;
6079 curr_cell_vertices[(vertex_idx + 1)%curr_cell_size];
6080 if ((vertex_mask != NULL) && (vertex_mask[neigh_vertex_idx]))
6081 temp_neigh_vertices[curr_num_neigh_vertices++] = neigh_vertex_idx;
6084 qsort(temp_neigh_vertices, curr_num_neigh_vertices,
6087 temp_neigh_vertices, &curr_num_neigh_vertices);
6088 memcpy(neigh_vertices + total_num_neigh, temp_neigh_vertices,
6089 curr_num_neigh_vertices *
sizeof(*neigh_vertices));
6091 total_num_neigh += curr_num_neigh_vertices;
6092 num_neighs_per_vertex[i] = curr_num_neigh_vertices;
6094 offset += curr_num_cells_per_vertex;
6096 free(temp_neigh_vertices);
6099 free(num_result_per_vertex);
6101 *neigh_vertices_ = neigh_vertices;
6106 size_t * vertices,
size_t count,
size_t ** vertex_to_cell,
6107 size_t * num_cells_per_vertex) {
6115 .coordinates_idx = SIZE_MAX,
6116 .masks_idx = SIZE_MAX};
6118 grid_pair, grid_name, vertices, count, vertex_to_cell,
6119 num_cells_per_vertex, dummy_interp_field);
6121 size_t max_num_cells_per_vertex = 0;
6122 for (
size_t i = 0; i < count; ++i)
6123 if (num_cells_per_vertex[i] > max_num_cells_per_vertex)
6124 max_num_cells_per_vertex = num_cells_per_vertex[i];
6127 xmalloc(max_num_cells_per_vertex *
sizeof(*global_id_buffer));
6132 (count == 0) || (global_cell_ids != NULL),
6133 "ERROR(yac_dist_grid_pair_get_corner_cells): no global cell ids")
6136 for (
size_t i = 0, offset = 0; i < count; ++i) {
6138 size_t curr_num_cells_per_vertex = num_cells_per_vertex[i];
6139 size_t * curr_vertex_to_cell = *vertex_to_cell + offset;
6140 offset += curr_num_cells_per_vertex;
6143 for (
size_t j = 0; j < curr_num_cells_per_vertex; ++j)
6144 global_id_buffer[j] = global_cell_ids[curr_vertex_to_cell[j]];
6148 global_id_buffer, curr_num_cells_per_vertex, curr_vertex_to_cell);
6151 free(global_id_buffer);
6156 size_t * cells,
size_t count,
6157 size_t ** vertex_to_cell,
size_t ** vertex_to_cell_offsets_,
6164 size_t * temp_cells =
xmalloc(
count *
sizeof(*temp_cells));
6165 int * required_vertices =
6167 memcpy(temp_cells, cells,
count *
sizeof(*cells));
6169 for (
size_t i = 0, prev_cell = SIZE_MAX; i <
count; ++i) {
6170 size_t curr_cell = temp_cells[i];
6171 if (curr_cell == SIZE_MAX)
break;
6172 if (curr_cell != prev_cell) {
6173 prev_cell = curr_cell;
6175 size_t const * curr_vertices =
6177 for (
size_t j = 0; j < curr_num_vertices; ++j)
6178 required_vertices[curr_vertices[j]] = 1;
6184 size_t num_unique_vertices = 0;
6186 if (required_vertices[i]) ++num_unique_vertices;
6187 size_t * unique_vertices =
6188 xmalloc(num_unique_vertices *
sizeof(*unique_vertices));
6190 if (required_vertices[i]) unique_vertices[j++] = i;
6191 free(required_vertices);
6194 int * num_cells_per_vertex =
6195 xcalloc(num_unique_vertices,
sizeof(*num_cells_per_vertex));
6197 grid_pair, grid_name, unique_vertices, num_unique_vertices,
6198 vertex_to_cell, num_cells_per_vertex, field);
6200 int * grid_num_cells_per_vertex =
6203 sizeof(*grid_num_cells_per_vertex));
6205 for (
size_t i = 0; i < num_unique_vertices; ++i)
6206 grid_num_cells_per_vertex[unique_vertices[i]] =
6207 num_cells_per_vertex[i];
6208 free(num_cells_per_vertex);
6209 free(unique_vertices);
6211 size_t * vertex_to_cell_offsets =
6214 sizeof(*vertex_to_cell_offsets));
6217 vertex_to_cell_offsets[i] = offset;
6218 offset += grid_num_cells_per_vertex[i];
6221 *vertex_to_cell_offsets_ = vertex_to_cell_offsets;
6222 *num_cells_per_vertex_ = grid_num_cells_per_vertex;
6226 size_t **
points,
size_t * reorder_idx,
int * ranks,
size_t count,
6227 enum yac_location location,
size_t local_count,
size_t recv_count,
6230 size_t * sendcounts,
size_t * sdispls,
size_t * recvcounts,
size_t * rdispls,
6231 MPI_Datatype single_remote_point_dt, MPI_Comm
comm,
6234 char const * routine =
"relocate_points";
6242 size_t * old_points = *
points;
6243 size_t * new_points =
6244 xmalloc((local_count + recv_count) *
sizeof(*new_points));
6246 for (
size_t i = 0, j = 0, k = 0; i <
count; ++i) {
6247 size_t idx = reorder_idx[i];
6248 size_t curr_point = old_points[idx];
6249 int curr_rank = ranks[i];
6250 if (curr_rank == comm_rank) {
6251 new_points[j++] = curr_point;
6253 id_send_buffer[k].
global_id = global_ids[curr_point];
6254 id_send_buffer[k].
data.
rank = comm_rank;
6262 id_send_buffer, sendcounts, sdispls,
6263 id_recv_buffer, recvcounts, rdispls,
6264 sizeof(*id_send_buffer), single_remote_point_dt,
comm, routine, __LINE__);
6269 dist_grid, id_recv_buffer, recv_count, location,
6270 new_points + local_count);
6277 double ** weights,
size_t * reorder_idx,
int * ranks,
size_t count,
6278 size_t send_count,
size_t local_count,
size_t recv_count,
6279 size_t * sendcounts,
size_t * sdispls,
size_t * recvcounts,
size_t * rdispls,
6282 char const * routine =
"relocate_weights";
6287 double * old_weights = *weights;
6288 double * send_buffer =
xmalloc(send_count *
sizeof(*send_buffer));
6289 double * recv_buffer =
6290 xmalloc((local_count + recv_count) *
sizeof(*recv_buffer));
6292 for (
size_t i = 0, j = 0, k = 0; i <
count; ++i) {
6293 size_t idx = reorder_idx[i];
6294 double curr_weight = old_weights[idx];
6295 int curr_rank = ranks[i];
6296 if (curr_rank == comm_rank) recv_buffer[j++] = curr_weight;
6297 else send_buffer[k++] = curr_weight;
6302 send_buffer, sendcounts, sdispls,
6303 recv_buffer + local_count, recvcounts, rdispls,
6304 sizeof(*send_buffer), MPI_DOUBLE,
comm, routine, __LINE__);
6307 *weights = recv_buffer;
6314 size_t * vertices,
size_t count,
int * ranks) {
6316 size_t * reorder_idx =
xmalloc(
count *
sizeof(*reorder_idx));
6317 for (
size_t i = 0; i <
count; ++i) reorder_idx[i] = i;
6321 for (valid_count = 0;
6322 (valid_count <
count) && (vertices[valid_count] != SIZE_MAX);
6325 for (
size_t i = valid_count; i <
count; ++i) ranks[reorder_idx[i]] = 0;
6327 size_t unique_count = 0;
6328 size_t prev_vertex = SIZE_MAX;
6329 for (
size_t i = 0; i < valid_count; ++i) {
6330 size_t curr_vertex = vertices[i];
6331 if (curr_vertex != prev_vertex) {
6332 prev_vertex = curr_vertex;
6339 xmalloc(unique_count *
sizeof(*search_coords));
6341 prev_vertex = SIZE_MAX;
6342 for (
size_t i = 0, j = 0; i < valid_count; ++i) {
6343 size_t curr_vertex = vertices[i];
6344 if (curr_vertex != prev_vertex) {
6345 prev_vertex = curr_vertex;
6347 search_coords[j++], grid_coords[curr_vertex], 3 *
sizeof(
double));
6351 int * temp_ranks =
xmalloc(unique_count *
sizeof(*temp_ranks));
6353 proc_sphere_part, search_coords, unique_count, temp_ranks);
6355 prev_vertex = SIZE_MAX;
6356 for (
size_t i = 0, j = 0; i < valid_count; ++i) {
6357 size_t curr_vertex = vertices[i];
6358 if (curr_vertex != prev_vertex) {
6359 prev_vertex = curr_vertex;
6362 ranks[reorder_idx[i]] = temp_ranks[j-1];
6367 free(search_coords);
6374 size_t * indices,
size_t count,
int * ranks,
6375 size_t (*get_ce_reference_vertex)(
struct yac_dist_grid *,
size_t)) {
6377 size_t * reorder_idx =
xmalloc(
count *
sizeof(*reorder_idx));
6378 for (
size_t i = 0; i <
count; ++i) reorder_idx[i] = i;
6381 size_t unique_count = 0;
6382 size_t prev_index = SIZE_MAX;
6383 for (
size_t i = 0; i <
count; ++i) {
6384 size_t curr_index = indices[i];
6385 if (curr_index != prev_index) {
6386 prev_index = curr_index;
6391 size_t * ref_vertices =
xmalloc(unique_count *
sizeof(*ref_vertices));
6392 prev_index = SIZE_MAX;
6393 for (
size_t i = 0, j = 0; i <
count; ++i) {
6394 size_t curr_index = indices[i];
6395 if (curr_index != prev_index) {
6396 prev_index = curr_index;
6398 get_ce_reference_vertex(dist_grid, curr_index);
6402 int * temp_ranks =
xmalloc(unique_count *
sizeof(*temp_ranks));
6404 dist_grid, proc_sphere_part, ref_vertices, unique_count, temp_ranks);
6407 prev_index = SIZE_MAX;
6408 for (
size_t i = 0, j = 0; i <
count; ++i) {
6409 size_t curr_index = indices[i];
6410 if (curr_index != prev_index) {
6411 prev_index = curr_index;
6414 ranks[reorder_idx[i]] = temp_ranks[j-1];
6425 size_t * cells,
size_t count,
int * ranks) {
6428 dist_grid, proc_sphere_part, cells,
count, ranks,
6435 size_t * edges,
size_t count,
int * ranks) {
6438 dist_grid, proc_sphere_part, edges,
count, ranks,
6451 void (*determine_dist_owner[3])(
6454 size_t * cells,
size_t count,
int * ranks) =
6458 determine_dist_owner[location](
6472 orig_owners = dist_grid->
owners[location];
6474 for (
size_t i = 0; i <
count; ++i) {
6479 int curr_count = curr_orig_owner->
count;
6480 if (curr_count == 1) {
6484 for (
int j = 1; j < curr_count; ++j) {
6486 if (min_rank > curr_rank) min_rank = curr_rank;
6489 ranks[i] = min_rank;
6495 char const * grid_name_a,
size_t ** points_a,
enum yac_location location_a,
6496 char const * grid_name_b,
size_t ** points_b,
enum yac_location location_b,
6497 double ** weights,
size_t *
count) {
6499 size_t count_ = *
count;
6501 MPI_Comm comm = grid_pair->
comm;
6502 int comm_rank, comm_size;
6507 int weight_flag_local =
6508 (count_ > 0) && (weights != NULL) && (*weights != NULL);
6510 yac_mpi_call(MPI_Allreduce(&weight_flag_local, &weight_flag, 1,
6511 MPI_INT, MPI_MAX, comm), comm);
6515 (count_ <= 0) || weight_flag_local || !weight_flag,
6516 "ERROR(yac_dist_grid_pair_relocate_point_pairs): weights")
6519 int * ranks =
xmalloc(count_ *
sizeof(ranks));
6520 size_t * reorder_idx =
xmalloc(count_ *
sizeof(reorder_idx));
6522 char const * grid_name = (a_is_ref)?grid_name_a:grid_name_b;
6523 size_t *
points = (a_is_ref)?*points_a:*points_b;
6524 enum yac_location location = (a_is_ref)?location_a:location_b;
6527 grid_pair, grid_name,
points, count_, location, ranks);
6530 grid_pair, grid_name,
points, count_, location, ranks);
6532 for (
size_t i = 0; i < count_; ++i) reorder_idx[i] = i;
6535 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
6537 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
6538 for (
size_t i = 0; i < count_; ++i) sendcounts[ranks[i]]++;
6540 size_t local_count = sendcounts[comm_rank];
6541 sendcounts[comm_rank] = 0;
6544 1, sendcounts, recvcounts, sdispls, rdispls, comm);
6546 size_t send_count = sdispls[comm_size] + sendcounts[comm_size-1];
6547 size_t recv_count = rdispls[comm_size-1] + recvcounts[comm_size-1];
6550 xmalloc((send_count + recv_count) *
6551 sizeof(*single_remote_point_buffer));
6556 MPI_Datatype single_remote_point_dt =
6560 points_a, reorder_idx, ranks, count_, location_a,
6561 local_count, recv_count, id_send_buffer, id_recv_buffer,
6562 sendcounts, sdispls + 1, recvcounts, rdispls,
6563 single_remote_point_dt, comm,
6566 points_b, reorder_idx, ranks, count_, location_b,
6567 local_count, recv_count, id_send_buffer, id_recv_buffer,
6568 sendcounts, sdispls + 1, recvcounts, rdispls,
6569 single_remote_point_dt, comm,
6571 yac_mpi_call(MPI_Type_free(&single_remote_point_dt), comm);
6575 weights, reorder_idx, ranks, count_,
6576 send_count, local_count, recv_count,
6577 sendcounts, sdispls + 1, recvcounts, rdispls, comm);
6580 free(single_remote_point_buffer);
6584 *count = local_count + recv_count;
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)
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)
static MPI_Datatype yac_get_id_reorder_coord_coord_mpi_datatype(MPI_Comm comm)
static Xt_xmap generate_xmap_data(struct remote_point_infos *point_infos, size_t count, 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)
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))
static int * determine_edge_owner_mask(struct yac_dist_grid *dist_grid, int *vertex_owner_mask)
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 struct yac_dist_grid generate_dist_grid(struct proc_sphere_part_node *proc_sphere_part, struct yac_basic_grid *grid, MPI_Comm comm)
static int compare_id_reorder_coord_coord(const void *a, const void *b)
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)
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 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)
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 void setup_search_data(struct yac_dist_grid_pair *dist_grid_pair)
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)
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 int * generate_vertex_ids(struct proc_sphere_part_node *proc_sphere_part, struct yac_basic_grid_data *grid, MPI_Comm comm)
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)
static void generate_ce_ids(struct yac_basic_grid *grid, int *vertex_ranks, int max_num_vertices_per_cell, MPI_Comm comm)
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 MPI_Datatype yac_get_id_reorder_coord_id_mpi_datatype(MPI_Comm comm)
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 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)
static void generate_global_ids(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)
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)
static struct proc_sphere_part_node * generate_dist_grid_decomposition(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, MPI_Comm comm)
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_id_reorder_coord_reorder_idx(const void *a, const void *b)
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 int compare_coords(double const *a, double const *b)
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
#define xrealloc(ptr, size)
#define xcalloc(nmemb, size)
struct proc_sphere_part_node * yac_redistribute_vertices(struct dist_vertex **vertices, size_t *num_vertices, MPI_Comm comm)
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_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_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
struct missing_edge_neighbour::@0 cell
struct missing_edge_neighbour::@0 edge
single location information of a point
location information about a point that is located on one or
union remote_point_infos::@46 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
size_t * cell_to_vertex_offsets
int * num_vertices_per_cell
const yac_const_coordinate_pointer vertex_coordinates
const_size_t_pointer cell_to_vertex_offsets
const_size_t_pointer cell_to_vertex
const const_int_pointer num_vertices_per_cell
const_size_t_pointer cell_to_edge
const const_yac_int_pointer ids[3]
const_size_t_pointer cell_to_edge_offsets
const_yac_edge_type_pointer edge_type
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)
static struct user_input_data_points ** points
#define YAC_ASSERT_F(exp, format,...)
#define YAC_ASSERT(exp, msg)
void yac_generate_alltoallv_args(int count, size_t const *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls, MPI_Comm comm)
void yac_free_comm_buffers(size_t *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls)
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]