OOPS
oops/mpi/mpi.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
11 #include "oops/mpi/mpi.h"
12 
13 #include <string>
14 
15 #include "eckit/exception/Exceptions.h"
16 
17 namespace oops {
18 namespace mpi {
19 
20 // ------------------------------------------------------------------------------------------------
21 
22 const eckit::mpi::Comm & world() {
23  return eckit::mpi::comm();
24 }
25 
26 // ------------------------------------------------------------------------------------------------
27 
28 const eckit::mpi::Comm & myself() {
29  return eckit::mpi::self();
30 }
31 
32 // ------------------------------------------------------------------------------------------------
33 
34 void gather(const eckit::mpi::Comm & comm, const std::vector<double> & send,
35  std::vector<double> & recv, const size_t root) {
36  int ntasks = comm.size();
37  if (ntasks > 1) {
38  int mysize = send.size();
39  std::vector<int> sizes(ntasks);
40  comm.allGather(mysize, sizes.begin(), sizes.end());
41  std::vector<int> displs(ntasks);
42  size_t rcvsz = sizes[0];
43  displs[0] = 0;
44  for (size_t jj = 1; jj < ntasks; ++jj) {
45  displs[jj] = displs[jj - 1] + sizes[jj - 1];
46  rcvsz += sizes[jj];
47  }
48  if (comm.rank() == root) recv.resize(rcvsz);
49 
50  comm.gatherv(send, recv, sizes, displs, root);
51  } else {
52  recv = send;
53  }
54 }
55 
56 // ------------------------------------------------------------------------------------------------
57 
58 void allGather(const eckit::mpi::Comm & comm,
59  const Eigen::VectorXd & sendbuf, std::vector<Eigen::VectorXd> & recvbuf) {
60  const int ntasks = comm.size();
61  int buf_size = sendbuf.size();
62 
63  std::vector<double> vbuf(sendbuf.data(), sendbuf.data() + buf_size);
64  std::vector<double> vbuf_total(ntasks * buf_size);
65 
66  std::vector<int> recvcounts(ntasks);
67  for (int ii = 0; ii < ntasks; ++ii) recvcounts[ii] = buf_size;
68 
69  std::vector<int> displs(ntasks);
70  for (int ii = 0; ii < ntasks; ++ii) displs[ii] = ii * buf_size;
71 
72  comm.allGatherv(vbuf.begin(), vbuf.end(),
73  vbuf_total.begin(), recvcounts.data(), displs.data());
74 
75  for (int ii = 0; ii < ntasks; ++ii) {
76  std::vector<double> vloc(vbuf_total.begin() + ii * buf_size,
77  vbuf_total.begin() + (ii + 1) * buf_size);
78  Eigen::VectorXd my_vect = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(vloc.data(),
79  vloc.size());
80  recvbuf[ii] = my_vect;
81  }
82 }
83 
84 // ------------------------------------------------------------------------------------------------
85 
86 } // namespace mpi
87 } // namespace oops
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
mpi.h
oops::mpi::allGather
void allGather(const eckit::mpi::Comm &comm, const Eigen::VectorXd &sendbuf, std::vector< Eigen::VectorXd > &recvbuf)
Definition: oops/mpi/mpi.cc:58
oops::mpi::myself
const eckit::mpi::Comm & myself()
Default communicator with each MPI task by itself.
Definition: oops/mpi/mpi.cc:28
oops::mpi::send
void send(const eckit::mpi::Comm &comm, const SERIALIZABLE &sendobj, const int dest, const int tag)
Extend eckit Comm for Serializable oops objects.
Definition: oops/mpi/mpi.h:36
oops::mpi::gather
void gather(const eckit::mpi::Comm &comm, const std::vector< double > &send, std::vector< double > &recv, const size_t root)
Definition: oops/mpi/mpi.cc:34
oops::mpi::world
const eckit::mpi::Comm & world()
Default communicator with all MPI tasks (ie MPI_COMM_WORLD)
Definition: oops/mpi/mpi.cc:22