Reference documentation for deal.II version Git 73c87d96ef 2021-11-30 22:54:44 +0100
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
mpi_consensus_algorithms.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2020 - 2021 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_mpi_consensus_algorithm_h
17 #define dealii_mpi_consensus_algorithm_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/mpi.h>
22 #include <deal.II/base/mpi.templates.h>
23 
25 
26 
27 namespace Utilities
28 {
29  namespace MPI
30  {
37  namespace ConsensusAlgorithms
38  {
61  template <typename T1, typename T2>
62  class Process
63  {
64  public:
68  virtual ~Process() = default;
69 
76  virtual std::vector<unsigned int>
77  compute_targets() = 0;
78 
88  virtual void
89  create_request(const unsigned int other_rank,
90  std::vector<T1> & send_buffer);
91 
102  virtual void
103  prepare_buffer_for_answer(const unsigned int other_rank,
104  std::vector<T2> & recv_buffer);
105 
118  virtual void
119  answer_request(const unsigned int other_rank,
120  const std::vector<T1> &buffer_recv,
121  std::vector<T2> & request_buffer);
122 
130  virtual void
131  read_answer(const unsigned int other_rank,
132  const std::vector<T2> &recv_buffer);
133  };
134 
135 
136 
165  template <typename T1, typename T2>
166  class Interface
167  {
168  public:
169  Interface(Process<T1, T2> &process, const MPI_Comm &comm);
170 
174  virtual ~Interface() = default;
175 
179  virtual std::vector<unsigned int>
180  run() = 0;
181 
182  protected:
187 
191  const MPI_Comm &comm;
192 
196  const bool job_supports_mpi;
197 
201  const unsigned int my_rank;
202 
206  const unsigned int n_procs;
207  };
208 
209 
224  template <typename T1, typename T2>
225  class NBX : public Interface<T1, T2>
226  {
227  public:
234  NBX(Process<T1, T2> &process, const MPI_Comm &comm);
235 
239  virtual ~NBX() = default;
240 
244  virtual std::vector<unsigned int>
245  run() override;
246 
247  private:
248 #ifdef DEAL_II_WITH_MPI
249 
252  std::vector<unsigned int> targets;
253 
257  std::vector<std::vector<T1>> send_buffers;
258 
262  std::vector<MPI_Request> send_requests;
263 
267  std::vector<std::vector<T2>> recv_buffers;
268 
269 
273  std::vector<MPI_Request> recv_requests;
274 
278  std::vector<std::unique_ptr<std::vector<T2>>> request_buffers;
279 
283  std::vector<std::unique_ptr<MPI_Request>> request_requests;
284 
285  // request for barrier
287 #endif
288 
292  std::set<unsigned int> requesting_processes;
293 
297  bool
298  check_own_state();
299 
304  void
305  signal_finish();
306 
311  bool
312  check_global_state();
313 
318  void
319  answer_requests();
320 
325  void
326  start_communication();
327 
332  void
333  clean_up_and_end_communication();
334  };
335 
358  template <typename T1, typename T2>
359  class PEX : public Interface<T1, T2>
360  {
361  public:
368  PEX(Process<T1, T2> &process, const MPI_Comm &comm);
369 
373  virtual ~PEX() = default;
374 
378  virtual std::vector<unsigned int>
379  run() override;
380 
381  private:
382 #ifdef DEAL_II_WITH_MPI
383 
386  std::vector<unsigned int> targets;
387 
391  std::vector<unsigned int> sources;
392 
393  // data structures to send and receive requests
394 
398  std::vector<std::vector<T1>> send_buffers;
399 
403  std::vector<std::vector<T2>> recv_buffers;
404 
408  std::vector<MPI_Request> send_and_recv_buffers;
409 
413  std::vector<std::vector<T2>> requests_buffers;
414 
418  std::vector<MPI_Request> requests_answers;
419 #endif
420 
423  std::set<unsigned int> requesting_processes;
424 
429  void
430  answer_requests(int index);
431 
436  unsigned int
437  start_communication();
438 
443  void
444  clean_up_and_end_communication();
445  };
446 
451  template <typename T1, typename T2>
452  class Serial : public Interface<T1, T2>
453  {
454  public:
461  Serial(Process<T1, T2> &process, const MPI_Comm &comm);
462 
466  virtual std::vector<unsigned int>
467  run() override;
468  };
469 
480  template <typename T1, typename T2>
481  class Selector : public Interface<T1, T2>
482  {
483  public:
490  Selector(Process<T1, T2> &process, const MPI_Comm &comm);
491 
495  virtual ~Selector() = default;
496 
502  virtual std::vector<unsigned int>
503  run() override;
504 
505  private:
506  // Pointer to the actual ConsensusAlgorithms::Interface implementation.
507  std::shared_ptr<Interface<T1, T2>> consensus_algo;
508  };
509 
516  template <typename T1, typename T2>
517  class AnonymousProcess : public Process<T1, T2>
518  {
519  public:
532  const std::function<std::vector<unsigned int>()>
533  &function_compute_targets,
534  const std::function<void(const unsigned int, std::vector<T1> &)>
535  &function_create_request =
536  [](const unsigned int, std::vector<T1> &) {},
537  const std::function<void(const unsigned int,
538  const std::vector<T1> &,
539  std::vector<T2> &)>
540  &function_answer_request = [](const unsigned int,
541  const std::vector<T1> &,
542  std::vector<T2> &) {},
543  const std::function<void(const unsigned int, std::vector<T2> &)>
544  &function_prepare_buffer_for_answer =
545  [](const unsigned int, std::vector<T2> &) {},
546  const std::function<void(const unsigned int, const std::vector<T2> &)>
547  &function_read_answer =
548  [](const unsigned int, const std::vector<T2> &) {});
549 
553  std::vector<unsigned int>
554  compute_targets() override;
555 
559  void
560  create_request(const unsigned int other_rank,
561  std::vector<T1> & send_buffer) override;
562 
566  void
567  answer_request(const unsigned int other_rank,
568  const std::vector<T1> &buffer_recv,
569  std::vector<T2> & request_buffer) override;
570 
574  void
575  prepare_buffer_for_answer(const unsigned int other_rank,
576  std::vector<T2> & recv_buffer) override;
577 
581  void
582  read_answer(const unsigned int other_rank,
583  const std::vector<T2> &recv_buffer) override;
584 
585  private:
586  const std::function<std::vector<unsigned int>()>
587  function_compute_targets;
588  const std::function<void(const int, std::vector<T1> &)>
589  function_create_request;
590  const std::function<
591  void(const unsigned int, const std::vector<T1> &, std::vector<T2> &)>
593  const std::function<void(const int, std::vector<T2> &)>
594  function_prepare_buffer_for_answer;
595  const std::function<void(const int, const std::vector<T2> &)>
596  function_read_answer;
597  };
598 
599 
600 
601  template <typename T1, typename T2>
603  const std::function<std::vector<unsigned int>()>
604  &function_compute_targets,
605  const std::function<void(const unsigned int, std::vector<T1> &)>
606  & function_create_request,
607  const std::function<void(const unsigned int,
608  const std::vector<T1> &,
609  std::vector<T2> &)> &function_answer_request,
610  const std::function<void(const unsigned int, std::vector<T2> &)>
611  &function_prepare_buffer_for_answer,
612  const std::function<void(const unsigned int, const std::vector<T2> &)>
613  &function_read_answer)
614  : function_compute_targets(function_compute_targets)
615  , function_create_request(function_create_request)
616  , function_answer_request(function_answer_request)
617  , function_prepare_buffer_for_answer(function_prepare_buffer_for_answer)
618  , function_read_answer(function_read_answer)
619  {}
620 
621 
622 
623  template <typename T1, typename T2>
624  std::vector<unsigned int>
626  {
627  return function_compute_targets();
628  }
629 
630 
631 
632  template <typename T1, typename T2>
633  void
634  AnonymousProcess<T1, T2>::create_request(const unsigned int other_rank,
635  std::vector<T1> & send_buffer)
636  {
637  function_create_request(other_rank, send_buffer);
638  }
639 
640 
641 
642  template <typename T1, typename T2>
643  void
645  const unsigned int other_rank,
646  const std::vector<T1> &buffer_recv,
647  std::vector<T2> & request_buffer)
648  {
649  function_answer_request(other_rank, buffer_recv, request_buffer);
650  }
651 
652 
653 
654  template <typename T1, typename T2>
655  void
657  const unsigned int other_rank,
658  std::vector<T2> & recv_buffer)
659  {
660  function_prepare_buffer_for_answer(other_rank, recv_buffer);
661  }
662 
663 
664 
665  template <typename T1, typename T2>
666  void
667  AnonymousProcess<T1, T2>::read_answer(const unsigned int other_rank,
668  const std::vector<T2> &recv_buffer)
669  {
670  function_read_answer(other_rank, recv_buffer);
671  }
672 
673 
674 
675  } // namespace ConsensusAlgorithms
676  } // end of namespace MPI
677 } // end of namespace Utilities
678 
679 
681 
682 #endif
std::vector< std::vector< T2 > > requests_buffers
void answer_request(const unsigned int other_rank, const std::vector< T1 > &buffer_recv, std::vector< T2 > &request_buffer) override
std::vector< std::vector< T1 > > send_buffers
virtual std::vector< unsigned int > compute_targets()=0
void create_request(const unsigned int other_rank, std::vector< T1 > &send_buffer) override
void read_answer(const unsigned int other_rank, const std::vector< T2 > &recv_buffer) override
const std::function< void(const int, std::vector< T2 > &)> function_prepare_buffer_for_answer
virtual void create_request(const unsigned int other_rank, std::vector< T1 > &send_buffer)
std::vector< std::vector< T2 > > recv_buffers
const std::function< void(const int, const std::vector< T2 > &)> function_read_answer
virtual void prepare_buffer_for_answer(const unsigned int other_rank, std::vector< T2 > &recv_buffer)
virtual void answer_request(const unsigned int other_rank, const std::vector< T1 > &buffer_recv, std::vector< T2 > &request_buffer)
const std::function< void(const int, std::vector< T1 > &)> function_create_request
const std::function< void(const unsigned int, const std::vector< T1 > &, std::vector< T2 > &)> function_answer_request
const std::function< std::vector< unsigned int >)> function_compute_targets
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:401
std::shared_ptr< Interface< T1, T2 > > consensus_algo
virtual void read_answer(const unsigned int other_rank, const std::vector< T2 > &recv_buffer)
std::vector< std::vector< T1 > > send_buffers
std::vector< std::vector< T2 > > recv_buffers
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:400
const MPI_Comm & comm
std::vector< std::unique_ptr< std::vector< T2 > > > request_buffers
AnonymousProcess(const std::function< std::vector< unsigned int >()> &function_compute_targets, const std::function< void(const unsigned int, std::vector< T1 > &)> &function_create_request=[](const unsigned int, std::vector< T1 > &) {}, const std::function< void(const unsigned int, const std::vector< T1 > &, std::vector< T2 > &)> &function_answer_request=[](const unsigned int, const std::vector< T1 > &, std::vector< T2 > &) {}, const std::function< void(const unsigned int, std::vector< T2 > &)> &function_prepare_buffer_for_answer=[](const unsigned int, std::vector< T2 > &) {}, const std::function< void(const unsigned int, const std::vector< T2 > &)> &function_read_answer=[](const unsigned int, const std::vector< T2 > &) {})
std::vector< std::unique_ptr< MPI_Request > > request_requests
void prepare_buffer_for_answer(const unsigned int other_rank, std::vector< T2 > &recv_buffer) override
void run(const Iterator &begin, const typename identity< Iterator >::type &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
Definition: work_stream.h:691