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
00033
00034
00035 #include "Field/Assign.h"
00036 #include "Field/AssignDefs.h"
00037 #include "Field/BareField.h"
00038 #include "Field/BrickExpression.h"
00039 #include "Field/IndexedBareField.h"
00040 #include "Field/LField.h"
00041 #include "Message/Communicate.h"
00042 #include "Message/Message.h"
00043 #include "Utility/PAssert.h"
00044 #include "Utility/IpplInfo.h"
00045 #include "Utility/IpplStats.h"
00046 #include "Profile/Profiler.h"
00047 #include "PETE/IpplExpressions.h"
00048
00049 #ifdef IPPL_STDSTL
00050 #include <map>
00051 #include <vector>
00052 #include <functional>
00053 #include <utility>
00054 using namespace std;
00055 #else
00056 #include <map.h>
00057 #include <vector.h>
00058 #include <function.h>
00059 #include <multimap.h>
00060 #endif
00061
00062 #ifdef IPPL_USE_STANDARD_HEADERS
00063 #include <iostream>
00064 #include <typeinfo>
00065 using namespace std;
00066 #else
00067 #include <iostream.h>
00068 #include <typeinfo.h>
00069 #endif
00070
00071
00073
00074
00075
00076
00077
00078
00080
00081 template<class T, unsigned Dim, class A, class Op>
00082 bool
00083 TryCompressLHS(LField<T,Dim>& lf, A& rhs, Op op, const NDIndex<Dim>& domain)
00084 {
00085
00086
00087
00088 TAU_TYPE_STRING(taustr, "bool (" + CT(lf) + ", " + CT(rhs) + ", " +
00089 CT(Op) + ", " + CT(domain) + " )" );
00090 TAU_PROFILE("TryCompressLHS()", taustr, TAU_ASSIGN | TAU_FIELD);
00091
00092
00093 if (IpplInfo::noFieldCompression)
00094 return(false);
00095
00096
00097
00098 ASSIGNMSG(Inform msg("TryCompressLHS", INFORM_ALL_NODES));
00099 ASSIGNMSG(msg << "Checking for compressibility of LField with domain = ");
00100 ASSIGNMSG(msg << lf.getOwned() << " over assignment domain = " << domain);
00101 ASSIGNMSG(msg << endl);
00102
00103
00104
00105
00106
00107
00108 bool c1 = for_each(rhs,IsCompressed(),PETE_AndCombiner());
00109 bool c2 = domain.containsAllPoints(lf.getOwned());
00110 bool c3 = OperatorTraits<Op>::IsAssign;
00111 bool c4 = lf.IsCompressed();
00112 bool compress = c1 && c2 && ( c3 || c4 );
00113
00114 ASSIGNMSG(msg << " RHS IsCompressed() = " << c1 << endl);
00115 ASSIGNMSG(msg << " LHS IsCompressed() = " << c4 << endl);
00116 ASSIGNMSG(msg << "domain.contains(lhs) = " << c2 << endl);
00117 ASSIGNMSG(msg << " IsAssign = " << c3 << endl);
00118 ASSIGNMSG(msg << " result = " << compress << endl);
00119
00120
00121 if (compress)
00122 {
00123
00124
00125 ASSIGNMSG(msg << "Yes we CAN compress, so do so now ... ");
00126 lf.Compress();
00127 ASSIGNMSG(msg << "now, compressed value = " << *lf.begin() << endl);
00128 return true;
00129 }
00130
00131
00132
00133
00134
00135
00136 if (c1 && c3 && c4)
00137 {
00138 T tmpval;
00139 PETE_apply(op, tmpval, for_each(rhs, EvalFunctor_0()));
00140 if (*lf.begin() == tmpval)
00141 {
00142
00143
00144
00145
00146 ASSIGNMSG(msg << "LHS and RHS are compressed, doing assign, and ");
00147 ASSIGNMSG(msg << *lf.begin() << " == " <<tmpval<<", so result = 1");
00148 ASSIGNMSG(msg << endl);
00149 return true;
00150 }
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 ASSIGNMSG(msg << "No we cannot compress, so make sure we're ");
00162 ASSIGNMSG(msg << "uncompressed. Fill domain? " << !(c3&&c2) << endl);
00163 lf.Uncompress( !(c3 && c2) );
00164 return false;
00165 }
00166
00167
00169
00170
00171
00172
00173
00174
00175
00176
00178
00179 template<class Expr>
00180 class ParensIterator : public Expr
00181 {
00182 public:
00183 typedef typename Expr::PETE_Return_t PETE_Return_t;
00184
00185 ParensIterator( const Expr& e ) : Expr(e) {}
00186 PETE_Return_t& operator*() const
00187 {
00188 return (*Expr::Child)(Expr::Value.Arg);
00189 }
00190 PETE_Return_t& offset(int i) const
00191 {
00192 return Expr::Child.offset(i)(Expr::Value.Arg);
00193 }
00194 PETE_Return_t& offset(int i, int j) const
00195 {
00196 return Expr::Child.offset(i,j)(Expr::Value.Arg);
00197 }
00198 PETE_Return_t& offset(int i, int j, int k) const
00199 {
00200 return Expr::Child.offset(i,j,k)(Expr::Value.Arg);
00201 }
00202
00203 PETE_Return_t& operator*()
00204 {
00205 return (*Expr::Child)(Expr::Value.Arg);
00206 }
00207 PETE_Return_t& offset(int i)
00208 {
00209 return Expr::Child.offset(i)(Expr::Value.Arg);
00210 }
00211 PETE_Return_t& offset(int i, int j)
00212 {
00213 return Expr::Child.offset(i,j)(Expr::Value.Arg);
00214 }
00215 PETE_Return_t& offset(int i, int j, int k)
00216 {
00217 return Expr::Child.offset(i,j,k)(Expr::Value.Arg);
00218 }
00219 PETE_Return_t& unit_offset(int i)
00220 {
00221 return Expr::Child.unit_offset(i)(Expr::Value.Arg);
00222 }
00223 PETE_Return_t& unit_offset(int i, int j)
00224 {
00225 return Expr::Child.unit_offset(i,j)(Expr::Value.Arg);
00226 }
00227 PETE_Return_t& unit_offset(int i, int j, int k)
00228 {
00229 return Expr::Child.unit_offset(i,j,k)(Expr::Value.Arg);
00230 }
00231
00232 void step(unsigned d)
00233 {
00234 Expr::Child.step(d);
00235 }
00236 void rewind(unsigned d)
00237 {
00238 Expr::Child.rewind(d);
00239 }
00240 int size(unsigned d) const
00241 {
00242 return Expr::Child.size(d);
00243 }
00244 int done(unsigned d) const
00245 {
00246 return Expr::Child.done(d);
00247 }
00248 int Stride(int d) const
00249 {
00250 return Expr::Child.Stride(d);
00251 }
00252 };
00253
00254
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00269
00270 template<class T1, unsigned Dim, class RHS, class OP>
00271 void
00272 assign(const IndexedBareField<T1,Dim,Dim> &aa, RHS b, OP op, ExprTag<true>,
00273 bool fillGC)
00274 {
00275 IndexedBareField<T1,Dim,Dim> &a =
00276 const_cast<IndexedBareField<T1,Dim,Dim>&>(aa);
00277
00278
00279
00280
00281 TAU_TYPE_STRING(p1, "void (" + CT(a) + ", " + CT(b) + ", " + CT(op)
00282 + ", ExprTag<true> )" );
00283 TAU_PROFILE("assign()", p1.data(), TAU_ASSIGN | TAU_FIELD);
00284 TAU_PROFILE_TIMER(looptimer, " assign[IndexedBareField]-vnodeloop",
00285 p1.data(), TAU_ASSIGN);
00286 TAU_PROFILE_TIMER(filltimer, " assign[IndexedBareField]-guardfill",
00287 p1.data(), TAU_ASSIGN);
00288
00289
00290
00291 ASSIGNMSG(Inform msg("assign IBF(t)", INFORM_ALL_NODES));
00292 ASSIGNMSG(msg << "Computing assignment to IBF[" << aa.getDomain());
00293 ASSIGNMSG(msg << "] ..." << endl);
00294
00295
00296
00297 int lhs_id = a.getBareField().get_Id();
00298 typename RHS::Wrapped& bb = b.PETE_unwrap();
00299 bool both_sides = for_each(bb,SameFieldID(lhs_id),PETE_OrCombiner());
00300
00301
00302 ASSIGNMSG(msg << "Checking whether to fill GC's on RHS ..." << endl);
00303 for_each(bb, FillGCIfNecessary(a.getBareField()), PETE_NullCombiner());
00304
00305
00306 typename BareField<T1,Dim>::iterator_if la = a.getBareField().begin_if();
00307 typename BareField<T1,Dim>::iterator_if aend = a.getBareField().end_if();
00308
00309
00310
00311
00312
00313
00314 a.getBareField().setDirtyFlag();
00315
00316
00317 TAU_PROFILE_START(looptimer);
00318 int lfcount=0;
00319 bool needFinalCompressCheck = false;
00320 while (la != aend)
00321 {
00322
00323 LField<T1,Dim> *lf = (*la).second.get();
00324
00325
00326 if ( both_sides ) {
00327 lf = new LField<T1,Dim>( *lf );
00328 ASSIGNMSG(msg << "For lf " << lfcount << ": making lfield copy.");
00329 ASSIGNMSG(msg << endl);
00330 }
00331
00332
00333
00334 NDIndex<Dim> local_domain = a.getDomain().intersect( lf->getOwned() );
00335
00336
00337 if ( ! local_domain.empty() )
00338 {
00339
00340
00341
00342 typedef typename LField<T1,Dim>::iterator LHS;
00343 typedef BrickExpression<Dim,LHS,typename RHS::Wrapped,OP> ExprT;
00344
00345
00346
00347
00348
00349 ASSIGNMSG(msg << "For lf " << lfcount << ": plugbase on ");
00350 ASSIGNMSG(msg << local_domain << endl);
00351 if ( for_each(bb,PlugBase<Dim>( local_domain ), PETE_AndCombiner()) )
00352 {
00353 ASSIGNMSG(msg << "For lf " << lfcount << " with owned domain ");
00354 ASSIGNMSG(msg << lf->getOwned() << " assigned intersection ");
00355 ASSIGNMSG(msg << local_domain << " : ");
00356
00357 if (a.getBareField().compressible() &&
00358 TryCompressLHS(*lf,bb,op,local_domain) ) {
00359
00360 ASSIGNMSG(msg << "compressed assign, changing ");
00361 ASSIGNMSG(msg << *(lf->begin()));
00362
00363
00364
00365
00366 PETE_apply(op, *(lf->begin()), for_each(bb,EvalFunctor_0()));
00367 ASSIGNMSG(msg << " to " << *(lf->begin()) << endl);
00368 } else {
00369
00370 ASSIGNMSG(msg << "loop assign." << endl);
00371
00372
00373 ExprT expr(lf->begin(local_domain), bb);
00374 expr.apply();
00375
00376
00377
00378
00379
00380
00381 if (IpplInfo::extraCompressChecks) {
00382 ASSIGNMSG(msg << "For lf " << lfcount);
00383 ASSIGNMSG(msg << ": doing extra post-compute ");
00384 ASSIGNMSG(msg << "compression check ..." << endl);
00385 lf->TryCompress(a.getBareField().isDirty());
00386 } else {
00387 needFinalCompressCheck = true;
00388 }
00389 }
00390 }
00391 else
00392 {
00393 ERRORMSG("All Fields in an expression must be aligned. ");
00394 ERRORMSG("(Do you have enough guard cells?)" << endl);
00395 ERRORMSG("This error occurred while evaluating an expression ");
00396 ERRORMSG("for an LField with domain " << lf->getOwned() << endl);
00397 Ippl::abort();
00398 }
00399 }
00400
00401
00402
00403 if ( both_sides )
00404 {
00405 ASSIGNMSG(msg << "For lf " << lfcount << ": swapping lfield data.");
00406 ASSIGNMSG(msg << endl);
00407 ASSIGNMSG(msg << "For lf " << lfcount << ": at beg, lfield=" << *lf);
00408 ASSIGNMSG(msg << endl);
00409 (*la).second->swapData( *lf );
00410 delete lf;
00411 ASSIGNMSG(msg << "For lf " << lfcount << ": at end, lfield=");
00412 ASSIGNMSG(msg << *((*la).second) << endl);
00413 }
00414
00415 ++la;
00416 ++lfcount;
00417 }
00418 TAU_PROFILE_STOP(looptimer);
00419
00420
00421
00422
00423 if (fillGC) {
00424 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
00425 TAU_PROFILE_START(filltimer);
00426 a.getBareField().fillGuardCellsIfNotDirty();
00427 TAU_PROFILE_STOP(filltimer);
00428 }
00429
00430
00431 if (fillGC && needFinalCompressCheck) {
00432 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
00433 a.getBareField().Compress();
00434 }
00435
00436
00437
00438 }
00439
00440
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00453
00454 template<class A, class RHS, class OP, class Tag, class TP>
00455 void
00456 assign(PETE_TUTree<OpParens<TP>,A> lhs, RHS wrhs, OP op, Tag,
00457 bool fillGC)
00458 {
00459
00460
00461
00462 TAU_PROFILE_STMT(Tag tauTag);
00463 TAU_TYPE_STRING(p1, "void (" + CT(lhs) + ", " + CT(wrhs) + ", " + CT(op)
00464 + ", " + CT(tauTag) + " )" );
00465 TAU_PROFILE("assign()", p1.data(), TAU_ASSIGN | TAU_FIELD);
00466 TAU_PROFILE_TIMER(looptimer, " assign[TUTree]-vnodeloop", p1.data(),
00467 TAU_ASSIGN);
00468 TAU_PROFILE_TIMER(filltimer, " assign[TUTree]-guardfill", p1.data(),
00469 TAU_ASSIGN);
00470
00471
00472
00473 ASSIGNMSG(Inform msg("assign Parens", INFORM_ALL_NODES));
00474 ASSIGNMSG(msg << "Computing assignment to IBF[" << lhs.Child.getDomain());
00475 ASSIGNMSG(msg << "](" << lhs.Value.Arg << ") ..." << endl);
00476
00477 enum { Dim = A::Dim_u };
00478 typedef typename A::return_type T1;
00479
00480 typedef typename Expressionize<RHS>::type::Wrapped RHS_Wrapped;
00481 typename Expressionize<RHS>::type expr = Expressionize<RHS>::apply(wrhs);
00482 RHS_Wrapped & rhs = expr.PETE_unwrap();
00483
00484
00485
00486 BareField<T1,Dim>& bare = lhs.Child.getBareField();
00487 const NDIndex<Dim> &total_domain = lhs.Child.getDomain();
00488
00489
00490
00491 bool both_sides = for_each(rhs,SameFieldID(bare.get_Id()),PETE_OrCombiner());
00492
00493
00494 ASSIGNMSG(msg << "Checking whether to fill GC's on RHS ..." << endl);
00495 for_each(rhs, FillGCIfNecessary(bare), PETE_NullCombiner());
00496
00497
00498 typename BareField<T1,Dim>::iterator_if la = bare.begin_if();
00499 typename BareField<T1,Dim>::iterator_if aend = bare.end_if();
00500
00501
00502
00503
00504
00505 bare.setDirtyFlag();
00506
00507
00508 TAU_PROFILE_START(looptimer);
00509 bool needFinalCompressCheck = false;
00510 while (la != aend)
00511 {
00512
00513 LField<T1,Dim> *lf = (*la).second.get();
00514 const NDIndex<Dim> &lo = lf->getOwned();
00515
00516
00517
00518 NDIndex<Dim> local_domain = total_domain.intersect(lo);
00519
00520
00521 if (!local_domain.empty())
00522 {
00523
00524
00525
00526 typedef typename LField<T1,Dim>::iterator LA;
00527 typedef PETE_TUTree<OpParens<TP>,LA> LHS;
00528 typedef BrickExpression<Dim,ParensIterator<LHS>,RHS_Wrapped,OP>
00529 ExprT;
00530
00531
00532
00533
00534 ASSIGNMSG(msg << "For lf " << lo << ": plugbase on ");
00535 ASSIGNMSG(msg << local_domain << endl);
00536 if (for_each(rhs, PlugBase<Dim>(local_domain), PETE_AndCombiner()))
00537 {
00538
00539
00540
00541
00542 bool c1 = for_each(rhs, IsCompressed(), PETE_AndCombiner());
00543 bool c2 = local_domain.containsAllPoints(lo);
00544 bool c3 = lf->IsCompressed();
00545 if (bare.compressible() && c1 && c2 && c3) {
00546
00547
00548
00549
00550 ASSIGNMSG(msg << "Compressed assign on ");
00551 ASSIGNMSG(msg << local_domain << ", changing "<< *lf->begin());
00552 const ParensIterator<LHS> ilhs = LHS(lhs.Value, lf->begin());
00553 PETE_apply(op, *ilhs, for_each(rhs, EvalFunctor_0()));
00554 ASSIGNMSG(msg << " to " << *lf->begin() << endl);
00555
00556 } else {
00557 ASSIGNMSG(msg << "Loop assign on " << local_domain << endl);
00558
00559
00560
00561
00562
00563 lf->Uncompress();
00564
00565
00566 const ParensIterator<LHS> ilhs =
00567 LHS(lhs.Value, lf->begin(local_domain));
00568 ExprT expr(ilhs, rhs, op);
00569 expr.apply();
00570
00571
00572
00573 if (IpplInfo::extraCompressChecks) {
00574 ASSIGNMSG(msg << "Doing extra post-compute ");
00575 ASSIGNMSG(msg << "compression check ..." << endl);
00576 lf->TryCompress(bare.isDirty());
00577 } else {
00578 needFinalCompressCheck = true;
00579 }
00580 }
00581 }
00582 else
00583 {
00584 ERRORMSG("All Fields in an expression must be aligned. ");
00585 ERRORMSG("(Do you have enough guard cells?)" << endl);
00586 ERRORMSG("This error occurred while evaluating an expression ");
00587 ERRORMSG("for an LField with domain ");
00588 ERRORMSG((*la).second->getOwned() << endl);
00589 Ippl::abort();
00590 }
00591 }
00592 ++la;
00593 }
00594 TAU_PROFILE_STOP(looptimer);
00595
00596
00597
00598 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
00599 if (fillGC) {
00600 TAU_PROFILE_START(filltimer);
00601 bare.fillGuardCellsIfNotDirty();
00602 TAU_PROFILE_STOP(filltimer);
00603 }
00604
00605
00606 if (fillGC && needFinalCompressCheck) {
00607 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
00608 bare.Compress();
00609 }
00610
00611
00612
00613 }
00614
00615
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00630
00631 template<class T1, unsigned Dim, class RHS, class OP>
00632 void
00633 assign(const BareField<T1,Dim>& ca, RHS b, OP op, ExprTag<true>)
00634 {
00635
00636
00637
00638 TAU_TYPE_STRING(p1, "void (" + CT(ca) + ", " + CT(b) + ", " +
00639 CT(op) + ", ExprTag<true> )" );
00640 TAU_PROFILE("assign()", p1.data(), TAU_ASSIGN | TAU_FIELD);
00641 TAU_PROFILE_TIMER(looptimer, " assign[BareField]-vnodeloop", p1.data(),
00642 TAU_ASSIGN);
00643 TAU_PROFILE_TIMER(filltimer, " assign[BareField]-guardfill", p1.data(),
00644 TAU_ASSIGN);
00645
00646
00647
00648 ASSIGNMSG(Inform msg("assign BF(t)", INFORM_ALL_NODES));
00649 ASSIGNMSG(msg << "Computing assignment to BF[" << ca.getDomain());
00650 ASSIGNMSG(msg << "] ..." << endl);
00651
00652
00653
00654 BareField<T1,Dim>& a = const_cast<BareField<T1,Dim>&>(ca);
00655 typename RHS::Wrapped& bb = b.PETE_unwrap();
00656
00657
00658 typedef typename LField<T1,Dim>::iterator It;
00659 typedef BrickExpression<Dim,It,typename RHS::Wrapped,OP> ExprT;
00660 typename BareField<T1,Dim>::iterator_if la = a.begin_if();
00661 typename BareField<T1,Dim>::iterator_if aend = a.end_if();
00662
00663
00664
00665
00666
00667 a.setDirtyFlag();
00668
00669
00670 TAU_PROFILE_START(looptimer);
00671 int lfcount = 0;
00672 bool needFinalCompressCheck = false;
00673 while (la != aend)
00674 {
00675
00676
00677
00678
00679 LField<T1,Dim>& lf = *(*la).second;
00680 for_each(bb, BeginLField(), PETE_NullCombiner());
00681
00682 ASSIGNMSG(msg << "For lf " << lfcount << " with domain ");
00683 ASSIGNMSG(msg << lf.getOwned() << " : ");
00684
00685
00686
00687 if (a.compressible() && TryCompressLHS(lf, bb, op, a.getDomain())) {
00688 ASSIGNMSG(msg << "compressed assign, changing " << *lf.begin());
00689 PETE_apply(op,*lf.begin(),for_each(bb,EvalFunctor_0()));
00690 ASSIGNMSG(msg << " to " << *lf.begin() << endl);
00691 } else {
00692 ASSIGNMSG(msg << "loop assign." << endl);
00693
00694
00695 ExprT expr(lf.begin(),bb,op);
00696 expr.apply();
00697
00698
00699
00700
00701
00702
00703 if (IpplInfo::extraCompressChecks) {
00704 ASSIGNMSG(msg << "For lf " << lfcount);
00705 ASSIGNMSG(msg << ": doing extra post-compute ");
00706 ASSIGNMSG(msg << "compression check ..." << endl);
00707 lf.TryCompress(a.isDirty());
00708 } else {
00709 needFinalCompressCheck = true;
00710 }
00711 }
00712
00713 ++la;
00714 for_each(bb,NextLField(),PETE_NullCombiner());
00715 ++lfcount;
00716 }
00717 TAU_PROFILE_STOP(looptimer);
00718
00719
00720
00721 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
00722 TAU_PROFILE_START(filltimer);
00723 a.fillGuardCellsIfNotDirty();
00724 TAU_PROFILE_STOP(filltimer);
00725
00726
00727 if (needFinalCompressCheck) {
00728 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
00729 a.Compress();
00730 }
00731
00732
00733
00734
00735 }
00736
00737
00738
00739
00740
00741
00742