00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "mapDistribute.H"
00027 #include <OpenFOAM/commSchedule.H>
00028 #include <OpenFOAM/HashSet.H>
00029 #include <OpenFOAM/ListOps.H>
00030
00031
00032
00033 Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
00034 (
00035 const labelListList& subMap,
00036 const labelListList& constructMap
00037 )
00038 {
00039
00040 List<labelPair> allComms;
00041
00042 {
00043 HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs());
00044
00045
00046 forAll(subMap, procI)
00047 {
00048 if (procI != Pstream::myProcNo())
00049 {
00050 if (subMap[procI].size())
00051 {
00052
00053 commsSet.insert(labelPair(Pstream::myProcNo(), procI));
00054 }
00055 if (constructMap[procI].size())
00056 {
00057
00058 commsSet.insert(labelPair(procI, Pstream::myProcNo()));
00059 }
00060 }
00061 }
00062 allComms = commsSet.toc();
00063 }
00064
00065
00066
00067 if (Pstream::master())
00068 {
00069
00070 for
00071 (
00072 int slave=Pstream::firstSlave();
00073 slave<=Pstream::lastSlave();
00074 slave++
00075 )
00076 {
00077 IPstream fromSlave(Pstream::blocking, slave);
00078 List<labelPair> nbrData(fromSlave);
00079
00080 forAll(nbrData, i)
00081 {
00082 if (findIndex(allComms, nbrData[i]) == -1)
00083 {
00084 label sz = allComms.size();
00085 allComms.setSize(sz+1);
00086 allComms[sz] = nbrData[i];
00087 }
00088 }
00089 }
00090
00091 for
00092 (
00093 int slave=Pstream::firstSlave();
00094 slave<=Pstream::lastSlave();
00095 slave++
00096 )
00097 {
00098 OPstream toSlave(Pstream::blocking, slave);
00099 toSlave << allComms;
00100 }
00101 }
00102 else
00103 {
00104 {
00105 OPstream toMaster(Pstream::blocking, Pstream::masterNo());
00106 toMaster << allComms;
00107 }
00108 {
00109 IPstream fromMaster(Pstream::blocking, Pstream::masterNo());
00110 fromMaster >> allComms;
00111 }
00112 }
00113
00114
00115
00116 labelList mySchedule
00117 (
00118 commSchedule
00119 (
00120 Pstream::nProcs(),
00121 allComms
00122 ).procSchedule()[Pstream::myProcNo()]
00123 );
00124
00125
00126 return UIndirectList<labelPair>(allComms, mySchedule);
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 }
00150
00151
00152 const Foam::List<Foam::labelPair>& Foam::mapDistribute::schedule() const
00153 {
00154 if (schedulePtr_.empty())
00155 {
00156 schedulePtr_.reset
00157 (
00158 new List<labelPair>
00159 (
00160 schedule(subMap_, constructMap_)
00161 )
00162 );
00163 }
00164 return schedulePtr_();
00165 }
00166
00167
00168
00169
00170
00171 Foam::mapDistribute::mapDistribute
00172 (
00173 const label constructSize,
00174 const labelListList& subMap,
00175 const labelListList& constructMap
00176 )
00177 :
00178 constructSize_(constructSize),
00179 subMap_(subMap),
00180 constructMap_(constructMap),
00181 schedulePtr_()
00182 {}
00183
00184
00185
00186 Foam::mapDistribute::mapDistribute
00187 (
00188 const label constructSize,
00189 labelListList& subMap,
00190 labelListList& constructMap,
00191 const bool reUse
00192 )
00193 :
00194 constructSize_(constructSize),
00195 subMap_(subMap, reUse),
00196 constructMap_(constructMap, reUse),
00197 schedulePtr_()
00198 {}
00199
00200
00201 Foam::mapDistribute::mapDistribute
00202 (
00203 const labelList& sendProcs,
00204 const labelList& recvProcs
00205 )
00206 :
00207 constructSize_(0),
00208 schedulePtr_()
00209 {
00210 if (sendProcs.size() != recvProcs.size())
00211 {
00212 FatalErrorIn
00213 (
00214 "mapDistribute::mapDistribute(const labelList&, const labelList&)"
00215 ) << "The send and receive data is not the same length. sendProcs:"
00216 << sendProcs.size() << " recvProcs:" << recvProcs.size()
00217 << abort(FatalError);
00218 }
00219
00220
00221 labelList nSend(Pstream::nProcs(), 0);
00222 labelList nRecv(Pstream::nProcs(), 0);
00223
00224 forAll(sendProcs, sampleI)
00225 {
00226 label sendProc = sendProcs[sampleI];
00227 label recvProc = recvProcs[sampleI];
00228
00229
00230
00231
00232 if (Pstream::myProcNo() == sendProc)
00233 {
00234
00235 nSend[recvProc]++;
00236 }
00237 if (Pstream::myProcNo() == recvProc)
00238 {
00239
00240 nRecv[sendProc]++;
00241 }
00242 }
00243
00244 subMap_.setSize(Pstream::nProcs());
00245 constructMap_.setSize(Pstream::nProcs());
00246 forAll(nSend, procI)
00247 {
00248 subMap_[procI].setSize(nSend[procI]);
00249 constructMap_[procI].setSize(nRecv[procI]);
00250 }
00251 nSend = 0;
00252 nRecv = 0;
00253
00254 forAll(sendProcs, sampleI)
00255 {
00256 label sendProc = sendProcs[sampleI];
00257 label recvProc = recvProcs[sampleI];
00258
00259 if (Pstream::myProcNo() == sendProc)
00260 {
00261
00262 subMap_[recvProc][nSend[recvProc]++] = sampleI;
00263 }
00264 if (Pstream::myProcNo() == recvProc)
00265 {
00266
00267 constructMap_[sendProc][nRecv[sendProc]++] = sampleI;
00268
00269 constructSize_ = sampleI+1;
00270 }
00271 }
00272 }
00273
00274
00275 Foam::mapDistribute::mapDistribute(const mapDistribute& map)
00276 :
00277 constructSize_(map.constructSize_),
00278 subMap_(map.subMap_),
00279 constructMap_(map.constructMap_),
00280 schedulePtr_()
00281 {}
00282
00283
00284
00285
00286 void Foam::mapDistribute::compact(const boolList& elemIsUsed)
00287 {
00288
00289
00290
00291
00292
00293
00294 {
00295 List<boolList> sendFields(Pstream::nProcs());
00296
00297 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00298 {
00299 const labelList& map = constructMap_[domain];
00300
00301 if (domain != Pstream::myProcNo() && map.size())
00302 {
00303 boolList& subField = sendFields[domain];
00304 subField.setSize(map.size());
00305 forAll(map, i)
00306 {
00307 subField[i] = elemIsUsed[map[i]];
00308 }
00309
00310 OPstream::write
00311 (
00312 Pstream::nonBlocking,
00313 domain,
00314 reinterpret_cast<const char*>(subField.begin()),
00315 subField.size()*sizeof(bool)
00316 );
00317 }
00318 }
00319
00320
00321
00322 List<boolList> recvFields(Pstream::nProcs());
00323
00324 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00325 {
00326 const labelList& map = subMap_[domain];
00327
00328 if (domain != Pstream::myProcNo() && map.size())
00329 {
00330 recvFields[domain].setSize(map.size());
00331 IPstream::read
00332 (
00333 Pstream::nonBlocking,
00334 domain,
00335 reinterpret_cast<char*>(recvFields[domain].begin()),
00336 recvFields[domain].size()*sizeof(bool)
00337 );
00338 }
00339 }
00340
00341
00342
00343
00344 {
00345 const labelList& map = constructMap_[Pstream::myProcNo()];
00346
00347 recvFields[Pstream::myProcNo()].setSize(map.size());
00348 forAll(map, i)
00349 {
00350 recvFields[Pstream::myProcNo()][i] = elemIsUsed[map[i]];
00351 }
00352 }
00353
00354
00355
00356
00357 OPstream::waitRequests();
00358 IPstream::waitRequests();
00359
00360
00361
00362 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00363 {
00364 const labelList& map = subMap_[domain];
00365
00366 labelList newMap(map.size());
00367 label newI = 0;
00368
00369 forAll(map, i)
00370 {
00371 if (recvFields[domain][i])
00372 {
00373
00374 newMap[newI++] = map[i];
00375 }
00376 }
00377 if (newI < map.size())
00378 {
00379 newMap.setSize(newI);
00380 subMap_[domain].transfer(newMap);
00381 }
00382 }
00383 }
00384
00385
00386
00387
00388
00389 label maxConstructIndex = -1;
00390
00391 for (label domain = 0; domain < Pstream::nProcs(); domain++)
00392 {
00393 const labelList& map = constructMap_[domain];
00394
00395 labelList newMap(map.size());
00396 label newI = 0;
00397
00398 forAll(map, i)
00399 {
00400 label destinationI = map[i];
00401
00402
00403 if (elemIsUsed[destinationI])
00404 {
00405 maxConstructIndex = max(maxConstructIndex, destinationI);
00406
00407 newMap[newI++] = destinationI;
00408 }
00409 }
00410 if (newI < map.size())
00411 {
00412 newMap.setSize(newI);
00413 constructMap_[domain].transfer(newMap);
00414 }
00415 }
00416
00417 constructSize_ = maxConstructIndex+1;
00418
00419
00420 schedulePtr_.clear();
00421 }
00422
00423
00424
00425
00426 void Foam::mapDistribute::operator=(const mapDistribute& rhs)
00427 {
00428
00429 if (this == &rhs)
00430 {
00431 FatalErrorIn
00432 (
00433 "Foam::mapDistribute::operator=(const Foam::mapDistribute&)"
00434 ) << "Attempted assignment to self"
00435 << abort(FatalError);
00436 }
00437 constructSize_ = rhs.constructSize_;
00438 subMap_ = rhs.subMap_;
00439 constructMap_ = rhs.constructMap_;
00440 schedulePtr_.clear();
00441 }
00442
00443
00444