TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
mpi.hpp
Go to the documentation of this file.
1// Copyright (c) 2020-2021 Simons Foundation
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You may obtain a copy of the License at
14// https://www.gnu.org/licenses/gpl-3.0.txt
15//
16// Authors: Michel Ferrero, Olivier Parcollet, Nils Wentzell
17
22
23#pragma once
24
25#include "./block_gf.hpp"
27
28#include <mpi/mpi.hpp>
29
30#include <cstddef>
31#include <numeric>
32#include <string>
33#include <type_traits>
34
35namespace triqs::gfs {
36
37 namespace detail {
38
39 // Check the shape of block GFs across all processes.
40 template <typename G> bool have_mpi_equal_shape(const G &bg, const mpi::communicator &comm) {
41 if constexpr (G::arity == 1) {
42 return mpi::all_equal(bg.size(), comm);
43 } else {
44 return mpi::all_equal(bg.size1(), comm) && mpi::all_equal(bg.size2(), comm);
45 }
46 }
47
48 // Hash the block names for comparison.
49 template <typename G> std::size_t hash_names(G const &bg) {
50 auto bin_op = [](std::size_t acc, auto const &name) { return acc + std::hash<std::string>{}(name); };
51 if constexpr (G::arity == 1) {
52 return std::accumulate(bg.block_names().begin(), bg.block_names().end(), std::size_t{0}, bin_op);
53 } else {
54 uint64_t hash = 0;
55 for (auto const &vec : bg.block_names()) { hash += std::accumulate(vec.begin(), vec.end(), std::size_t{0}, bin_op); }
56 return hash;
57 }
58 }
59
60 } // namespace detail
61
66
79 template <BlockGf BG> void mpi_broadcast(BG &&bg, mpi::communicator c, int root) { // NOLINT (temporary views are allowed)
80 constexpr bool is_view = std::decay_t<BG>::is_view;
81
82 // broadcast block names
83 if constexpr (!is_view) {
84 // for non-view block GFs, we broadcast the block names directly into the block GF
85 mpi::broadcast(bg._block_names, c, root);
86 } else {
87 // for views, we keep the block names in the block GF but check that they are the same as on the root process
88 auto names = bg.block_names();
89 mpi::broadcast(names, c, root);
90 EXPECTS(bg.block_names() == names);
91 }
92
93 // broadcast data
94 mpi::broadcast(bg.data(), c, root);
95 }
96
123 template <BlockGf BG1, BlockGf BG2>
124 void mpi_reduce_into(BG1 const &bg_in, BG2 &&bg_out, mpi::communicator c, int root, // NOLINT (temporary views are allowed here)
125 bool all, MPI_Op op) {
126 constexpr bool is_view = std::decay_t<BG2>::is_view;
127
128 // check the shape and block names of the input block GFs
129 EXPECTS(mpi::all_equal(detail::hash_names(bg_in), c));
130 if (not detail::have_mpi_equal_shape(bg_in, c))
131 TRIQS_RUNTIME_ERROR << "Error in triqs::gfs::mpi_reduce_into: Shapes of input block GFs must be equal";
132
133 // assign (check) the block names of the output block GF (view) on receiving ranks
134 if ((c.rank() == root || all)) {
135 if constexpr (is_view) {
136 EXPECTS(bg_in.block_names() == bg_out.block_names());
137 } else {
138 bg_out._block_names = bg_in.block_names();
139 }
140 }
141
142 // reduce the vector (of vectors) of GF objects
143 mpi::reduce_into(bg_in.data(), bg_out.data(), c, root, all, op);
144 }
145
166 template <BlockGf BG> auto mpi_reduce(BG const &bg, mpi::communicator c = {}, int root = 0, bool all = false, MPI_Op op = MPI_SUM) {
167 auto res = typename BG::regular_type{};
168 mpi_reduce_into(bg, res, c, root, all, op);
169 return res;
170 }
171
173
174} // namespace triqs::gfs
Provides the block Green's function container.
TRIQS exception hierarchy and related macros.
void mpi_broadcast(BG &&bg, mpi::communicator c={}, int root=0)
Implementation of an MPI broadcast for triqs::gfs::block_gf and triqs::gfs::block_gf_view types.
Definition mpi.hpp:79
void mpi_reduce_into(BG1 const &bg_in, BG2 &&bg_out, mpi::communicator c={}, int root=0, bool all=false, MPI_Op op=MPI_SUM)
Implementation of an MPI reduce for triqs::gfs::block_gf and triqs::gfs::block_gf_view types that red...
Definition mpi.hpp:124
auto mpi_reduce(BG const &bg, mpi::communicator c={}, int root=0, bool all=false, MPI_Op op=MPI_SUM)
Implementation of an MPI reduce for triqs::gfs::block_gf and triqs::gfs::block_gf_view types.
Definition mpi.hpp:166
uint64_t hash(Ts &&...ts)
Generic hash function for multiple arguments.
Definition utils.hpp:70
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
Trait that detects view types by checking for inheritance from is_view_tag.
Definition traits.hpp:74