Reference documentation for deal.II version Git b43ef918fe 2022-01-29 10:49:23 +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  {
63  template <typename T1, typename T2>
64  class Process
65  {
66  public:
71  virtual ~Process() = default;
72 
79  virtual std::vector<unsigned int>
80  compute_targets() = 0;
81 
91  virtual void
92  create_request(const unsigned int other_rank,
93  std::vector<T1> & send_buffer);
94 
107  virtual void
108  answer_request(const unsigned int other_rank,
109  const std::vector<T1> &buffer_recv,
110  std::vector<T2> & request_buffer);
111 
119  virtual void
120  read_answer(const unsigned int other_rank,
121  const std::vector<T2> &recv_buffer);
122  };
123 
124 
125 
199  template <typename T1, typename T2>
200  class Interface
201  {
202  public:
209  Interface(Process<T1, T2> &process, const MPI_Comm &comm);
210 
215  virtual ~Interface() = default;
216 
220  virtual std::vector<unsigned int>
221  run() = 0;
222 
223  protected:
228 
232  const MPI_Comm &comm;
233  };
234 
235 
249  template <typename T1, typename T2>
250  class NBX : public Interface<T1, T2>
251  {
252  public:
259  NBX(Process<T1, T2> &process, const MPI_Comm &comm);
260 
264  virtual ~NBX() = default;
265 
269  virtual std::vector<unsigned int>
270  run() override;
271 
272  private:
273 #ifdef DEAL_II_WITH_MPI
274 
277  std::vector<unsigned int> targets;
278 
282  std::vector<std::vector<T1>> send_buffers;
283 
287  std::vector<MPI_Request> send_requests;
288 
296  std::vector<std::unique_ptr<std::vector<T2>>> request_buffers;
297 
301  std::vector<std::unique_ptr<MPI_Request>> request_requests;
302 
306  unsigned int n_outstanding_answers;
307 
308  // request for barrier
310 #endif
311 
315  std::set<unsigned int> requesting_processes;
316 
322  bool
323  all_locally_originated_receives_are_completed();
324 
329  void
330  signal_finish();
331 
337  bool
338  all_remotely_originated_receives_are_completed();
339 
345  void
346  maybe_answer_one_request();
347 
352  void
353  start_communication();
354 
359  void
360  clean_up_and_end_communication();
361  };
362 
388  template <typename T1, typename T2>
389  class PEX : public Interface<T1, T2>
390  {
391  public:
398  PEX(Process<T1, T2> &process, const MPI_Comm &comm);
399 
403  virtual ~PEX() = default;
404 
408  virtual std::vector<unsigned int>
409  run() override;
410 
411  private:
412 #ifdef DEAL_II_WITH_MPI
413 
416  std::vector<unsigned int> targets;
417 
418  // data structures to send and receive requests
419 
423  std::vector<std::vector<T1>> send_buffers;
424 
428  std::vector<std::vector<T2>> recv_buffers;
429 
433  std::vector<MPI_Request> send_request_requests;
434 
438  std::vector<std::vector<T2>> requests_buffers;
439 
443  std::vector<MPI_Request> send_answer_requests;
444 #endif
445 
448  std::set<unsigned int> requesting_processes;
449 
454  unsigned int
455  start_communication();
456 
461  void
462  answer_one_request(const unsigned int index);
463 
468  void
469  process_incoming_answers();
470 
475  void
476  clean_up_and_end_communication();
477  };
478 
479 
480 
485  template <typename T1, typename T2>
486  class Serial : public Interface<T1, T2>
487  {
488  public:
495  Serial(Process<T1, T2> &process, const MPI_Comm &comm);
496 
500  virtual std::vector<unsigned int>
501  run() override;
502  };
503 
504 
505 
518  template <typename T1, typename T2>
519  class Selector : public Interface<T1, T2>
520  {
521  public:
528  Selector(Process<T1, T2> &process, const MPI_Comm &comm);
529 
533  virtual ~Selector() = default;
534 
540  virtual std::vector<unsigned int>
541  run() override;
542 
543  private:
544  // Pointer to the actual ConsensusAlgorithms::Interface implementation.
545  std::shared_ptr<Interface<T1, T2>> consensus_algo;
546  };
547 
548 
549 
556  template <typename T1, typename T2>
557  class AnonymousProcess : public Process<T1, T2>
558  {
559  public:
570  const std::function<std::vector<unsigned int>()>
571  &function_compute_targets,
572  const std::function<void(const unsigned int, std::vector<T1> &)>
573  &function_create_request = {},
574  const std::function<void(const unsigned int,
575  const std::vector<T1> &,
576  std::vector<T2> &)>
577  &function_answer_request = {},
578  const std::function<void(const unsigned int, const std::vector<T2> &)>
579  &function_read_answer = {});
580 
584  std::vector<unsigned int>
585  compute_targets() override;
586 
590  void
591  create_request(const unsigned int other_rank,
592  std::vector<T1> & send_buffer) override;
593 
597  void
598  answer_request(const unsigned int other_rank,
599  const std::vector<T1> &buffer_recv,
600  std::vector<T2> & request_buffer) override;
601 
605  void
606  read_answer(const unsigned int other_rank,
607  const std::vector<T2> &recv_buffer) override;
608 
609  private:
610  const std::function<std::vector<unsigned int>()>
611  function_compute_targets;
612  const std::function<void(const int, std::vector<T1> &)>
613  function_create_request;
614  const std::function<
615  void(const unsigned int, const std::vector<T1> &, std::vector<T2> &)>
617  const std::function<void(const int, const std::vector<T2> &)>
618  function_read_answer;
619  };
620 
621 
622 
623  template <typename T1, typename T2>
625  const std::function<std::vector<unsigned int>()>
626  &function_compute_targets,
627  const std::function<void(const unsigned int, std::vector<T1> &)>
628  & function_create_request,
629  const std::function<void(const unsigned int,
630  const std::vector<T1> &,
631  std::vector<T2> &)> &function_answer_request,
632  const std::function<void(const unsigned int, const std::vector<T2> &)>
633  &function_read_answer)
634  : function_compute_targets(function_compute_targets)
635  , function_create_request(function_create_request)
636  , function_answer_request(function_answer_request)
637  , function_read_answer(function_read_answer)
638  {}
639 
640 
641 
642  template <typename T1, typename T2>
643  std::vector<unsigned int>
645  {
646  return function_compute_targets();
647  }
648 
649 
650 
651  template <typename T1, typename T2>
652  void
653  AnonymousProcess<T1, T2>::create_request(const unsigned int other_rank,
654  std::vector<T1> & send_buffer)
655  {
657  function_create_request(other_rank, send_buffer);
658  }
659 
660 
661 
662  template <typename T1, typename T2>
663  void
665  const unsigned int other_rank,
666  const std::vector<T1> &buffer_recv,
667  std::vector<T2> & request_buffer)
668  {
670  function_answer_request(other_rank, buffer_recv, request_buffer);
671  }
672 
673 
674 
675  template <typename T1, typename T2>
676  void
677  AnonymousProcess<T1, T2>::read_answer(const unsigned int other_rank,
678  const std::vector<T2> &recv_buffer)
679  {
681  function_read_answer(other_rank, recv_buffer);
682  }
683 
684 
685 
686  } // namespace ConsensusAlgorithms
687  } // end of namespace MPI
688 } // end of namespace Utilities
689 
690 
692 
693 #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
virtual void create_request(const unsigned int other_rank, std::vector< T1 > &send_buffer)
const std::function< void(const int, const std::vector< T2 > &)> function_read_answer
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:407
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:406
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 std::function< void(const unsigned int, const std::vector< T1 > &, std::vector< T2 > &)> &function_answer_request={}, const std::function< void(const unsigned int, const std::vector< T2 > &)> &function_read_answer={})
const MPI_Comm & comm
std::vector< std::unique_ptr< std::vector< T2 > > > request_buffers
std::vector< std::unique_ptr< MPI_Request > > request_requests
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:474