17 #include <deal.II/base/mpi.h> 18 #include <deal.II/base/utilities.h> 19 #include <deal.II/base/exceptions.h> 20 #include <deal.II/lac/vector_memory.h> 21 #include <deal.II/lac/parallel_vector.h> 22 #include <deal.II/lac/parallel_block_vector.h> 23 #include <deal.II/base/multithread_info.h> 28 #ifdef DEAL_II_WITH_TRILINOS 29 # ifdef DEAL_II_WITH_MPI 30 # include <Epetra_MpiComm.h> 31 # include <deal.II/lac/vector_memory.h> 32 # include <deal.II/lac/trilinos_vector.h> 33 # include <deal.II/lac/trilinos_block_vector.h> 37 #ifdef DEAL_II_WITH_PETSC 38 # ifdef DEAL_II_WITH_MPI 39 # include <petscsys.h> 40 # include <deal.II/lac/petsc_block_vector.h> 41 # include <deal.II/lac/petsc_parallel_block_vector.h> 42 # include <deal.II/lac/petsc_vector.h> 43 # include <deal.II/lac/petsc_parallel_vector.h> 47 #ifdef DEAL_II_WITH_SLEPC 48 # ifdef DEAL_II_WITH_MPI 49 # include <slepcsys.h> 53 #ifdef DEAL_II_WITH_P4EST 54 # include <p4est_bits.h> 57 DEAL_II_NAMESPACE_OPEN
65 #ifdef DEAL_II_WITH_MPI 102 (void) MPI_Comm_size (mpi_communicator, &n_jobs);
111 (void) MPI_Comm_rank (mpi_communicator, &rank);
119 MPI_Comm new_communicator;
120 MPI_Comm_dup (mpi_communicator, &new_communicator);
121 return new_communicator;
125 std::vector<unsigned int>
127 const std::vector<unsigned int> &destinations)
132 for (
unsigned int i=0; i<destinations.size(); ++i)
134 Assert (destinations[i] < n_procs,
135 ExcIndexRange (destinations[i], 0, n_procs));
136 Assert (destinations[i] != myid,
137 ExcMessage (
"There is no point in communicating with ourselves."));
145 const unsigned int max_n_destinations
148 if (max_n_destinations==0)
150 return std::vector<unsigned int>();
159 std::vector<unsigned int> my_destinations(max_n_destinations,
161 std::copy (destinations.begin(), destinations.end(),
162 my_destinations.begin());
173 std::vector<unsigned int> all_destinations (max_n_destinations * n_procs);
174 MPI_Allgather (&my_destinations[0], max_n_destinations, MPI_UNSIGNED,
175 &all_destinations[0], max_n_destinations, MPI_UNSIGNED,
182 std::vector<unsigned int> origins;
183 for (
unsigned int i=0; i<n_procs; ++i)
184 for (
unsigned int j=0; j<max_n_destinations; ++j)
185 if (all_destinations[i*max_n_destinations + j] == myid)
186 origins.push_back (i);
187 else if (all_destinations[i*max_n_destinations + j] ==
198 void max_reduce (
const void *in_lhs_,
207 Assert(*len==1, ExcInternalError());
209 inout_rhs->sum += in_lhs->sum;
210 if (inout_rhs->min>in_lhs->min)
212 inout_rhs->min = in_lhs->min;
213 inout_rhs->min_index = in_lhs->min_index;
215 else if (inout_rhs->min == in_lhs->min)
218 if (inout_rhs->min_index > in_lhs->min_index)
219 inout_rhs->min_index = in_lhs->min_index;
222 if (inout_rhs->max < in_lhs->max)
224 inout_rhs->max = in_lhs->max;
225 inout_rhs->max_index = in_lhs->max_index;
227 else if (inout_rhs->max == in_lhs->max)
230 if (inout_rhs->max_index > in_lhs->max_index)
231 inout_rhs->max_index = in_lhs->max_index;
240 const MPI_Comm &mpi_communicator)
247 result.sum = my_value;
248 result.avg = my_value;
249 result.min = my_value;
250 result.max = my_value;
251 result.min_index = 0;
252 result.max_index = 0;
259 MinMaxAvg result = { 0., std::numeric_limits<double>::max(),
260 -std::numeric_limits<double>::max(), 0, 0, 0.
263 const unsigned int my_id
264 = ::Utilities::MPI::this_mpi_process(mpi_communicator);
265 const unsigned int numproc
266 = ::Utilities::MPI::n_mpi_processes(mpi_communicator);
269 int ierr = MPI_Op_create((MPI_User_function *)&max_reduce,
true, &op);
270 AssertThrow(ierr == MPI_SUCCESS, ExcInternalError());
273 in.sum = in.min = in.max = my_value;
274 in.min_index = in.max_index = my_id;
277 int lengths[]= {3,2};
278 MPI_Aint displacements[]= {0,offsetof(
MinMaxAvg, min_index)};
279 MPI_Datatype
types[]= {MPI_DOUBLE, MPI_INT};
281 ierr = MPI_Type_struct(2, lengths, displacements, types, &type);
282 AssertThrow(ierr == MPI_SUCCESS, ExcInternalError());
284 ierr = MPI_Type_commit(&type);
285 ierr = MPI_Allreduce (&in, &result, 1, type, op, mpi_communicator);
286 AssertThrow(ierr == MPI_SUCCESS, ExcInternalError());
288 ierr = MPI_Type_free (&type);
289 AssertThrow(ierr == MPI_SUCCESS, ExcInternalError());
291 ierr = MPI_Op_free(&op);
292 AssertThrow(ierr == MPI_SUCCESS, ExcInternalError());
294 result.avg = result.sum / numproc;
316 return mpi_communicator;
327 result.sum = my_value;
328 result.avg = my_value;
329 result.min = my_value;
330 result.max = my_value;
331 result.min_index = 0;
332 result.max_index = 0;
343 const unsigned int max_num_threads)
345 static bool constructor_has_already_run =
false;
346 (void)constructor_has_already_run;
347 Assert (constructor_has_already_run ==
false,
348 ExcMessage (
"You can only create a single object of this class " 349 "in a program since it initializes the MPI system."));
353 #ifdef DEAL_II_WITH_MPI 356 int MPI_has_been_started = 0;
357 MPI_Initialized(&MPI_has_been_started);
359 ExcMessage (
"MPI error. You can only start MPI once!"));
361 int mpi_err, provided;
366 int wanted = MPI_THREAD_SERIALIZED;
367 mpi_err = MPI_Init_thread(&argc, &argv, wanted, &provided);
369 ExcMessage (
"MPI could not be initialized."));
383 #ifdef DEAL_II_WITH_PETSC 384 # ifdef DEAL_II_WITH_SLEPC 386 SlepcInitialize(&argc, &argv, PETSC_NULL, PETSC_NULL);
389 PetscInitialize(&argc, &argv, PETSC_NULL, PETSC_NULL);
393 #ifdef DEAL_II_WITH_P4EST 395 sc_init(MPI_COMM_WORLD, 0, 0, NULL, SC_LP_SILENT);
396 p4est_init (0, SC_LP_SILENT);
399 constructor_has_already_run =
true;
413 #ifdef DEAL_II_WITH_MPI 425 std::vector<char> hostname_array (max_hostname_size);
426 std::copy (hostname.c_str(), hostname.c_str()+hostname.size()+1,
427 hostname_array.begin());
429 std::vector<char> all_hostnames(max_hostname_size *
431 MPI_Allgather (&hostname_array[0], max_hostname_size, MPI_CHAR,
432 &all_hostnames[0], max_hostname_size, MPI_CHAR,
437 unsigned int n_local_processes=0;
438 unsigned int nth_process_on_host = 0;
440 if (std::string (&all_hostnames[0] + i*max_hostname_size) == hostname)
444 ++nth_process_on_host;
446 Assert (nth_process_on_host > 0, ExcInternalError());
455 const unsigned int n_threads
482 #ifdef DEAL_II_WITH_MPI 486 ::release_unused_memory ();
488 ::release_unused_memory ();
490 ::release_unused_memory ();
492 ::release_unused_memory ();
495 # if defined(DEAL_II_WITH_TRILINOS) 506 #ifdef DEAL_II_WITH_PETSC 507 if ((PetscInitializeCalled == PETSC_TRUE)
509 (PetscFinalizeCalled == PETSC_FALSE))
520 # ifdef DEAL_II_WITH_SLEPC 530 #ifdef DEAL_II_WITH_P4EST 540 #ifdef DEAL_II_WITH_MPI 543 if (std::uncaught_exception())
545 std::cerr <<
"ERROR: Uncaught exception in MPI_InitFinalize on proc " 547 <<
". Skipping MPI_Finalize() to avoid a deadlock." 552 const int mpi_err = MPI_Finalize();
554 ExcMessage (
"An error occurred while calling MPI_Finalize()"));
565 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
static void release_unused_memory()
::ExceptionBase & ExcMessage(std::string arg1)
static unsigned int n_cores()
MPI_InitFinalize(int &argc, char **&argv, const unsigned int max_num_threads=numbers::invalid_unsigned_int)
#define AssertThrow(cond, exc)
#define Assert(cond, exc)
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
std::string get_hostname()
MPI_Comm duplicate_communicator(const MPI_Comm &mpi_communicator)
static void set_thread_limit(const unsigned int max_threads=numbers::invalid_unsigned_int)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
MinMaxAvg min_max_avg(const double my_value, const MPI_Comm &mpi_communicator)
std::vector< unsigned int > compute_point_to_point_communication_pattern(const MPI_Comm &mpi_comm, const std::vector< unsigned int > &destinations)
T max(const T &t, const MPI_Comm &mpi_communicator)