1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
28 #include "dictionary.H"
29 #include "IOstreams.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 defineTypeNameAndDebug(Foam::UPstream, 0);
38 const char* Foam::NamedEnum
40 Foam::UPstream::commsTypes,
51 const Foam::NamedEnum<Foam::UPstream::commsTypes, 3>
52 Foam::UPstream::commsTypeNames;
55 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
57 void Foam::UPstream::setParRun()
61 Pout.prefix() = '[' + name(myProcNo()) + "] ";
62 Perr.prefix() = '[' + name(myProcNo()) + "] ";
66 void Foam::UPstream::calcLinearComm(const label nProcs)
68 linearCommunication_.setSize(nProcs);
71 labelList belowIDs(nProcs - 1);
77 linearCommunication_[0] = commsStruct
86 // Slaves. Have no below processors, only communicate up to master
87 for (label procID = 1; procID < nProcs; procID++)
89 linearCommunication_[procID] = commsStruct
101 // Append my children (and my children children etc.) to allReceives.
102 void Foam::UPstream::collectReceives
105 const List<DynamicList<label> >& receives,
106 DynamicList<label>& allReceives
109 const DynamicList<label>& myChildren = receives[procID];
111 forAll(myChildren, childI)
113 allReceives.append(myChildren[childI]);
114 collectReceives(myChildren[childI], receives, allReceives);
119 // Tree like schedule. For 8 procs:
131 // The sends/receives for all levels are collected per processor (one send per
132 // processor; multiple receives possible) creating a table:
135 // proc receives from sends to
136 // ---- ------------- --------
145 void Foam::UPstream::calcTreeComm(label nProcs)
148 while ((1 << nLevels) < nProcs)
153 List<DynamicList<label> > receives(nProcs);
154 labelList sends(nProcs, -1);
156 // Info<< "Using " << nLevels << " communication levels" << endl;
159 label childOffset = offset/2;
161 for (label level = 0; level < nLevels; level++)
164 while (receiveID < nProcs)
166 // Determine processor that sends and we receive from
167 label sendID = receiveID + childOffset;
171 receives[receiveID].append(sendID);
172 sends[sendID] = receiveID;
182 // For all processors find the processors it receives data from
183 // (and the processors they receive data from etc.)
184 List<DynamicList<label> > allReceives(nProcs);
185 for (label procID = 0; procID < nProcs; procID++)
187 collectReceives(procID, receives, allReceives[procID]);
191 treeCommunication_.setSize(nProcs);
193 for (label procID = 0; procID < nProcs; procID++)
195 treeCommunication_[procID] = commsStruct
200 receives[procID].shrink(),
201 allReceives[procID].shrink()
207 // Callback from UPstream::init() : initialize linear and tree communication
208 // schedules now that nProcs is known.
209 void Foam::UPstream::initCommunicationSchedule()
211 calcLinearComm(nProcs());
212 calcTreeComm(nProcs());
216 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
218 // Initialise my process number to 0 (the master)
219 int Foam::UPstream::myProcNo_(0);
221 // By default this is not a parallel run
222 bool Foam::UPstream::parRun_(false);
224 // List of process IDs
225 Foam::List<int> Foam::UPstream::procIDs_(1, 0);
227 // Standard transfer message type
228 int Foam::UPstream::msgType_(1);
230 // Linear communication schedule
231 Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::linearCommunication_(0);
233 // Multi level communication schedule
234 Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::treeCommunication_(0);
236 // Should compact transfer be used in which floats replace doubles
237 // reducing the bandwidth requirement at the expense of some loss
239 bool Foam::UPstream::floatTransfer
241 debug::optimisationSwitch("floatTransfer", 0)
244 // Number of processors at which the reduce algorithm changes from linear to
246 int Foam::UPstream::nProcsSimpleSum
248 debug::optimisationSwitch("nProcsSimpleSum", 16)
252 Foam::UPstream::commsTypes Foam::UPstream::defaultCommsType
254 commsTypeNames.read(debug::optimisationSwitches().lookup("commsType"))
258 // ************************************************************************* //