Reference documentation for deal.II version 9.3.3
\(\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
27namespace 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>
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>
167 {
168 public:
170
174 virtual ~Interface() = default;
175
179 virtual std::vector<unsigned int>
180 run() = 0;
181
182 protected:
187
192
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:
235
239 virtual ~NBX() = default;
240
244 virtual std::vector<unsigned int>
245 run() override;
246
247 private:
248#ifdef DEAL_II_WITH_MPI
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
286 MPI_Request barrier_request;
287#endif
288
292 std::set<unsigned int> requesting_processes;
293
297 bool
299
304 void
306
311 bool
313
318 void
320
325 void
327
332 void
334 };
335
358 template <typename T1, typename T2>
359 class PEX : public Interface<T1, T2>
360 {
361 public:
369
373 virtual ~PEX() = default;
374
378 virtual std::vector<unsigned int>
379 run() override;
380
381 private:
382#ifdef DEAL_II_WITH_MPI
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
423 std::set<unsigned int> requesting_processes;
424
429 void
430 answer_requests(int index);
431
436 unsigned int
438
443 void
445 };
446
451 template <typename T1, typename T2>
452 class Serial : public Interface<T1, T2>
453 {
454 public:
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:
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>()>
534 const std::function<void(const unsigned int, std::vector<T1> &)>
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> &)>
545 [](const unsigned int, std::vector<T2> &) {},
546 const std::function<void(const unsigned int, const std::vector<T2> &)>
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>()>
588 const std::function<void(const int, std::vector<T1> &)>
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> &)>
595 const std::function<void(const int, const std::vector<T2> &)>
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
const std::function< std::vector< unsigned int >()> function_compute_targets
const std::function< void(const unsigned int, const std::vector< T1 > &, std::vector< T2 > &)> function_answer_request
void prepare_buffer_for_answer(const unsigned int other_rank, std::vector< T2 > &recv_buffer) override
const std::function< void(const int, std::vector< T1 > &)> function_create_request
void answer_request(const unsigned int other_rank, const std::vector< T1 > &buffer_recv, std::vector< T2 > &request_buffer) override
void read_answer(const unsigned int other_rank, const std::vector< T2 > &recv_buffer) override
void create_request(const unsigned int other_rank, std::vector< T1 > &send_buffer) override
const std::function< void(const int, std::vector< T2 > &)> function_prepare_buffer_for_answer
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 > &) {})
const std::function< void(const int, const std::vector< T2 > &)> function_read_answer
Interface(Process< T1, T2 > &process, const MPI_Comm &comm)
virtual std::vector< unsigned int > run()=0
std::vector< std::vector< T2 > > recv_buffers
NBX(Process< T1, T2 > &process, const MPI_Comm &comm)
virtual std::vector< unsigned int > run() override
std::vector< std::unique_ptr< std::vector< T2 > > > request_buffers
std::vector< std::unique_ptr< MPI_Request > > request_requests
std::vector< std::vector< T1 > > send_buffers
virtual std::vector< unsigned int > run() override
std::vector< std::vector< T2 > > recv_buffers
PEX(Process< T1, T2 > &process, const MPI_Comm &comm)
std::vector< std::vector< T1 > > send_buffers
std::vector< std::vector< T2 > > requests_buffers
virtual void create_request(const unsigned int other_rank, std::vector< T1 > &send_buffer)
virtual void read_answer(const unsigned int other_rank, const 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)
virtual std::vector< unsigned int > compute_targets()=0
virtual void prepare_buffer_for_answer(const unsigned int other_rank, std::vector< T2 > &recv_buffer)
std::shared_ptr< Interface< T1, T2 > > consensus_algo
virtual std::vector< unsigned int > run() override
Selector(Process< T1, T2 > &process, const MPI_Comm &comm)
Serial(Process< T1, T2 > &process, const MPI_Comm &comm)
virtual std::vector< unsigned int > run() override
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403