1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
28 #include <OpenFOAM/debug.H>
29 #include <OpenFOAM/dictionary.H>
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 defineTypeNameAndDebug(Foam::Pstream, 0);
36 const char* Foam::NamedEnum<Foam::Pstream::commsTypes, 3>::names[] =
43 const Foam::NamedEnum<Foam::Pstream::commsTypes, 3>
44 Foam::Pstream::commsTypeNames;
46 Foam::autoPtr<Foam::PstreamImpl> Foam::Pstream::impl_;
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 void Foam::Pstream::calcLinearComm(const label nProcs)
53 linearCommunication_.setSize(nProcs);
56 labelList belowIDs(nProcs - 1);
62 linearCommunication_[0] = commsStruct
71 // Slaves. Have no below processors, only communicate up to master
72 for (label procID = 1; procID < nProcs; procID++)
74 linearCommunication_[procID] = commsStruct
86 // Append my children (and my children children etc.) to allReceives.
87 void Foam::Pstream::collectReceives
90 const List<DynamicList<label> >& receives,
91 DynamicList<label>& allReceives
94 const DynamicList<label>& myChildren = receives[procID];
96 forAll(myChildren, childI)
98 allReceives.append(myChildren[childI]);
99 collectReceives(myChildren[childI], receives, allReceives);
104 // Tree like schedule. For 8 procs:
116 // The sends/receives for all levels are collected per processor (one send per
117 // processor; multiple receives possible) creating a table:
120 // proc receives from sends to
121 // ---- ------------- --------
130 void Foam::Pstream::calcTreeComm(label nProcs)
133 while ((1 << nLevels) < nProcs)
138 List<DynamicList<label> > receives(nProcs);
139 labelList sends(nProcs, -1);
141 // Info<< "Using " << nLevels << " communication levels" << endl;
144 label childOffset = offset/2;
146 for (label level = 0; level < nLevels; level++)
149 while (receiveID < nProcs)
151 // Determine processor that sends and we receive from
152 label sendID = receiveID + childOffset;
156 receives[receiveID].append(sendID);
157 sends[sendID] = receiveID;
167 // For all processors find the processors it receives data from
168 // (and the processors they receive data from etc.)
169 List<DynamicList<label> > allReceives(nProcs);
170 for (label procID = 0; procID < nProcs; procID++)
172 collectReceives(procID, receives, allReceives[procID]);
176 treeCommunication_.setSize(nProcs);
178 for (label procID = 0; procID < nProcs; procID++)
180 treeCommunication_[procID] = commsStruct
185 receives[procID].shrink(),
186 allReceives[procID].shrink()
192 // Callback from Pstream::init() : initialize linear and tree communication
193 // schedules now that nProcs is known.
194 void Foam::Pstream::initCommunicationSchedule()
196 calcLinearComm(nProcs());
197 calcTreeComm(nProcs());
201 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
203 // Initialise my process number to 0 (the master)
204 int Foam::Pstream::myProcNo_(0);
206 // By default this is not a parallel run
207 bool Foam::Pstream::parRun_(false);
209 // List of process IDs
210 Foam::List<int> Foam::Pstream::procIDs_(1, 0);
212 // Standard transfer message type
213 const int Foam::Pstream::msgType_(1);
215 // Linear communication schedule
216 Foam::List<Foam::Pstream::commsStruct> Foam::Pstream::linearCommunication_(0);
218 // Multi level communication schedule
219 Foam::List<Foam::Pstream::commsStruct> Foam::Pstream::treeCommunication_(0);
221 // Should compact transfer be used in which floats replace doubles
222 // reducing the bandwidth requirement at the expense of some loss
224 bool Foam::Pstream::floatTransfer
226 debug::optimisationSwitch("floatTransfer", 0)
229 // Number of processors at which the reduce algorithm changes from linear to
231 int Foam::Pstream::nProcsSimpleSum
233 debug::optimisationSwitch("nProcsSimpleSum", 16)
237 Foam::Pstream::commsTypes Foam::Pstream::defaultCommsType
239 commsTypeNames.read(debug::optimisationSwitches().lookup("commsType"))
243 // ************************ vim: set sw=4 sts=4 et: ************************ //