Go to the documentation of this file.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 "ParSortableList.H"
00027 #include "SortableList.H"
00028 #include <OpenFOAM/Pstream.H>
00029 #include <OpenFOAM/ListListOps.H>
00030 #include <OpenFOAM/PstreamReduceOps.H>
00031
00032
00033
00034 template <class Type>
00035 void Foam::ParSortableList<Type>::write
00036 (
00037 const List<Type>& elems,
00038 Ostream& os
00039 ) const
00040 {
00041 os << '(';
00042
00043 forAll(elems, elemI)
00044 {
00045 os << ' ' << elems[elemI];
00046 }
00047 os << ')';
00048 }
00049
00050
00051
00052 template <class Type>
00053 void Foam::ParSortableList<Type>::copyInto
00054 (
00055 const List<Type>& values,
00056 const labelList& indices,
00057 const label fromProcNo,
00058 label& destI,
00059 List<taggedValue>& dest
00060 ) const
00061 {
00062 forAll(values, elemI)
00063 {
00064 taggedValue& tagVal = dest[destI];
00065
00066 tagVal.value() = values[elemI];
00067 tagVal.index() = indices[elemI];
00068 tagVal.procID() = fromProcNo;
00069
00070 destI++;
00071 }
00072 }
00073
00074
00075 template <class Type>
00076 void Foam::ParSortableList<Type>::getPivots
00077 (
00078 const List<Type>& elems,
00079 List<Type>& pivots
00080 ) const
00081 {
00082 pivots.setSize(Pstream::nProcs());
00083
00084 label pivotPos = 0;
00085
00086 forAll(pivots, pivotI)
00087 {
00088 pivots[pivotI] = elems[pivotPos];
00089
00090 pivotPos += elems.size()/Pstream::nProcs();
00091 }
00092 }
00093
00094
00095 template <class Type>
00096 void Foam::ParSortableList<Type>::checkAndSend
00097 (
00098 List<Type>& values,
00099 labelList& indices,
00100 const label bufSize,
00101 const label destProcI
00102 ) const
00103 {
00104 if (destProcI != Pstream::myProcNo())
00105 {
00106 values.setSize(bufSize);
00107 indices.setSize(bufSize);
00108
00109 if (debug)
00110 {
00111 Pout<< "Sending to " << destProcI << " elements:" << values
00112 << endl;
00113 }
00114
00115 {
00116 OPstream toSlave(Pstream::blocking, destProcI);
00117 toSlave << values << indices;
00118 }
00119 }
00120 }
00121
00122
00123
00124
00125
00126 template <class Type>
00127 Foam::ParSortableList<Type>::ParSortableList(const UList<Type>& values)
00128 :
00129 List<Type>(values),
00130 indices_(0),
00131 procs_(0)
00132 {
00133 sort();
00134 }
00135
00136
00137
00138 template <class Type>
00139 Foam::ParSortableList<Type>::ParSortableList(const label size)
00140 :
00141 List<Type>(size),
00142 indices_(0),
00143 procs_(0)
00144 {}
00145
00146
00147
00148
00149
00150 template <class Type>
00151 void Foam::ParSortableList<Type>::sort()
00152 {
00153
00154
00155
00156
00157 label n = this->size();
00158
00159 reduce(n, sumOp<label>());
00160
00161
00162
00163 SortableList<Type> sorted(*this);
00164
00165
00166 labelListList sortedGatherList(Pstream::nProcs());
00167
00168 labelList& pivots = sortedGatherList[Pstream::myProcNo()];
00169
00170 getPivots(sorted, pivots);
00171
00172 if (debug)
00173 {
00174 Pout<< "pivots:";
00175 write(pivots, Pout);
00176 Pout<< endl;
00177 }
00178
00179
00180
00181
00182
00183
00184 Pstream::gatherList(sortedGatherList);
00185
00186 if (Pstream::master())
00187 {
00188 labelList allPivots =
00189 ListListOps::combine<labelList>
00190 (
00191 sortedGatherList,
00192 accessOp<labelList>()
00193 );
00194
00195 SortableList<Type> sortedPivots(allPivots);
00196
00197 if (debug)
00198 {
00199 Pout<< "allPivots:";
00200 write(allPivots, Pout);
00201 Pout<< endl;
00202 }
00203
00204 getPivots(sortedPivots, pivots);
00205 }
00206 Pstream::scatter(pivots);
00207
00208 if (debug)
00209 {
00210 Pout<< "new pivots:";
00211 write(pivots, Pout);
00212 Pout<< endl;
00213 }
00214
00215
00216
00217
00218
00219
00220 label pivotI = 1;
00221 label destProcI = 0;
00222
00223
00224 labelList ownValues(sorted.size());
00225 labelList ownIndices(sorted.size());
00226 label ownI = 0;
00227
00228
00229 labelList sendValues(sorted.size());
00230 labelList sendIndices(sorted.size());
00231 label sendI = 0;
00232
00233 forAll(sorted, sortedI)
00234 {
00235 if ((pivotI < Pstream::nProcs()) && (sorted[sortedI] > pivots[pivotI]))
00236 {
00237 checkAndSend(sendValues, sendIndices, sendI, destProcI);
00238
00239
00240 sendValues.setSize(sorted.size());
00241 sendIndices.setSize(sorted.size());
00242 sendI = 0;
00243
00244 pivotI++;
00245 destProcI++;
00246 }
00247
00248 if (destProcI != Pstream::myProcNo())
00249 {
00250 sendValues[sendI] = sorted[sortedI];
00251 sendIndices[sendI] = sorted.indices()[sortedI];
00252 sendI++;
00253 }
00254 else
00255 {
00256 ownValues[ownI] = sorted[sortedI];
00257 ownIndices[ownI] = sorted.indices()[sortedI];
00258 ownI++;
00259 }
00260 }
00261
00262
00263
00264 if (sendI != 0)
00265 {
00266 checkAndSend(sendValues, sendIndices, sendI, destProcI);
00267 }
00268
00269
00270 ownValues.setSize(ownI);
00271 ownIndices.setSize(ownI);
00272
00273 if (debug & 2)
00274 {
00275 Pout<< "Not sending (to myself) elements "
00276 << ownValues << endl;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286 List<taggedValue> combinedValues(2 * n/Pstream::nProcs());
00287
00288 label combinedI = 0;
00289
00290 for (label procI = 0; procI < Pstream::nProcs(); procI++)
00291 {
00292 if (procI == Pstream::myProcNo())
00293 {
00294 if (debug & 2)
00295 {
00296 Pout<< "Copying from own:" << ownValues << endl;
00297 }
00298
00299
00300 copyInto(ownValues, ownIndices, procI, combinedI, combinedValues);
00301 }
00302 else
00303 {
00304 labelList recValues;
00305 labelList recIndices;
00306
00307 {
00308 if (debug)
00309 {
00310 Pout<< "Receiving from " << procI << endl;
00311 }
00312
00313 IPstream fromSlave(Pstream::blocking, procI);
00314
00315 fromSlave >> recValues >> recIndices;
00316
00317 if (debug & 2)
00318 {
00319 Pout<< "Received from " << procI
00320 << " elements:" << recValues << endl;
00321 }
00322 }
00323
00324 if (debug)
00325 {
00326 Pout<< "Copying starting at:" << combinedI << endl;
00327 }
00328 copyInto(recValues, recIndices, procI, combinedI, combinedValues);
00329 }
00330 }
00331 combinedValues.setSize(combinedI);
00332
00333
00334 Foam::sort(combinedValues);
00335
00336
00337 this->setSize(combinedI);
00338 indices_.setSize(combinedI);
00339 procs_.setSize(combinedI);
00340
00341 forAll(combinedValues, elemI)
00342 {
00343 this->operator[](elemI) = combinedValues[elemI].value();
00344 indices_[elemI] = combinedValues[elemI].index();
00345 procs_[elemI] = combinedValues[elemI].procID();
00346 }
00347 }
00348
00349
00350