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-2018 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  recvBufs.setSize(sendBufs.size());
65 
66  if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
67  {
68  label startOfRequests = Pstream::nRequests();
69 
70  // Set up receives
71  // ~~~~~~~~~~~~~~~
72 
73  forAll(recvSizes, proci)
74  {
75  label nRecv = recvSizes[proci];
76 
77  if (proci != Pstream::myProcNo(comm) && nRecv > 0)
78  {
79  recvBufs[proci].setSize(nRecv);
81  (
82  UPstream::commsTypes::nonBlocking,
83  proci,
84  reinterpret_cast<char*>(recvBufs[proci].begin()),
85  nRecv*sizeof(T),
86  tag,
87  comm
88  );
89  }
90  }
91 
92 
93  // Set up sends
94  // ~~~~~~~~~~~~
95 
96  forAll(sendBufs, proci)
97  {
98  if (proci != Pstream::myProcNo(comm) && sendBufs[proci].size() > 0)
99  {
100  if
101  (
103  (
104  UPstream::commsTypes::nonBlocking,
105  proci,
106  reinterpret_cast<const char*>(sendBufs[proci].begin()),
107  sendBufs[proci].size()*sizeof(T),
108  tag,
109  comm
110  )
111  )
112  {
114  << "Cannot send outgoing message. "
115  << "to:" << proci << " nBytes:"
116  << label(sendBufs[proci].size()*sizeof(T))
118  }
119  }
120  }
121 
122 
123  // Wait for all to finish
124  // ~~~~~~~~~~~~~~~~~~~~~~
125 
126  if (block)
127  {
128  Pstream::waitRequests(startOfRequests);
129  }
130  }
131 
132  // Do myself
133  recvBufs[Pstream::myProcNo(comm)] = sendBufs[Pstream::myProcNo(comm)];
134 }
135 
136 
137 template<class Container>
139 (
140  const Container& sendBufs,
141  labelList& recvSizes,
142  const label comm
143 )
144 {
145  if (sendBufs.size() != UPstream::nProcs(comm))
146  {
148  << "Size of container " << sendBufs.size()
149  << " does not equal the number of processors "
150  << UPstream::nProcs(comm)
152  }
153 
154  labelList sendSizes(sendBufs.size());
155  forAll(sendBufs, proci)
156  {
157  sendSizes[proci] = sendBufs[proci].size();
158  }
159  recvSizes.setSize(sendSizes.size());
160  allToAll(sendSizes, recvSizes, comm);
161 }
162 
163 
164 template<class Container, class T>
166 (
167  const UList<Container>& sendBufs,
168  List<Container>& recvBufs,
169  const int tag,
170  const label comm,
171  const bool block
172 )
173 {
174  labelList recvSizes;
175  exchangeSizes(sendBufs, recvSizes, comm);
176 
177  exchange<Container, T>(sendBufs, recvSizes, recvBufs, tag, comm, block);
178 }
179 
180 
181 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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:60
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:139
void write(Ostream &, const label, const dictionary &)
Write with dictionary lookup.
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:61
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