exchange.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  Exchange data.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "Pstream.H"
30 #include "contiguous.H"
32 #include "UPstream.H"
33 
34 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 
36 template<class Container, class T>
38 (
39  const UList<Container>& sendBufs,
40  const labelUList& recvSizes,
41  List<Container>& recvBufs,
42  const int tag,
43  const label comm,
44  const bool block
45 )
46 {
47  if (!contiguous<T>())
48  {
50  << "Continuous data only." << sizeof(T) << Foam::abort(FatalError);
51  }
52 
53  if (sendBufs.size() != UPstream::nProcs(comm))
54  {
56  << "Size of list " << sendBufs.size()
57  << " does not equal the number of processors "
58  << UPstream::nProcs(comm)
60  }
61 
62  recvBufs.setSize(sendBufs.size());
63 
64  if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
65  {
66  label startOfRequests = Pstream::nRequests();
67 
68  // Set up receives
69  // ~~~~~~~~~~~~~~~
70 
71  forAll(recvSizes, proci)
72  {
73  label nRecv = recvSizes[proci];
74 
75  if (proci != Pstream::myProcNo(comm) && nRecv > 0)
76  {
77  recvBufs[proci].setSize(nRecv);
79  (
80  UPstream::commsTypes::nonBlocking,
81  proci,
82  reinterpret_cast<char*>(recvBufs[proci].begin()),
83  nRecv*sizeof(T),
84  tag,
85  comm
86  );
87  }
88  }
89 
90 
91  // Set up sends
92  // ~~~~~~~~~~~~
93 
94  forAll(sendBufs, proci)
95  {
96  if (proci != Pstream::myProcNo(comm) && sendBufs[proci].size() > 0)
97  {
98  if
99  (
101  (
102  UPstream::commsTypes::nonBlocking,
103  proci,
104  reinterpret_cast<const char*>(sendBufs[proci].begin()),
105  sendBufs[proci].size()*sizeof(T),
106  tag,
107  comm
108  )
109  )
110  {
112  << "Cannot send outgoing message. "
113  << "to:" << proci << " nBytes:"
114  << label(sendBufs[proci].size()*sizeof(T))
116  }
117  }
118  }
119 
120 
121  // Wait for all to finish
122  // ~~~~~~~~~~~~~~~~~~~~~~
123 
124  if (block)
125  {
126  Pstream::waitRequests(startOfRequests);
127  }
128  }
129 
130  // Do myself
131  recvBufs[Pstream::myProcNo(comm)] = sendBufs[Pstream::myProcNo(comm)];
132 }
133 
134 
135 template<class Container>
137 (
138  const Container& sendBufs,
139  labelList& recvSizes,
140  const label comm
141 )
142 {
143  if (sendBufs.size() != UPstream::nProcs(comm))
144  {
146  << "Size of container " << sendBufs.size()
147  << " does not equal the number of processors "
148  << UPstream::nProcs(comm)
150  }
151 
152  labelList sendSizes(sendBufs.size());
153  forAll(sendBufs, proci)
154  {
155  sendSizes[proci] = sendBufs[proci].size();
156  }
157  recvSizes.setSize(sendSizes.size());
158  allToAll(sendSizes, recvSizes, comm);
159 }
160 
161 
162 template<class Container, class T>
164 (
165  const UList<Container>& sendBufs,
166  List<Container>& recvBufs,
167  const int tag,
168  const label comm,
169  const bool block
170 )
171 {
172  labelList recvSizes;
173  exchangeSizes(sendBufs, recvSizes, comm);
174 
175  exchange<Container, T>(sendBufs, recvSizes, recvBufs, tag, comm, block);
176 }
177 
178 
179 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Template function to specify if the data of a type are contiguous.
static void exchange(const UList< Container > &sendData, const labelUList &recvSizes, List< Container > &recvData, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, const bool block=true)
Helper: exchange contiguous data. Sends sendData, receives into.
Definition: exchange.C:38
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
Combination-Reduction operation for a parallel run. The information from all nodes is collected on th...
static void exchangeSizes(const Container &sendData, labelList &sizes, const label comm=UPstream::worldComm)
Helper: exchange sizes of sendData. sendData is the data per.
Definition: exchange.C:137
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
const volScalarField & T
void setSize(const label)
Reset size of List.
Definition: List.C:281
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299