252 const char * filename, MPI_Comm comm,
int * nbr_vertices,
int * nbr_cells,
253 int ** num_vertices_per_cell,
int **
cell_to_vertex,
int ** global_cell_ids,
254 int ** cell_owner,
int ** global_vertex_ids,
int ** vertex_owner,
255 double ** x_vertices,
double ** y_vertices,
256 double ** x_cells,
double ** y_cells,
int ** cell_msk) {
259 ((x_cells == NULL) && (y_cells == NULL)) ||
260 ((x_cells != NULL) && (y_cells != NULL)),
261 "arguments x_cells and y_cells have to be either both NULL or "
262 "both different from NULL");
264 const int with_cell_coords = x_cells != NULL;
265 const int with_cell_mask = cell_msk != NULL;
267 int comm_rank, comm_size;
269 MPI_Comm_rank(comm, &comm_rank);
270 MPI_Comm_size(comm, &comm_size);
272 int local_is_io, * io_ranks, num_io_ranks;
275 size_t ncells, nvertices, nv, ne;
277 size_t read_local_start_cell = 0;
278 size_t read_num_local_cells = 0;
279 size_t read_local_start_vertex = 0;
280 size_t read_num_local_vertices = 0;
281 double * read_cell_lon = NULL;
282 double * read_cell_lat = NULL;
283 int * read_cell_mask = NULL;
284 double * read_vertex_lon = NULL;
285 double * read_vertex_lat = NULL;
286 int * read_dist_vertex_of_cell = NULL;
287 int * read_dist_cells_of_vertex = NULL;
291 unsigned long io_proc_idx = ULONG_MAX;
292 for (
int i = 0; (i < num_io_ranks) && (io_proc_idx == ULONG_MAX); ++i)
293 if (io_ranks[i] == comm_rank)
294 io_proc_idx = (
unsigned long)i;
312 read_local_start_cell =
313 ((
unsigned long)ncells * io_proc_idx) / (
unsigned long)num_io_ranks;
314 read_num_local_cells =
315 ((
unsigned long)ncells * (io_proc_idx+1)) / (
unsigned long)num_io_ranks -
316 (
unsigned long)read_local_start_cell;
317 read_local_start_vertex =
318 ((
unsigned long)nvertices * io_proc_idx) / (
unsigned long)num_io_ranks;
319 read_num_local_vertices =
320 ((
unsigned long)nvertices * (io_proc_idx+1)) / (
unsigned long)num_io_ranks -
321 (
unsigned long)read_local_start_vertex;
326 xmalloc(read_num_local_cells *
sizeof(*read_cell_lon)):NULL;
329 xmalloc(read_num_local_cells *
sizeof(*read_cell_lat)):NULL;
332 xmalloc(read_num_local_cells *
sizeof(*read_cell_mask)):NULL;
333 read_vertex_lon =
xmalloc(read_num_local_vertices *
sizeof(*read_vertex_lon));
334 read_vertex_lat =
xmalloc(read_num_local_vertices *
sizeof(*read_vertex_lat));
335 read_dist_vertex_of_cell =
336 xmalloc(read_num_local_cells * nv *
sizeof(*read_dist_vertex_of_cell));
337 read_dist_cells_of_vertex =
338 xmalloc(read_num_local_vertices * ne *
sizeof(*read_dist_cells_of_vertex));
340 if (with_cell_coords) {
343 &read_num_local_cells, read_cell_lon));
347 &read_num_local_cells, read_cell_lat));
350 if (with_cell_mask) {
353 &read_num_local_cells, read_cell_mask));
357 &read_num_local_vertices, read_vertex_lon));
358 convert_to_rad(ncid, varid, read_vertex_lon, read_num_local_vertices);
361 &read_num_local_vertices, read_vertex_lat));
362 convert_to_rad(ncid, varid, read_vertex_lat, read_num_local_vertices);
365 ne*read_num_local_vertices) *
sizeof(*
buffer));
367 size_t tmp_start[2] = {0, read_local_start_cell};
368 size_t tmp_count[2] = {nv, read_num_local_cells};
371 for (
size_t i = 0; i < read_num_local_cells; ++i)
372 for (
size_t j = 0; j < nv; ++j)
373 read_dist_vertex_of_cell[i * nv + j] =
374 buffer[i + j * read_num_local_cells];
377 size_t tmp_start[2] = {0, read_local_start_vertex};
378 size_t tmp_count[2] = {ne, read_num_local_vertices};
381 for (
size_t i = 0; i < read_num_local_vertices; ++i)
382 for (
size_t j = 0; j < ne; ++j)
383 read_dist_cells_of_vertex[i * ne + j] =
384 buffer[i + j * read_num_local_vertices];
389 for (
size_t i = 0; i < read_num_local_cells * nv; ++i)
390 if (read_dist_vertex_of_cell[i] > 0) read_dist_vertex_of_cell[i]--;
391 for (
size_t i = 0; i < read_num_local_vertices * ne; ++i)
392 read_dist_cells_of_vertex[i]--;
398 with_cell_coords?
xmalloc(1 *
sizeof(*read_cell_lon)):NULL;
400 with_cell_coords?
xmalloc(1 *
sizeof(*read_cell_lat)):NULL;
402 with_cell_mask?
xmalloc(1 *
sizeof(*read_cell_mask)):NULL;
403 read_vertex_lon =
xmalloc(1 *
sizeof(*read_vertex_lon));
404 read_vertex_lat =
xmalloc(1 *
sizeof(*read_vertex_lat));
405 read_dist_vertex_of_cell =
xmalloc(1 *
sizeof(*read_dist_vertex_of_cell));
406 read_dist_cells_of_vertex =
xmalloc(1 *
sizeof(*read_dist_cells_of_vertex));
413 if (comm_rank == 0) tmp = (int)ncells;
414 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
415 ncells = (size_t)tmp;
416 if (comm_rank == 0) tmp = (int)nvertices;
417 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
418 nvertices = (size_t)tmp;
419 if (comm_rank == 0) tmp = (int)nv;
420 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
422 if (comm_rank == 0) tmp = (int)ne;
423 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
428 size_t local_start_cell =
429 ((
unsigned long)ncells * (
unsigned long)comm_rank) /
430 (
unsigned long)comm_size;
431 size_t num_local_cells =
432 ((
unsigned long)ncells * ((
unsigned long)comm_rank+1)) /
433 (
unsigned long)comm_size - (
unsigned long)local_start_cell;
434 size_t local_start_vertex =
435 ((
unsigned long)nvertices * (
unsigned long)comm_rank) /
436 (
unsigned long)comm_size;
437 size_t num_local_vertices =
438 ((
unsigned long)nvertices * ((
unsigned long)comm_rank+1)) /
439 (
unsigned long)comm_size - (
unsigned long)local_start_vertex;
448 int * dist_vertex_of_cell =
449 xmalloc(num_local_cells * nv *
sizeof(*dist_vertex_of_cell));
451 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
452 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
454 for (
size_t i = 0; i < read_num_local_cells; ++i)
457 read_local_start_cell + i, ncells, comm_size)]++;
459 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
461 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
462 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
463 int send_accum = 0, recv_accum = 0;
464 for (
int i = 0; i < comm_size; ++i) {
465 send_displ[i] = send_accum;
466 recv_displ[i] = recv_accum;
467 send_accum += send_count[i];
468 recv_accum += recv_count[i];
471 if (with_cell_coords) {
472 MPI_Alltoallv(read_cell_lon, send_count, send_displ, MPI_DOUBLE,
473 cell_lon, recv_count, recv_displ, MPI_DOUBLE, comm);
474 MPI_Alltoallv(read_cell_lat, send_count, send_displ, MPI_DOUBLE,
475 cell_lat, recv_count, recv_displ, MPI_DOUBLE, comm);
477 if (with_cell_mask) {
478 MPI_Alltoallv(read_cell_mask, send_count, send_displ, MPI_INT,
479 cell_mask, recv_count, recv_displ, MPI_INT, comm);
482 for (
int i = 0; i < comm_size; ++i) {
489 MPI_Alltoallv(read_dist_vertex_of_cell, send_count, send_displ, MPI_INT,
490 dist_vertex_of_cell, recv_count, recv_displ, MPI_INT, comm);
498 free(read_cell_mask);
499 free(read_dist_vertex_of_cell);
503 double * vertex_lon =
xmalloc(num_local_vertices *
sizeof(*vertex_lon));
504 double * vertex_lat =
xmalloc(num_local_vertices *
sizeof(*vertex_lat));
505 int * dist_cells_of_vertex =
506 xmalloc(num_local_vertices * ne *
sizeof(*dist_cells_of_vertex));
508 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
509 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
511 for (
size_t i = 0; i < read_num_local_vertices; ++i)
514 read_local_start_vertex + i, nvertices, comm_size)]++;
516 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
518 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
519 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
520 int send_accum = 0, recv_accum = 0;
521 for (
int i = 0; i < comm_size; ++i) {
522 send_displ[i] = send_accum;
523 recv_displ[i] = recv_accum;
524 send_accum += send_count[i];
525 recv_accum += recv_count[i];
528 MPI_Alltoallv(read_vertex_lon, send_count, send_displ, MPI_DOUBLE,
529 vertex_lon, recv_count, recv_displ, MPI_DOUBLE, comm);
530 MPI_Alltoallv(read_vertex_lat, send_count, send_displ, MPI_DOUBLE,
531 vertex_lat, recv_count, recv_displ, MPI_DOUBLE, comm);
533 for (
int i = 0; i < comm_size; ++i) {
540 MPI_Alltoallv(read_dist_cells_of_vertex, send_count, send_displ, MPI_INT,
541 dist_cells_of_vertex, recv_count, recv_displ, MPI_INT, comm);
547 free(read_vertex_lon);
548 free(read_vertex_lat);
549 free(read_dist_cells_of_vertex);
553 size_t num_core_vertices = num_local_cells * nv;
554 int * core_vertices =
xmalloc(num_core_vertices *
sizeof(*core_vertices));
556 memcpy(core_vertices, dist_vertex_of_cell,
557 num_core_vertices *
sizeof(*core_vertices));
561 xrealloc(core_vertices, num_core_vertices *
sizeof(*core_vertices));
565 int * cells_of_vertex_core =
566 xmalloc(num_core_vertices * ne *
sizeof(*cells_of_vertex_core));
567 int * dist_vertex_owner =
568 xmalloc(num_local_vertices *
sizeof(*dist_vertex_owner));
570 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
571 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
573 for (
size_t i = 0; i < num_core_vertices; ++i)
574 send_count[((
unsigned long)(core_vertices[i]) *
575 (
unsigned long)comm_size + (
unsigned long)comm_size - 1) /
576 (
unsigned long)nvertices]++;
578 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
580 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
581 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
582 int send_accum = 0, recv_accum = 0;
583 for (
int i = 0; i < comm_size; ++i) {
584 send_displ[i] = send_accum;
585 recv_displ[i] = recv_accum;
586 send_accum += send_count[i];
587 recv_accum += recv_count[i];
590 int num_core_vertices_remote = 0;
591 for (
int i = 0; i < comm_size; ++i)
592 num_core_vertices_remote += recv_count[i];
594 int * remote_vertex_buffer =
595 xmalloc(num_core_vertices_remote *
sizeof(*remote_vertex_buffer));
597 MPI_Alltoallv(core_vertices, send_count, send_displ, MPI_INT,
598 remote_vertex_buffer, recv_count, recv_displ, MPI_INT, comm);
600 for (
size_t i = 0; i < num_local_vertices; ++i) dist_vertex_owner[i] = -1;
602 for (
int i = 0, j = 0; i < comm_size; ++i)
603 for (
int k = 0; k < recv_count[i]; ++k, ++j)
604 dist_vertex_owner[remote_vertex_buffer[j] - local_start_vertex] = i;
606 int * send_cell_of_vertex =
607 xmalloc(num_core_vertices_remote * ne *
sizeof(*send_cell_of_vertex));
609 for (
int i = 0, l = 0, m = 0; i < comm_size; ++i) {
610 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
611 int idx = remote_vertex_buffer[l] - local_start_vertex;
612 for (
size_t k = 0; k < ne; ++k, ++m)
613 send_cell_of_vertex[m] = dist_cells_of_vertex[idx * ne + k];
616 free(dist_cells_of_vertex);
618 for (
int i = 0; i < comm_size; ++i) {
625 MPI_Alltoallv(send_cell_of_vertex, recv_count, recv_displ, MPI_INT,
626 cells_of_vertex_core, send_count, send_displ, MPI_INT, comm);
628 free(send_cell_of_vertex);
629 free(remote_vertex_buffer);
638 size_t num_halo_cells = 0;
640 int * tmp_cells = cells_of_vertex_core;
641 size_t num_tmp_cells = num_core_vertices * ne;
646 if ((num_tmp_cells > 0) && (tmp_cells[0] == -1)) {
651 halo_cells =
xmalloc((num_tmp_cells - num_local_cells) *
sizeof(*halo_cells));
654 for (; i < num_tmp_cells && tmp_cells[i] < (int)local_start_cell; ++i)
655 halo_cells[num_halo_cells++] = tmp_cells[i];
656 i += num_local_cells;
657 for (; i < num_tmp_cells; ++i) halo_cells[num_halo_cells++] = tmp_cells[i];
659 assert(num_halo_cells == num_tmp_cells - num_local_cells);
661 free(cells_of_vertex_core);
665 size_t num_all_local_vertices = num_halo_cells * nv + num_core_vertices;
666 int * all_cell_to_vertex;
667 int * all_local_vertices =
xrealloc(core_vertices, num_all_local_vertices *
668 sizeof(*all_local_vertices));
669 if (with_cell_coords) {
675 if (with_cell_mask) {
680 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
681 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
683 for (
size_t i = 0; i < num_halo_cells; ++i)
684 send_count[((
unsigned long)(halo_cells[i]) *
685 (
unsigned long)comm_size + (
unsigned long)comm_size - 1) /
686 (
unsigned long)ncells]++;
688 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
690 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
691 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
692 int send_accum = 0, recv_accum = 0;
693 for (
int i = 0; i < comm_size; ++i) {
694 send_displ[i] = send_accum;
695 recv_displ[i] = recv_accum;
696 send_accum += send_count[i];
697 recv_accum += recv_count[i];
700 int num_halo_cells_remote = 0;
701 for (
int i = 0; i < comm_size; ++i)
702 num_halo_cells_remote += recv_count[i];
704 int * remote_halo_cell_buffer =
705 xmalloc(num_halo_cells_remote *
sizeof(*remote_halo_cell_buffer));
707 MPI_Alltoallv(halo_cells, send_count, send_displ, MPI_INT,
708 remote_halo_cell_buffer, recv_count, recv_displ, MPI_INT,
711 int * send_halo_cell_vertices =
712 xmalloc(num_halo_cells_remote * nv *
sizeof(*send_halo_cell_vertices));
713 double * send_cell_lon =
715 xmalloc(num_halo_cells_remote *
sizeof(*send_cell_lon)):NULL;
716 double * send_cell_lat =
718 xmalloc(num_halo_cells_remote *
sizeof(*send_cell_lat)):NULL;
719 int * send_cell_mask =
721 xmalloc(num_halo_cells_remote *
sizeof(*send_cell_mask)):NULL;
723 for (
int i = 0, l = 0, m = 0; i < comm_size; ++i) {
724 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
725 int idx = remote_halo_cell_buffer[l] - local_start_cell;
726 for (
size_t k = 0; k < nv; ++k, ++m)
727 send_halo_cell_vertices[m] = dist_vertex_of_cell[idx * nv + k];
730 if (with_cell_coords) {
731 for (
int i = 0, l = 0; i < comm_size; ++i) {
732 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
733 int idx = remote_halo_cell_buffer[l] - local_start_cell;
739 if (with_cell_mask) {
740 for (
int i = 0, l = 0; i < comm_size; ++i) {
741 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
742 int idx = remote_halo_cell_buffer[l] - local_start_cell;
748 if (with_cell_coords) {
749 MPI_Alltoallv(send_cell_lon, recv_count, recv_displ, MPI_DOUBLE,
750 cell_lon + num_local_cells, send_count, send_displ,
752 MPI_Alltoallv(send_cell_lat, recv_count, recv_displ, MPI_DOUBLE,
753 cell_lat + num_local_cells, send_count, send_displ,
756 if (with_cell_mask) {
757 MPI_Alltoallv(send_cell_mask, recv_count, recv_displ, MPI_INT,
758 cell_mask + num_local_cells, send_count, send_displ,
762 for (
int i = 0; i < comm_size; ++i) {
770 xrealloc(dist_vertex_of_cell, (num_local_cells + num_halo_cells) * nv *
771 sizeof(*all_cell_to_vertex));
773 MPI_Alltoallv(send_halo_cell_vertices, recv_count, recv_displ, MPI_INT,
774 all_cell_to_vertex + num_local_cells * nv, send_count,
775 send_displ, MPI_INT, comm);
777 memcpy(all_local_vertices + num_core_vertices,
778 all_cell_to_vertex + num_local_cells * nv,
779 num_halo_cells * nv *
sizeof(*all_local_vertices));
781 free(send_cell_mask);
784 free(send_halo_cell_vertices);
785 free(remote_halo_cell_buffer);
792 all_local_vertices, num_all_local_vertices, NULL);
797 double * all_vertex_lon =
798 xmalloc(num_all_local_vertices *
sizeof(*all_vertex_lon));
799 double * all_vertex_lat =
800 xmalloc(num_all_local_vertices *
sizeof(*all_vertex_lat));
801 int * all_local_vertices_owner =
802 xmalloc(num_all_local_vertices *
sizeof(*all_local_vertices_owner));
804 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
805 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
807 for (
size_t i = 0; i < num_all_local_vertices; ++i)
808 send_count[((
unsigned long)(all_local_vertices[i]) *
809 (
unsigned long)comm_size + (
unsigned long)comm_size - 1) /
810 (
unsigned long)nvertices]++;
812 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
814 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
815 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
816 int send_accum = 0, recv_accum = 0;
817 for (
int i = 0; i < comm_size; ++i) {
818 send_displ[i] = send_accum;
819 recv_displ[i] = recv_accum;
820 send_accum += send_count[i];
821 recv_accum += recv_count[i];
824 int num_all_local_vertices_remote = 0;
825 for (
int i = 0; i < comm_size; ++i)
826 num_all_local_vertices_remote += recv_count[i];
828 int * remote_vertex_buffer =
829 xmalloc(num_all_local_vertices_remote *
sizeof(*remote_vertex_buffer));
831 MPI_Alltoallv(all_local_vertices, send_count, send_displ, MPI_INT,
832 remote_vertex_buffer, recv_count, recv_displ, MPI_INT, comm);
834 int * send_vertex_owner = remote_vertex_buffer;
835 double * send_vertex_lon =
836 xmalloc(num_all_local_vertices_remote *
sizeof(*send_vertex_lon));
837 double * send_vertex_lat =
838 xmalloc(num_all_local_vertices_remote *
sizeof(*send_vertex_lat));
840 for (
int i = 0, l = 0; i < comm_size; ++i) {
841 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
842 int idx = remote_vertex_buffer[l] - local_start_vertex;
843 send_vertex_owner[l] = dist_vertex_owner[idx];
844 send_vertex_lon[l] = vertex_lon[idx];
845 send_vertex_lat[l] = vertex_lat[idx];
849 free(dist_vertex_owner);
853 MPI_Alltoallv(send_vertex_owner, recv_count, recv_displ, MPI_INT,
854 all_local_vertices_owner, send_count, send_displ, MPI_INT,
856 MPI_Alltoallv(send_vertex_lon, recv_count, recv_displ, MPI_DOUBLE,
857 all_vertex_lon, send_count, send_displ, MPI_DOUBLE, comm);
858 MPI_Alltoallv(send_vertex_lat, recv_count, recv_displ, MPI_DOUBLE,
859 all_vertex_lat, send_count, send_displ, MPI_DOUBLE, comm);
861 free(send_vertex_lat);
862 free(send_vertex_lon);
863 free(send_vertex_owner);
872 size_t vertex_count = nv * (num_local_cells + num_halo_cells);
873 int * permutation =
xmalloc(vertex_count *
sizeof(*permutation));
874 for (
size_t i = 0; i < vertex_count; ++i) permutation[i] = (
int)i;
878 for (
size_t i = 0, j = 0; i < vertex_count; ++i) {
879 while (all_local_vertices[j] != all_cell_to_vertex[i]) ++j;
880 all_cell_to_vertex[i] = (int)j;
887 *nbr_vertices = num_all_local_vertices;
888 *nbr_cells = num_local_cells + num_halo_cells;
890 *num_vertices_per_cell =
891 xmalloc((num_local_cells + num_halo_cells) *
sizeof(**num_vertices_per_cell));
892 for (
size_t i = 0; i < num_local_cells + num_halo_cells; ++i)
893 (*num_vertices_per_cell)[i] = nv;
898 xmalloc((num_local_cells + num_halo_cells) *
sizeof(**global_cell_ids));
899 for (
size_t i = 0; i < num_local_cells; ++i)
900 (*global_cell_ids)[i] = local_start_cell + i;
901 memcpy(*global_cell_ids + num_local_cells, halo_cells,
902 num_halo_cells *
sizeof(*halo_cells));
903 *global_vertex_ids =
xrealloc(all_local_vertices, num_all_local_vertices *
904 sizeof(*all_local_vertices));
907 xmalloc((num_local_cells + num_halo_cells) *
sizeof(**cell_owner));
908 for (
size_t i = 0; i < num_local_cells; ++i)
909 (*cell_owner)[i] = -1;
910 for (
size_t i = 0; i < num_halo_cells; ++i)
911 (*cell_owner)[num_local_cells + i] =
912 ((
unsigned long)(halo_cells[i]) * (
unsigned long)comm_size +
913 (
unsigned long)comm_size - 1) / (
unsigned long)ncells;
916 for (
size_t i = 0; i < num_all_local_vertices; ++i)
917 if (all_local_vertices_owner[i] == comm_rank)
918 all_local_vertices_owner[i] = -1;
919 *vertex_owner = all_local_vertices_owner;
921 *x_vertices = all_vertex_lon;
922 *y_vertices = all_vertex_lat;
923 if (with_cell_coords) {
927 if (with_cell_mask) *cell_msk =
cell_mask;
961 const char * filename, MPI_Comm comm,
962 double ** x_vertices,
double ** y_vertices,
964 size_t *
num_cells,
size_t * num_vertices,
size_t * num_edges,
965 int ** num_vertices_per_cell,
int ** num_cells_per_vertex,
966 size_t **
cell_to_vertex,
size_t ** cell_to_edge,
size_t ** vertex_to_cell,
968 double ** x_cells,
double ** y_cells,
int ** cell_msk) {
971 ((x_cells == NULL) && (y_cells == NULL)) ||
972 ((x_cells != NULL) && (y_cells != NULL)),
973 "arguments x_cells and y_cells have to be either both NULL or "
974 "both different from NULL");
976 const int with_cell_coords = x_cells != NULL;
977 const int with_cell_mask = cell_msk != NULL;
979 int comm_rank, comm_size;
981 MPI_Comm_rank(comm, &comm_rank);
982 MPI_Comm_size(comm, &comm_size);
984 int local_is_io, * io_ranks, num_io_ranks;
987 size_t ncells, nvertices, nedges, nv, ne;
989 size_t read_local_start_cell = 0;
990 size_t read_num_local_cells = 0;
991 size_t read_local_start_vertex = 0;
992 size_t read_num_local_vertices = 0;
993 size_t read_local_start_edge = 0;
994 size_t read_num_local_edges = 0;
995 double * read_cell_lon = NULL;
996 double * read_cell_lat = NULL;
997 int * read_cell_mask = NULL;
998 double * read_vertex_lon = NULL;
999 double * read_vertex_lat = NULL;
1000 int * read_dist_vertex_of_cell = NULL;
1001 int * read_dist_edge_of_cell = NULL;
1002 int * read_dist_edge_vertices = NULL;
1006 unsigned long io_proc_idx = ULONG_MAX;
1007 for (
int i = 0; (i < num_io_ranks) && (io_proc_idx == ULONG_MAX); ++i)
1008 if (io_ranks[i] == comm_rank)
1009 io_proc_idx = (
unsigned long)i;
1029 read_local_start_cell =
1030 ((
unsigned long)ncells * io_proc_idx) / (
unsigned long)num_io_ranks;
1031 read_num_local_cells =
1032 ((
unsigned long)ncells * (io_proc_idx+1)) / (
unsigned long)num_io_ranks -
1033 (
unsigned long)read_local_start_cell;
1034 read_local_start_vertex =
1035 ((
unsigned long)nvertices * io_proc_idx) / (
unsigned long)num_io_ranks;
1036 read_num_local_vertices =
1037 ((
unsigned long)nvertices * (io_proc_idx+1)) / (
unsigned long)num_io_ranks -
1038 (
unsigned long)read_local_start_vertex;
1039 read_local_start_edge =
1040 ((
unsigned long)nedges * io_proc_idx) / (
unsigned long)num_io_ranks;
1041 read_num_local_edges =
1042 ((
unsigned long)nedges * (io_proc_idx+1)) / (
unsigned long)num_io_ranks -
1043 (
unsigned long)read_local_start_edge;
1046 read_vertex_lon =
xmalloc(read_num_local_vertices *
sizeof(*read_vertex_lon));
1047 read_vertex_lat =
xmalloc(read_num_local_vertices *
sizeof(*read_vertex_lat));
1050 xmalloc(read_num_local_cells *
sizeof(*read_cell_lon)):NULL;
1053 xmalloc(read_num_local_cells *
sizeof(*read_cell_lat)):NULL;
1056 xmalloc(read_num_local_cells *
sizeof(*read_cell_mask)):NULL;
1057 read_dist_vertex_of_cell =
1058 xmalloc(read_num_local_cells * nv *
sizeof(*read_dist_vertex_of_cell));
1059 read_dist_edge_of_cell =
1060 xmalloc(read_num_local_cells * nv *
sizeof(*read_dist_edge_of_cell));
1061 read_dist_edge_vertices =
1062 xmalloc(read_num_local_edges * 2 *
sizeof(*read_dist_edge_vertices));
1066 &read_num_local_vertices, read_vertex_lon));
1067 convert_to_rad(ncid, varid, read_vertex_lon, read_num_local_vertices);
1070 &read_num_local_vertices, read_vertex_lat));
1071 convert_to_rad(ncid, varid, read_vertex_lat, read_num_local_vertices);
1072 if (with_cell_coords) {
1076 ncid, varid, &read_local_start_cell,
1077 &read_num_local_cells, read_cell_lon));
1078 convert_to_rad(ncid, varid, read_cell_lon, read_num_local_cells);
1082 ncid, varid, &read_local_start_cell,
1083 &read_num_local_cells, read_cell_lat));
1084 convert_to_rad(ncid, varid, read_cell_lat, read_num_local_cells);
1086 if (read_cell_mask) {
1090 ncid, varid, &read_local_start_cell,
1091 &read_num_local_cells, read_cell_mask));
1096 MAX(nv*read_num_local_cells, 2*read_num_local_edges) *
1099 size_t tmp_start[2] = {0, read_local_start_cell};
1100 size_t tmp_count[2] = {nv, read_num_local_cells};
1103 for (
size_t i = 0; i < read_num_local_cells; ++i)
1104 for (
size_t j = 0; j < nv; ++j)
1105 read_dist_vertex_of_cell[i * nv + j] =
1106 buffer[i + j * read_num_local_cells];
1109 for (
size_t i = 0; i < read_num_local_cells; ++i)
1110 for (
size_t j = 0; j < nv; ++j)
1111 read_dist_edge_of_cell[i * nv + j] =
1112 buffer[i + j * read_num_local_cells];
1115 size_t tmp_start[2] = {0, read_local_start_edge};
1116 size_t tmp_count[2] = {2, read_num_local_edges};
1119 for (
size_t i = 0; i < read_num_local_edges; ++i)
1120 for (
int j = 0; j < 2; ++j)
1121 read_dist_edge_vertices[i * 2 + j] =
1122 buffer[i + j * read_num_local_edges];
1127 for (
size_t i = 0; i < read_num_local_cells * nv; ++i)
1128 if (read_dist_vertex_of_cell[i] > 0) read_dist_vertex_of_cell[i]--;
1129 for (
size_t i = 0; i < read_num_local_cells * nv; ++i)
1130 if (read_dist_edge_of_cell[i] > 0) read_dist_edge_of_cell[i]--;
1131 for (
size_t i = 0; i < read_num_local_edges * 2; ++i)
1132 if (read_dist_edge_vertices[i] > 0) read_dist_edge_vertices[i]--;
1137 read_cell_lon = with_cell_coords?
xmalloc(1 *
sizeof(*read_cell_lon)):NULL;
1138 read_cell_lat = with_cell_coords?
xmalloc(1 *
sizeof(*read_cell_lat)):NULL;
1139 read_cell_mask = with_cell_mask?
xmalloc(1 *
sizeof(*read_cell_mask)):NULL;
1140 read_vertex_lon =
xmalloc(1 *
sizeof(*read_vertex_lon));
1141 read_vertex_lat =
xmalloc(1 *
sizeof(*read_vertex_lat));
1142 read_dist_vertex_of_cell =
xmalloc(1 *
sizeof(*read_dist_vertex_of_cell));
1143 read_dist_edge_of_cell =
xmalloc(1 *
sizeof(*read_dist_edge_of_cell));
1144 read_dist_edge_vertices =
xmalloc(1 *
sizeof(*read_dist_edge_vertices));
1151 if (comm_rank == 0) tmp = (int)ncells;
1152 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
1153 ncells = (size_t)tmp;
1154 if (comm_rank == 0) tmp = (int)nvertices;
1155 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
1156 nvertices = (size_t)tmp;
1157 if (comm_rank == 0) tmp = (int)nedges;
1158 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
1159 nedges = (size_t)tmp;
1160 if (comm_rank == 0) tmp = (int)nv;
1161 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
1163 if (comm_rank == 0) tmp = (int)ne;
1164 MPI_Bcast(&tmp, 1, MPI_INT, 0, comm);
1169 size_t local_start_cell =
1170 ((
unsigned long)ncells * (
unsigned long)comm_rank) /
1171 (
unsigned long)comm_size;
1172 size_t num_local_cells =
1173 ((
unsigned long)ncells * ((
unsigned long)comm_rank+1)) /
1174 (
unsigned long)comm_size - (
unsigned long)local_start_cell;
1175 size_t local_start_vertex =
1176 ((
unsigned long)nvertices * (
unsigned long)comm_rank) /
1177 (
unsigned long)comm_size;
1178 size_t num_local_vertices =
1179 ((
unsigned long)nvertices * ((
unsigned long)comm_rank+1)) /
1180 (
unsigned long)comm_size - (
unsigned long)local_start_vertex;
1181 size_t local_start_edge =
1182 ((
unsigned long)nedges * (
unsigned long)comm_rank) /
1183 (
unsigned long)comm_size;
1184 size_t num_local_edges =
1185 ((
unsigned long)nedges * ((
unsigned long)comm_rank+1)) /
1186 (
unsigned long)comm_size - (
unsigned long)local_start_edge;
1189 if (with_cell_coords) {
1190 *x_cells =
xmalloc(num_local_cells *
sizeof(**x_cells));
1191 *y_cells =
xmalloc(num_local_cells *
sizeof(**y_cells));
1193 if (with_cell_mask) {
1194 *cell_msk =
xmalloc(num_local_cells *
sizeof(**cell_msk));
1196 int * dist_vertex_of_cell =
1197 xmalloc(num_local_cells * nv *
sizeof(*dist_vertex_of_cell));
1198 int * dist_edge_of_cell =
1199 xmalloc(num_local_cells * nv *
sizeof(*dist_edge_of_cell));
1201 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
1202 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
1204 for (
unsigned i = 0; i < read_num_local_cells; ++i)
1207 read_local_start_cell + i, ncells, comm_size)]++;
1209 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
1211 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
1212 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
1213 int send_accum = 0, recv_accum = 0;
1214 for (
int i = 0; i < comm_size; ++i) {
1215 send_displ[i] = send_accum;
1216 recv_displ[i] = recv_accum;
1217 send_accum += send_count[i];
1218 recv_accum += recv_count[i];
1221 if (with_cell_coords) {
1222 MPI_Alltoallv(read_cell_lon, send_count, send_displ, MPI_DOUBLE,
1223 *x_cells, recv_count, recv_displ, MPI_DOUBLE, comm);
1224 MPI_Alltoallv(read_cell_lat, send_count, send_displ, MPI_DOUBLE,
1225 *y_cells, recv_count, recv_displ, MPI_DOUBLE, comm);
1227 if (with_cell_mask) {
1228 MPI_Alltoallv(read_cell_mask, send_count, send_displ, MPI_INT,
1229 *cell_msk, recv_count, recv_displ, MPI_INT, comm);
1232 for (
int i = 0; i < comm_size; ++i) {
1233 send_count[i] *= nv;
1234 send_displ[i] *= nv;
1235 recv_count[i] *= nv;
1236 recv_displ[i] *= nv;
1239 MPI_Alltoallv(read_dist_vertex_of_cell, send_count, send_displ, MPI_INT,
1240 dist_vertex_of_cell, recv_count, recv_displ, MPI_INT, comm);
1241 MPI_Alltoallv(read_dist_edge_of_cell, send_count, send_displ, MPI_INT,
1242 dist_edge_of_cell, recv_count, recv_displ, MPI_INT, comm);
1248 free(read_dist_vertex_of_cell);
1249 free(read_dist_edge_of_cell);
1250 free(read_cell_mask);
1251 free(read_cell_lat);
1252 free(read_cell_lon);
1256 double * vertex_lon =
xmalloc(num_local_vertices *
sizeof(*vertex_lon));
1257 double * vertex_lat =
xmalloc(num_local_vertices *
sizeof(*vertex_lat));
1259 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
1260 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
1262 for (
unsigned i = 0; i < read_num_local_vertices; ++i)
1265 read_local_start_vertex + i, nvertices, comm_size)]++;
1267 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
1269 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
1270 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
1271 int send_accum = 0, recv_accum = 0;
1272 for (
int i = 0; i < comm_size; ++i) {
1273 send_displ[i] = send_accum;
1274 recv_displ[i] = recv_accum;
1275 send_accum += send_count[i];
1276 recv_accum += recv_count[i];
1279 MPI_Alltoallv(read_vertex_lon, send_count, send_displ, MPI_DOUBLE,
1280 vertex_lon, recv_count, recv_displ, MPI_DOUBLE, comm);
1281 MPI_Alltoallv(read_vertex_lat, send_count, send_displ, MPI_DOUBLE,
1282 vertex_lat, recv_count, recv_displ, MPI_DOUBLE, comm);
1288 free(read_vertex_lon);
1289 free(read_vertex_lat);
1293 int * dist_edge_vertices =
1294 xmalloc(num_local_edges * 2 *
sizeof(*dist_edge_vertices));
1296 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
1297 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
1299 for (
unsigned i = 0; i < read_num_local_edges; ++i)
1302 read_local_start_edge + i, nedges, comm_size)] += 2;
1304 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
1306 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
1307 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
1308 int send_accum = 0, recv_accum = 0;
1309 for (
int i = 0; i < comm_size; ++i) {
1310 send_displ[i] = send_accum;
1311 recv_displ[i] = recv_accum;
1312 send_accum += send_count[i];
1313 recv_accum += recv_count[i];
1316 MPI_Alltoallv(read_dist_edge_vertices, send_count, send_displ, MPI_INT,
1317 dist_edge_vertices, recv_count, recv_displ, MPI_INT, comm);
1323 free(read_dist_edge_vertices);
1329 size_t num_core_vertices;
1331 size_t N = num_local_cells * nv;
1332 *vertex_ids =
xmalloc(
N *
sizeof(**vertex_ids));
1333 *num_cells_per_vertex =
xmalloc(
N *
sizeof(**num_cells_per_vertex));
1334 *vertex_to_cell =
xmalloc(
N *
sizeof(**vertex_to_cell));
1336 for (
size_t i = 0; i <
N; ++i)
1337 (*vertex_ids)[i] = (
yac_int)dist_vertex_of_cell[i];
1338 size_t * permutation = *vertex_to_cell;
1339 for (
size_t i = 0; i <
N; ++i) permutation[i] = i;
1342 yac_int prev_vertex_id = YAC_INT_MAX;
1343 num_core_vertices = 0;
1344 for (
size_t i = 0; i <
N; ++i) {
1345 yac_int curr_vertex_id = (*vertex_ids)[i];
1346 if (prev_vertex_id == curr_vertex_id) {
1347 (*num_cells_per_vertex)[num_core_vertices-1]++;
1349 (*num_cells_per_vertex)[num_core_vertices] = 1;
1350 (*vertex_ids)[num_core_vertices] = (prev_vertex_id = curr_vertex_id);
1351 ++num_core_vertices;
1353 (*cell_to_vertex)[permutation[i]] = num_core_vertices-1;
1354 permutation[i] /= nv;
1357 xrealloc(*vertex_ids, num_core_vertices *
sizeof(**vertex_ids));
1358 *num_cells_per_vertex =
1360 num_core_vertices *
sizeof(**num_cells_per_vertex));
1361 free(dist_vertex_of_cell);
1366 size_t num_core_edges;
1368 size_t N = num_local_cells * nv;
1369 *edge_ids =
xmalloc(
N *
sizeof(**edge_ids));
1370 size_t * permutation =
xmalloc(
N *
sizeof(*permutation));
1371 *cell_to_edge =
xmalloc(
N *
sizeof(**cell_to_edge));
1372 for (
size_t i = 0; i <
N; ++i)
1373 (*edge_ids)[i] = (
yac_int)dist_edge_of_cell[i];
1374 for (
size_t i = 0; i <
N; ++i) permutation[i] = i;
1377 yac_int prev_edge_id = YAC_INT_MAX;
1379 for (
size_t i = 0; i <
N; ++i) {
1380 yac_int curr_edge_id = (*edge_ids)[i];
1381 if (prev_edge_id != curr_edge_id)
1382 (*edge_ids)[num_core_edges++] = (prev_edge_id = curr_edge_id);
1383 (*cell_to_edge)[permutation[i]] = num_core_edges-1;
1384 permutation[i] /= nv;
1388 xrealloc(*edge_ids, num_core_edges *
sizeof(**edge_ids));
1389 free(dist_edge_of_cell);
1394 *x_vertices =
xmalloc(num_core_vertices *
sizeof(**x_vertices));
1395 *y_vertices =
xmalloc(num_core_vertices *
sizeof(**y_vertices));
1396 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
1397 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
1399 for (
size_t i = 0; i < num_core_vertices; ++i)
1400 send_count[((
unsigned long)((*vertex_ids)[i]) *
1401 (
unsigned long)comm_size + (
unsigned long)comm_size - 1) /
1402 (
unsigned long)nvertices]++;
1404 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
1406 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
1407 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
1408 int send_accum = 0, recv_accum = 0;
1409 for (
int i = 0; i < comm_size; ++i) {
1410 send_displ[i] = send_accum;
1411 recv_displ[i] = recv_accum;
1412 send_accum += send_count[i];
1413 recv_accum += recv_count[i];
1416 int num_all_local_vertices_remote = 0;
1417 for (
int i = 0; i < comm_size; ++i)
1418 num_all_local_vertices_remote += recv_count[i];
1420 yac_int * remote_vertex_buffer =
1421 xmalloc(num_all_local_vertices_remote *
sizeof(*remote_vertex_buffer));
1424 *vertex_ids, send_count, send_displ,
yac_int_dt,
1425 remote_vertex_buffer, recv_count, recv_displ,
yac_int_dt, comm);
1427 double * send_vertex_lon =
1428 xmalloc(num_all_local_vertices_remote *
sizeof(*send_vertex_lon));
1429 double * send_vertex_lat =
1430 xmalloc(num_all_local_vertices_remote *
sizeof(*send_vertex_lat));
1432 for (
int i = 0, l = 0; i < comm_size; ++i) {
1433 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
1434 size_t idx = (size_t)(remote_vertex_buffer[l]) - local_start_vertex;
1435 send_vertex_lon[l] = vertex_lon[idx];
1436 send_vertex_lat[l] = vertex_lat[idx];
1440 free(remote_vertex_buffer);
1444 MPI_Alltoallv(send_vertex_lon, recv_count, recv_displ, MPI_DOUBLE,
1445 *x_vertices, send_count, send_displ, MPI_DOUBLE, comm);
1446 MPI_Alltoallv(send_vertex_lat, recv_count, recv_displ, MPI_DOUBLE,
1447 *y_vertices, send_count, send_displ, MPI_DOUBLE, comm);
1449 free(send_vertex_lat);
1450 free(send_vertex_lon);
1459 xmalloc(2 * num_core_edges *
sizeof(**edge_to_vertex));
1461 int * local_edge_to_vertex =
1462 xmalloc(2 * num_core_edges *
sizeof(*local_edge_to_vertex));
1463 int * send_count =
xcalloc(comm_size,
sizeof(*send_count));
1464 int * recv_count =
xcalloc(comm_size,
sizeof(*recv_count));
1466 for (
size_t i = 0; i < num_core_edges; ++i)
1467 send_count[((
unsigned long)((*edge_ids)[i]) *
1468 (
unsigned long)comm_size + (
unsigned long)comm_size - 1) /
1469 (
unsigned long)nedges]++;
1471 MPI_Alltoall(send_count, 1, MPI_INT, recv_count, 1, MPI_INT, comm);
1473 int * send_displ =
xmalloc(comm_size *
sizeof(*send_displ));
1474 int * recv_displ =
xmalloc(comm_size *
sizeof(*recv_displ));
1475 int send_accum = 0, recv_accum = 0;
1476 for (
int i = 0; i < comm_size; ++i) {
1477 send_displ[i] = send_accum;
1478 recv_displ[i] = recv_accum;
1479 send_accum += send_count[i];
1480 recv_accum += recv_count[i];
1483 int num_all_local_edges_remote = 0;
1484 for (
int i = 0; i < comm_size; ++i)
1485 num_all_local_edges_remote += recv_count[i];
1487 yac_int * remote_edge_buffer =
1488 xmalloc(num_all_local_edges_remote *
sizeof(*remote_edge_buffer));
1491 *edge_ids, send_count, send_displ,
yac_int_dt,
1492 remote_edge_buffer, recv_count, recv_displ,
yac_int_dt, comm);
1494 int * send_edge_vertices =
1495 xmalloc(2 * num_all_local_edges_remote *
sizeof(*send_edge_vertices));
1497 for (
int i = 0, l = 0; i < comm_size; ++i) {
1498 for (
int j = 0; j < recv_count[i]; ++j, ++l) {
1499 size_t idx = (size_t)(remote_edge_buffer[l]) - local_start_edge;
1500 send_edge_vertices[2*l+0] = dist_edge_vertices[2*idx+0];
1501 send_edge_vertices[2*l+1] = dist_edge_vertices[2*idx+1];
1510 free(remote_edge_buffer);
1511 free(dist_edge_vertices);
1513 MPI_Alltoallv(send_edge_vertices, recv_count, recv_displ, MPI_INT,
1514 local_edge_to_vertex, send_count, send_displ, MPI_INT, comm);
1516 size_t * permutation =
xmalloc(2 * num_core_edges *
sizeof(*permutation));
1517 for (
size_t i = 0; i < 2 * num_core_edges; ++i) permutation[i] = i;
1520 local_edge_to_vertex, 2 * num_core_edges, permutation);
1522 for (
size_t i = 0, j = 0; i < 2 * num_core_edges; ++i) {
1524 while ((j < nvertices) && ((*vertex_ids)[j] < curr_vertex)) ++j;
1526 (j < nvertices) && ((*vertex_ids)[j] == curr_vertex),
1527 "vertex id missmatch")
1528 (*edge_to_vertex)[permutation[i]] = j;
1532 free(send_edge_vertices);
1537 free(local_edge_to_vertex);
1541 *cell_ids =
xmalloc(num_local_cells *
sizeof(**cell_ids));
1542 for (
size_t i = 0; i < num_local_cells; ++i)
1543 (*cell_ids)[i] = (
yac_int)(local_start_cell + i);
1546 *num_vertices_per_cell =
1547 xmalloc(num_local_cells *
sizeof(**num_vertices_per_cell));
1548 for (
size_t i = 0; i < num_local_cells; ++i) (*num_vertices_per_cell)[i] = nv;
1551 *edge_type =
xmalloc(num_core_edges *
sizeof(**edge_type));
1552 for (
size_t i = 0; i < num_core_edges; ++i)
1556 *num_vertices = num_core_vertices;
1557 *num_edges = num_core_edges;