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
00027
00028
00029
00030
00031
00032
00034
00035
00036 #include "Field/Assign.h"
00037 #include "Field/AssignDefs.h"
00038 #include "Field/BareField.h"
00039 #include "Field/BrickExpression.h"
00040 #include "Field/IndexedBareField.h"
00041 #include "Field/LField.h"
00042 #include "Message/Communicate.h"
00043 #include "Message/Message.h"
00044 #include "Utility/PAssert.h"
00045 #include "Utility/IpplInfo.h"
00046 #include "Utility/IpplStats.h"
00047 #include "Profile/Profiler.h"
00048 #include "PETE/IpplExpressions.h"
00049
00050 #ifdef IPPL_STDSTL
00051 #include <map>
00052 #include <vector>
00053 #include <functional>
00054 #include <utility>
00055 using namespace std;
00056 #else
00057 #include <map.h>
00058 #include <vector.h>
00059 #include <function.h>
00060 #include <multimap.h>
00061 #endif
00062
00063 #ifdef IPPL_USE_STANDARD_HEADERS
00064 #include <iostream>
00065 #include <typeinfo>
00066 using namespace std;
00067 #else
00068 #include <iostream.h>
00069 #include <typeinfo.h>
00070 #endif
00071
00072
00074
00075
00076
00077
00078
00080
00081 template<class T1, unsigned Dim, class RHS, class Op>
00082 void
00083 assign(const BareField<T1,Dim>& clhs, RHS rhsp, Op op, ExprTag<false>)
00084 {
00085
00086
00087
00088 TAU_TYPE_STRING(p1, "void (" + CT(clhs) + ", " + CT(rhsp) + ", " + CT(op)
00089 + ", ExprTag<false> )" );
00090 TAU_PROFILE("assign()", p1.data(), TAU_ASSIGN | TAU_FIELD);
00091 TAU_PROFILE_TIMER(sendtimer, " assign[BareField]-send", p1.data(),
00092 TAU_ASSIGN);
00093 TAU_PROFILE_TIMER(findtimer, " assign[BareField]-findreceive", p1.data(),
00094 TAU_ASSIGN);
00095 TAU_PROFILE_TIMER(localstimer, " assign[BareField]-locals", p1.data(),
00096 TAU_ASSIGN);
00097 TAU_PROFILE_TIMER(rectimer, " assign[BareField]-receive", p1.data(),
00098 TAU_ASSIGN);
00099 TAU_PROFILE_TIMER(filltimer, " assign[BareField]-fill", p1.data(),
00100 TAU_ASSIGN);
00101
00102
00103
00104 ASSIGNMSG(Inform msg("NEW assign BF(f)", INFORM_ALL_NODES));
00105 ASSIGNMSG(msg << "Computing general assignment to BF[" << clhs.getDomain());
00106 ASSIGNMSG(msg << "] ..." << endl);
00107
00108
00109
00110
00111
00112 BareField<T1,Dim>& lhs = (BareField<T1,Dim>&) clhs ;
00113 typedef typename RHS::PETE_Return_t T2;
00114 const BareField<T2,Dim>& rhs( rhsp.GetBareField() );
00115
00116
00117 typedef typename LField<T1,Dim>::iterator LFI;
00118 typedef typename LField<T2,Dim>::iterator RFI;
00119 T1 lhs_compressed_data;
00120 T2 rhs_compressed_data;
00121 LFI lhs_i(lhs_compressed_data);
00122 RFI rhs_i(rhs_compressed_data);
00123
00124
00125 typename BareField<T1,Dim>::iterator_if lf_i, lf_e = lhs.end_if();
00126 typename BareField<T2,Dim>::const_iterator_if rf_i, rf_e = rhs.end_if();
00127
00128
00129 int tag = Ippl::Comm->next_tag( F_GEN_ASSIGN_TAG , F_TAG_CYCLE );
00130 int remaining = 0;
00131
00132
00133 typedef multimap< NDIndex<Dim> , LField<T1,Dim>* , less<NDIndex<Dim> > >
00134 ac_recv_type;
00135 ac_recv_type recv_ac;
00136
00137
00138
00139
00140
00141 int nprocs = Ippl::getNodes();
00142 ASSIGNMSG(msg << "Processing send-loop for " << nprocs << " nodes." << endl);
00143 if (nprocs > 1) {
00144
00145
00146 TAU_PROFILE_START(sendtimer);
00147 Message** mess = new Message*[nprocs];
00148 bool* recvmsg = new bool[nprocs];
00149 int iproc;
00150 for (iproc=0; iproc<nprocs; ++iproc) {
00151 mess[iproc] = 0;
00152 recvmsg[iproc] = false;
00153 }
00154 TAU_PROFILE_STOP(sendtimer);
00155
00156
00157 TAU_PROFILE_START(findtimer);
00158 for (lf_i = lhs.begin_if(); lf_i != lf_e; ++lf_i) {
00159
00160 LField<T1,Dim> &lf = *((*lf_i).second);
00161 const NDIndex<Dim> &la = lf.getAllocated();
00162
00163
00164 typename FieldLayout<Dim>::touch_range_dv
00165 range( rhs.getLayout().touch_range_rdv(la) );
00166 typename FieldLayout<Dim>::touch_iterator_dv rv_i;
00167 for (rv_i = range.first; rv_i != range.second; ++rv_i) {
00168
00169
00170 NDIndex<Dim> sub = la.intersect((*rv_i).first);
00171 typedef typename ac_recv_type::value_type value_type;
00172 recv_ac.insert( value_type(sub,&lf) );
00173
00174
00175 int rnode = (*rv_i).second->getNode();
00176 recvmsg[rnode] = true;
00177 }
00178 }
00179 TAU_PROFILE_STOP(findtimer);
00180
00181
00182 TAU_PROFILE_START(sendtimer);
00183 for (rf_i = rhs.begin_if(); rf_i != rf_e; ++rf_i) {
00184
00185 LField<T2,Dim> &rf = *((*rf_i).second);
00186 const NDIndex<Dim>& ro = rf.getOwned();
00187
00188
00189
00190 typename FieldLayout<Dim>::touch_range_dv
00191 range( lhs.getLayout().touch_range_rdv(ro,lhs.getGuardCellSizes()) );
00192 typename FieldLayout<Dim>::touch_iterator_dv remote_i;
00193 for (remote_i = range.first; remote_i != range.second; ++remote_i) {
00194
00195 NDIndex<Dim> intersection = ro.intersect( (*remote_i).first );
00196
00197
00198 int rnode = (*remote_i).second->getNode();
00199
00200
00201 rhs_i = rf.begin(intersection, rhs_compressed_data);
00202 rhs_i.TryCompress();
00203
00204
00205 if (mess[rnode] == 0)
00206 mess[rnode] = new Message;
00207 intersection.putMessage(*mess[rnode]);
00208 rhs_i.putMessage(*mess[rnode]);
00209 }
00210 }
00211 TAU_PROFILE_STOP(sendtimer);
00212
00213
00214 TAU_PROFILE_START(findtimer);
00215 for (iproc=0; iproc<nprocs; ++iproc)
00216 if (recvmsg[iproc]) ++remaining;
00217 delete [] recvmsg;
00218 TAU_PROFILE_STOP(findtimer);
00219
00220
00221 TAU_PROFILE_START(sendtimer);
00222 for (iproc=0; iproc<nprocs; ++iproc) {
00223 if (mess[iproc] != 0)
00224 Ippl::Comm->send(mess[iproc],iproc,tag);
00225 }
00226 delete [] mess;
00227 TAU_PROFILE_STOP(sendtimer);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236 ASSIGNMSG(msg << "Doing local fills for " << lhs.size_if());
00237 ASSIGNMSG(msg << " local lhs blocks and ");
00238 ASSIGNMSG(msg << rhs.size_if() << " local rhs blocks." << endl);
00239 TAU_PROFILE_START(localstimer);
00240 for (lf_i = lhs.begin_if(); lf_i != lf_e; ++lf_i) {
00241
00242 LField<T1,Dim> &lf = *(*lf_i).second;
00243 const NDIndex<Dim> &lo = lf.getOwned();
00244 const NDIndex<Dim> &la = lf.getAllocated();
00245
00246 ASSIGNMSG(msg << "----------------" << endl);
00247 ASSIGNMSG(msg << "Assigning to local LField with owned = " << lo);
00248 ASSIGNMSG(msg << ", allocated = " << la << endl);
00249
00250
00251 for (rf_i = rhs.begin_if(); rf_i != rf_e; ++rf_i) {
00252
00253 LField<T2,Dim> &rf = *(*rf_i).second;
00254 const NDIndex<Dim> &ro = rf.getOwned();
00255 const NDIndex<Dim> &ra = rf.getAllocated();
00256
00257
00258 if (la.touches(ro)) {
00259 ASSIGNMSG(msg << "Computing assignment of portion of rhs " << ro);
00260 ASSIGNMSG(msg << " to lhs " << la << endl);
00261
00262
00263
00264 bool c1 = rf.IsCompressed();
00265 bool c2 = lf.IsCompressed();
00266 bool c3 = ro.contains(lo);
00267 ASSIGNMSG(msg << "Checking for possible compressed-assign:");
00268 ASSIGNMSG(msg << "\n rf.IsCompressed = " << c1);
00269 ASSIGNMSG(msg << "\n lf.IsCompressed = " << c2);
00270 ASSIGNMSG(msg << "\n ro.contains(lo) = " << c3);
00271 ASSIGNMSG(msg << endl);
00272
00273
00274 if (c1 && c2 && c3) {
00275 ASSIGNMSG(msg << "LHS, RHS both compressed, and rhs contains lhs, ");
00276 ASSIGNMSG(msg << "compress." << endl);
00277 PETE_apply(op,*lf.begin(),*rf.begin());
00278 ASSIGNMSG(msg << "Now " << *lf.begin() << " == " << *rf.begin());
00279 ASSIGNMSG(msg << endl);
00280 } else {
00281
00282 NDIndex<Dim> intersection = la.intersect(ro);
00283 ASSIGNMSG(msg << "Intersection is " << intersection << endl);
00284
00285
00286 RFI rhs_i = rf.begin(intersection);
00287
00288
00289
00290
00291
00292 if (rhs_i.CanCompress(*rf.begin(intersection)) &&
00293 lhs.compressible() && intersection.containsAllPoints(la) &&
00294 OperatorTraits<Op>::IsAssign) {
00295
00296
00297 ASSIGNMSG(msg << "LHS BF is compressible, rhs_i compressed, ");
00298 ASSIGNMSG(msg << "intersection contains ");
00299 ASSIGNMSG(msg << la << ", assignment ==> compress assign.");
00300 ASSIGNMSG(msg << endl);
00301 lf.Compress((T1)(*rf.begin(intersection)));
00302 ASSIGNMSG(msg << "Now " << *lf.begin() << " == ");
00303 ASSIGNMSG(msg << *rf.begin(intersection) << endl);
00304
00305 } else {
00306
00307
00308
00309
00310
00311
00312
00313
00314 ASSIGNMSG(msg << "Cannot do compressed assign, so do loop."<<endl);
00315 ASSIGNMSG(msg << "First uncompress LHS LF ..." << endl);
00316 lf.Uncompress(!intersection.containsAllPoints(la));
00317
00318
00319 ASSIGNMSG(msg << "Get iterator for LHS ..." << endl);
00320 LFI lhs_i = lf.begin(intersection);
00321
00322
00323 ASSIGNMSG(msg << "And do expression evaluation." << endl);
00324 BrickExpression<Dim,LFI,RFI,Op>(lhs_i,rhs_i,op).apply();
00325 }
00326 }
00327 }
00328 }
00329 }
00330 TAU_PROFILE_STOP(localstimer);
00331
00332
00333
00334 ASSIGNMSG(msg << "Processing receive-loop for " << nprocs<<" nodes."<<endl);
00335 if (nprocs > 1) {
00336 TAU_PROFILE_START(rectimer);
00337 while (remaining>0) {
00338
00339 int any_node = COMM_ANY_NODE;
00340 Message *rmess = Ippl::Comm->receive_block(any_node,tag);
00341 PAssert(rmess != 0);
00342 --remaining;
00343
00344
00345 int ndoms = rmess->size() / (Dim+3);
00346 for (int idom=0; idom<ndoms; ++idom) {
00347
00348 NDIndex<Dim> intersection;
00349 intersection.getMessage(*rmess);
00350
00351
00352 T2 rhs_compressed_data;
00353 RFI rhs_i(rhs_compressed_data);
00354 rhs_i.getMessage(*rmess);
00355
00356
00357 typename ac_recv_type::iterator hit = recv_ac.find( intersection );
00358 PAssert( hit != recv_ac.end() );
00359
00360
00361 LField<T1,Dim> &lf = *(*hit).second;
00362 const NDIndex<Dim> &lo = lf.getOwned();
00363
00364
00365 if ( !(rhs_i.IsCompressed() && lf.IsCompressed() &&
00366 (*rhs_i == *lf.begin())) )
00367 {
00368
00369
00370 bool c2 = intersection.containsAllPoints(lo);
00371 bool c3 = OperatorTraits<Op>::IsAssign;
00372 lf.Uncompress( !(c2&&c3) );
00373 LFI lhs_i = lf.begin(intersection);
00374
00375
00376 BrickExpression<Dim,LFI,RFI,Op>(lhs_i,rhs_i,op).apply();
00377 }
00378
00379
00380 recv_ac.erase( hit );
00381 }
00382 delete rmess;
00383 }
00384 TAU_PROFILE_STOP(rectimer);
00385 }
00386
00387
00388 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
00389 TAU_PROFILE_START(filltimer);
00390 lhs.setDirtyFlag();
00391 lhs.fillGuardCellsIfNotDirty();
00392 TAU_PROFILE_STOP(filltimer);
00393
00394
00395 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
00396 lhs.Compress();
00397
00398
00399
00400 }
00401
00402
00403
00404
00405
00406