From 77b50d8ab54f4b15a462c72819e454e81eadf4bb Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Sun, 11 Sep 2016 12:48:54 +0200 Subject: [PATCH] Use Bcast --- include/deal.II/base/index_set.h | 9 +++ source/base/index_set.cc | 98 +++++++++++--------------------- 2 files changed, 42 insertions(+), 65 deletions(-) diff --git a/include/deal.II/base/index_set.h b/include/deal.II/base/index_set.h index ea0c8c1013..8d2bc790bc 100644 --- a/include/deal.II/base/index_set.h +++ b/include/deal.II/base/index_set.h @@ -217,6 +217,15 @@ public: */ bool is_contiguous () const; + /** + * Return whether the index set stored by this object defines a linear + * range, i.e., each index is contained in exactly one IndexSet, + * the first indices are contained in the IndexSet of the first MPI process, + * the second indices are contained in the IndexSet of the second MPI process + * and so on. + */ + bool is_linear() const; + /** * Return the number of elements stored in this index set. */ diff --git a/source/base/index_set.cc b/source/base/index_set.cc index 0d117333c3..b3ff1ab4b3 100644 --- a/source/base/index_set.cc +++ b/source/base/index_set.cc @@ -522,78 +522,46 @@ IndexSet::make_trilinos_map (const MPI_Comm &communicator, { is_linear = true; // we know that there is only one interval - types::global_dof_index first_local_dof - = (n_elements()>0) ? *(begin_intervals()->begin()) : numbers::invalid_dof_index ; - types::global_dof_index last_local_dof - = (n_elements()>0) ? begin_intervals()->last() : numbers::invalid_dof_index; + types::global_dof_index local_dofs[2]; + local_dofs[0] = (n_elements()>0) ? *(begin_intervals()->begin()) + : numbers::invalid_dof_index ; + local_dofs[1] = (n_elements()>0) ? begin_intervals()->last() + : numbers::invalid_dof_index; - // sent and receive the elements to the neighbors const unsigned int my_rank = Utilities::MPI::this_mpi_process(communicator); + // first gather all information on process 0 + const unsigned int gather_size = (my_rank==0)?2*n_ranks:1; + std::vector global_dofs(gather_size); + + MPI_Gather(local_dofs, 2, DEAL_II_DOF_INDEX_MPI_TYPE, + &(global_dofs[0]), 2, DEAL_II_DOF_INDEX_MPI_TYPE, 0, + communicator); if (my_rank == 0) { - types::global_dof_index first_neighbor_dof = last_local_dof; - MPI_Status last_send_status, first_recv_status; - MPI_Request last_send_request, first_recv_request; - MPI_Isend(&last_local_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank+1,1,MPI_COMM_WORLD,&last_send_request); - MPI_Irecv(&first_neighbor_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank+1,0,MPI_COMM_WORLD,&first_recv_request); - MPI_Wait(&last_send_request,&last_send_status); - MPI_Wait(&first_recv_request,&first_recv_status); - if (last_local_dof != numbers::invalid_dof_index && - first_neighbor_dof != numbers::invalid_dof_index && - last_local_dof != first_neighbor_dof+1) - is_linear = false; - } - else if (my_rank == n_ranks-1) - { - types::global_dof_index last_neighbor_dof = first_local_dof; - MPI_Status first_send_status, last_recv_status; - MPI_Request first_send_request, last_recv_request; - MPI_Isend(&first_local_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank-1,0,MPI_COMM_WORLD,&first_send_request); - MPI_Irecv(&last_neighbor_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank-1,1,MPI_COMM_WORLD,&last_recv_request); - MPI_Wait(&first_send_request,&first_send_status); - MPI_Wait(&last_recv_request,&last_recv_status); - if (first_local_dof != numbers::invalid_dof_index && - last_neighbor_dof != numbers::invalid_dof_index && - first_local_dof != last_neighbor_dof-1) - is_linear = false; - } - else - { - types::global_dof_index first_neighbor_dof = last_local_dof; - types::global_dof_index last_neighbor_dof = first_local_dof; - MPI_Status first_send_status, last_send_status; - MPI_Status first_recv_status, last_recv_status; - MPI_Request first_send_request, last_send_request; - MPI_Request first_recv_request, last_recv_request; - MPI_Isend(&first_local_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank-1,0,MPI_COMM_WORLD,&first_send_request); - MPI_Isend(&last_local_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank+1,1,MPI_COMM_WORLD,&last_send_request); - MPI_Irecv(&first_neighbor_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank+1,0,MPI_COMM_WORLD,&first_recv_request); - MPI_Irecv(&last_neighbor_dof, 1, DEAL_II_DOF_INDEX_MPI_TYPE, - my_rank-1,1,MPI_COMM_WORLD,&last_recv_request); - MPI_Wait(&first_send_request,&first_send_status); - MPI_Wait(&last_send_request,&last_send_status); - MPI_Wait(&first_recv_request,&first_recv_status); - MPI_Wait(&last_recv_request,&last_recv_status); - if (first_local_dof != numbers::invalid_dof_index && - last_neighbor_dof != numbers::invalid_dof_index && - first_local_dof != last_neighbor_dof-1) - is_linear = false; - if (last_local_dof != numbers::invalid_dof_index && - first_neighbor_dof != numbers::invalid_dof_index && - last_local_dof != first_neighbor_dof+1) - is_linear = false; + // find out if the received std::vector is linear + types::global_dof_index old_dof = global_dofs[0], new_dof = 0; + types::global_dof_index index = 0; + while (global_dofs[index] == numbers::invalid_dof_index) + ++index; + old_dof = global_dofs[index++]; + for (; index