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 "commSchedule.H"
00027 #include <OpenFOAM/SortableList.H>
00028 #include <OpenFOAM/boolList.H>
00029 #include <OpenFOAM/IOstreams.H>
00030 #include <OpenFOAM/IOmanip.H>
00031 #include <OpenFOAM/OStringStream.H>
00032 #include <OpenFOAM/Pstream.H>
00033
00034
00035
00036 defineTypeNameAndDebug(Foam::commSchedule, 0);
00037
00038
00039
00040
00041 Foam::label Foam::commSchedule::outstandingComms
00042 (
00043 const labelList& commToSchedule,
00044 DynamicList<label>& procComms
00045 ) const
00046 {
00047 label nOutstanding = 0;
00048
00049 forAll(procComms, i)
00050 {
00051 if (commToSchedule[procComms[i]] == -1)
00052 {
00053 nOutstanding++;
00054 }
00055 }
00056 return nOutstanding;
00057 }
00058
00059
00060
00061
00062
00063 Foam::commSchedule::commSchedule
00064 (
00065 const label nProcs,
00066 const List<labelPair>& comms
00067 )
00068 :
00069 schedule_(comms.size()),
00070 procSchedule_(nProcs)
00071 {
00072
00073 List<DynamicList<label> > procToComms(nProcs);
00074
00075 forAll(comms, commI)
00076 {
00077 label proc0 = comms[commI][0];
00078 label proc1 = comms[commI][1];
00079
00080 if (proc0 < 0 || proc0 >= nProcs || proc1 < 0 || proc1 >= nProcs)
00081 {
00082 FatalErrorIn
00083 (
00084 "commSchedule::commSchedule"
00085 "(const label, const List<labelPair>&)"
00086 ) << "Illegal processor " << comms[commI] << abort(FatalError);
00087 }
00088
00089 procToComms[proc0].append(commI);
00090 procToComms[proc1].append(commI);
00091 }
00092
00093
00094 if (debug && Pstream::master())
00095 {
00096 Pout<< "commSchedule::commSchedule : Wanted communication:" << endl;
00097
00098 forAll(comms, i)
00099 {
00100 const labelPair& twoProcs = comms[i];
00101
00102 Pout<< i << ": "
00103 << twoProcs[0] << " with " << twoProcs[1] << endl;
00104 }
00105 Pout<< endl;
00106
00107
00108 Pout<< "commSchedule::commSchedule : Schedule:" << endl;
00109
00110
00111
00112 {
00113 OStringStream os;
00114 os << "iter|";
00115 for (int i = 0; i < nProcs; i++)
00116 {
00117 os << setw(3) << i;
00118 }
00119 Pout<< os.str().c_str() << endl;
00120 }
00121 {
00122 OStringStream os;
00123 os << "----+";
00124 for (int i = 0; i < nProcs; i++)
00125 {
00126 os << "---";
00127 }
00128 Pout<< os.str().c_str() << endl;
00129 }
00130 }
00131
00132
00133
00134
00135 label nScheduled = 0;
00136
00137 label iter = 0;
00138
00139
00140 labelList commToSchedule(comms.size(), -1);
00141
00142 while (nScheduled < comms.size())
00143 {
00144 label oldNScheduled = nScheduled;
00145
00146
00147
00148
00149 boolList busy(nProcs, false);
00150
00151 while (true)
00152 {
00153 label maxCommI = -1;
00154 label maxNeed = labelMin;
00155
00156 forAll(comms, commI)
00157 {
00158 label proc0 = comms[commI][0];
00159 label proc1 = comms[commI][1];
00160
00161 if
00162 (
00163 commToSchedule[commI] == -1
00164 && !busy[proc0]
00165 && !busy[proc1]
00166 )
00167 {
00168 label need =
00169 outstandingComms(commToSchedule, procToComms[proc0])
00170 + outstandingComms(commToSchedule, procToComms[proc1]);
00171
00172 if (need > maxNeed)
00173 {
00174 maxNeed = need;
00175 maxCommI = commI;
00176 }
00177 }
00178 }
00179
00180
00181 if (maxCommI == -1)
00182 {
00183
00184 break;
00185 }
00186
00187
00188 commToSchedule[maxCommI] = nScheduled++;
00189 busy[comms[maxCommI][0]] = true;
00190 busy[comms[maxCommI][1]] = true;
00191 }
00192
00193 if (debug && Pstream::master())
00194 {
00195 label nIterComms = nScheduled-oldNScheduled;
00196
00197 if (nIterComms > 0)
00198 {
00199 labelList procToComm(nProcs, -1);
00200
00201 forAll(commToSchedule, commI)
00202 {
00203 label sched = commToSchedule[commI];
00204
00205 if (sched >= oldNScheduled && sched < nScheduled)
00206 {
00207 label proc0 = comms[commI][0];
00208 procToComm[proc0] = commI;
00209 label proc1 = comms[commI][1];
00210 procToComm[proc1] = commI;
00211 }
00212 }
00213
00214
00215 OStringStream os;
00216 os << setw(3) << iter << " |";
00217 forAll(procToComm, procI)
00218 {
00219 if (procToComm[procI] == -1)
00220 {
00221 os << " ";
00222 }
00223 else
00224 {
00225 os << setw(3) << procToComm[procI];
00226 }
00227 }
00228 Pout<< os.str().c_str() << endl;
00229 }
00230 }
00231
00232 iter++;
00233 }
00234
00235 if (debug && Pstream::master())
00236 {
00237 Pout<< endl;
00238 }
00239
00240
00241
00242 schedule_ = SortableList<label>(commToSchedule).indices();
00243
00244
00245
00246 labelList nProcScheduled(nProcs, 0);
00247
00248
00249 forAll(schedule_, i)
00250 {
00251 label commI = schedule_[i];
00252 const labelPair& twoProcs = comms[commI];
00253
00254 nProcScheduled[twoProcs[0]]++;
00255 nProcScheduled[twoProcs[1]]++;
00256 }
00257
00258 forAll(procSchedule_, procI)
00259 {
00260 procSchedule_[procI].setSize(nProcScheduled[procI]);
00261 }
00262 nProcScheduled = 0;
00263
00264 forAll(schedule_, i)
00265 {
00266 label commI = schedule_[i];
00267 const labelPair& twoProcs = comms[commI];
00268
00269 label proc0 = twoProcs[0];
00270 procSchedule_[proc0][nProcScheduled[proc0]++] = commI;
00271
00272 label proc1 = twoProcs[1];
00273 procSchedule_[proc1][nProcScheduled[proc1]++] = commI;
00274 }
00275
00276 if (debug && Pstream::master())
00277 {
00278 Pout<< "commSchedule::commSchedule : Per processor:" << endl;
00279
00280 forAll(procSchedule_, procI)
00281 {
00282 const labelList& procComms = procSchedule_[procI];
00283
00284 Pout<< "Processor " << procI << " talks to processors:" << endl;
00285
00286 forAll(procComms, i)
00287 {
00288 const labelPair& twoProcs = comms[procComms[i]];
00289
00290 label nbr = (twoProcs[1] == procI ? twoProcs[0] : twoProcs[1]);
00291
00292 Pout<< " " << nbr << endl;
00293 }
00294 }
00295 Pout<< endl;
00296 }
00297 }
00298
00299
00300