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
00027 #include "Index/SIndexAssign.h"
00028 #include "Index/SIndex.h"
00029 #include "Field/BrickIterator.h"
00030 #include "Field/Field.h"
00031 #include "Field/IndexedField.h"
00032 #include "Field/Assign.h"
00033 #include "Utility/IpplInfo.h"
00034 #include "Profile/Profiler.h"
00035
00036
00038
00039
00040 template<unsigned int Dim, class OP>
00041 class SIndexAssignTraits { };
00042
00043
00045
00046
00047
00048 template<unsigned int Dim>
00049 class SIndexAssignTraits<Dim, OpAssign> {
00050 public:
00051
00052 static void initialize(SIndex<Dim>& s) { s.clear(); }
00053
00054
00055
00056 static void apply(SIndex<Dim>& SI,
00057 typename SIndex<Dim>::iterator_iv& LSI,
00058 const SOffset<Dim>& SO,
00059 bool result) {
00060 TAU_TYPE_STRING(taustr, "void (" + CT(SI) + ", " + CT(LSI) + ", " + CT(SO)
00061 + ", bool)" );
00062 TAU_PROFILE("SIndexAssignTraits::apply()", taustr,
00063 TAU_SPARSE | TAU_ASSIGN);
00064 if (result) {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 (*LSI)->addIndex(SO);
00077 }
00078 }
00079 };
00080
00081
00083
00084
00085
00086 template<unsigned int Dim>
00087 class SIndexAssignTraits<Dim, OpBitwiseAndAssign> {
00088 public:
00089
00090 static void initialize(SIndex<Dim>&) { }
00091
00092
00093
00094 static void apply(SIndex<Dim>& SI,
00095 typename SIndex<Dim>::iterator_iv& LSI,
00096 const SOffset<Dim>& SO,
00097 bool result) {
00098 TAU_TYPE_STRING(taustr, "void (" + CT(SI) + ", " + CT(LSI) + ", " + CT(SO)
00099 + ", bool)" );
00100 TAU_PROFILE("SIndexAssignTraits::apply()", taustr,
00101 TAU_SPARSE | TAU_ASSIGN);
00102 if (!result && (*LSI)->hasIndex(SO)) {
00103
00104
00105
00106
00107 SI.removeIndex(LSI, SO);
00108 }
00109 }
00110 };
00111
00112
00114
00115
00116
00117 template<unsigned int Dim>
00118 class SIndexAssignTraits<Dim, OpBitwiseOrAssign> {
00119 public:
00120
00121 static void initialize(SIndex<Dim>&) { }
00122
00123
00124
00125 static void apply(SIndex<Dim>& SI,
00126 typename SIndex<Dim>::iterator_iv& LSI,
00127 const SOffset<Dim>& SO,
00128 bool result) {
00129 TAU_TYPE_STRING(taustr, "void (" + CT(SI) + ", " + CT(LSI) + ", " + CT(SO)
00130 + ", bool)" );
00131 TAU_PROFILE("SIndexAssignTraits::apply()", taustr,
00132 TAU_SPARSE | TAU_ASSIGN);
00133 if (result && ! (*LSI)->hasIndex(SO)) {
00134
00135
00136
00137
00138 SI.addIndex(LSI, SO);
00139 }
00140 }
00141 };
00142
00143
00145
00146
00147 template<class OP, unsigned int Dim>
00148 class SIndexExpLoop {
00149 public:
00150
00151 template<class RHS>
00152 static void evaluate(SIndex<Dim>& si, typename SIndex<Dim>::iterator_iv& lsi,
00153 NDIndex<Dim>& dom, RHS& Rhs) {
00154 TAU_TYPE_STRING(taustr, "void (" + CT(si) + ", " + CT(lsi) + ", "
00155 + CT(dom) + ", " + CT(Rhs) + " )" );
00156 TAU_PROFILE("SIndexExpLoop::evaluate()", taustr, TAU_SPARSE);
00157 int n0 = dom[0].length();
00158 int n1 = dom[1].length();
00159 int n2 = dom[2].length();
00160 if (n0 > 0 && n1 > 0 && n2 > 0) {
00161 BrickCounter<Dim> count(dom);
00162 ERRORMSG("changed from cdom to dom, cdom does not make sense! (SindexAssign.cpp)" << endl);
00163
00164 unsigned d;
00165 SOffset<Dim> so;
00166 for (d=3; d < Dim; ++d)
00167 so[d] = dom[d].first();
00168 do {
00169 Index::iterator x2 = dom[2].begin();
00170 for (int i2=0; i2<n2; ++i2, ++x2) {
00171 so[2] = *x2;
00172 Index::iterator x1 = dom[1].begin();
00173 for (int i1=0; i1<n1; ++i1, ++x1) {
00174 so[1] = *x1;
00175 Index::iterator x0 = dom[0].begin();
00176 for (int i0=0; i0<n0; ++i0, ++x0) {
00177 so[0] = *x0;
00178 bool result = (for_each(Rhs, EvalFunctor_3(i0,i1,i2)) != false);
00179 SIndexAssignTraits<3U,OP>::apply(si, lsi, so, result);
00180 }
00181 }
00182 }
00183
00184 for (d=3; d<Dim; ++d) {
00185 count.step(d);
00186 so[d] += dom[d].stride();
00187 for_each(Rhs,StepFunctor(d),PETE_NullCombiner());
00188 if ( ! count.done(d) )
00189 break;
00190 count.rewind(d);
00191 so[d] = dom[d].first();
00192 for_each(Rhs,RewindFunctor(d),PETE_NullCombiner());
00193 }
00194
00195 } while (d<Dim);
00196 }
00197 }
00198 };
00199
00200
00202
00203
00204 template<class OP>
00205 class SIndexExpLoop<OP,1U> {
00206 public:
00207 template<class RHS>
00208 static void evaluate(SIndex<1U>& si, SIndex<1U>::iterator_iv& lsi,
00209 NDIndex<1U>& dom, RHS& Rhs) {
00210 TAU_TYPE_STRING(taustr, "void (" + CT(si) + ", " + CT(lsi) + ", " + CT(dom)
00211 + ", " + CT(Rhs) + " )" );
00212 TAU_PROFILE("SIndexExpLoop::evaluate()", taustr, TAU_SPARSE );
00213 int n0 = dom[0].length();
00214 if (n0 > 0) {
00215 Index::iterator x0 = dom[0].begin();
00216 for (int i0 = 0; i0 < n0; ++i0, ++x0) {
00217 bool result = (for_each(Rhs, EvalFunctor_1(i0)) != false);
00218 SIndexAssignTraits<1U,OP>::apply(si, lsi, SOffset<1>(*x0), result);
00219 }
00220 }
00221 }
00222 };
00223
00224
00226
00227
00228 template<class OP>
00229 class SIndexExpLoop<OP,2U> {
00230 public:
00231 template<class RHS>
00232 static void evaluate(SIndex<2U>& si, SIndex<2U>::iterator_iv& lsi,
00233 NDIndex<2U>& dom, RHS& Rhs) {
00234 TAU_TYPE_STRING(taustr, "void (" + CT(si) + ", " + CT(lsi) + ", " + CT(dom)
00235 + ", " + CT(Rhs) + " )" );
00236 TAU_PROFILE("SIndexExpLoop::evaluate()", taustr, TAU_SPARSE );
00237 int n0 = dom[0].length();
00238 int n1 = dom[1].length();
00239 if (n0 > 0 && n1 > 0) {
00240 Index::iterator x1 = dom[1].begin();
00241 for (int i1 = 0; i1 < n1; ++i1, ++x1) {
00242 Index::iterator x0 = dom[0].begin();
00243 for (int i0 = 0; i0 < n0; ++i0, ++x0) {
00244 bool result = (for_each(Rhs, EvalFunctor_2(i0,i1)) != false);
00245 SIndexAssignTraits<2U,OP>::apply(si, lsi, SOffset<2>(*x0, *x1),
00246 result);
00247 }
00248 }
00249 }
00250 }
00251 };
00252
00253
00255
00256
00257 template<class OP>
00258 class SIndexExpLoop<OP,3U> {
00259 public:
00260 template<class RHS>
00261 static void evaluate(SIndex<3U>& si, SIndex<3U>::iterator_iv& lsi,
00262 NDIndex<3U>& dom, RHS& Rhs) {
00263 TAU_TYPE_STRING(taustr, "void (" + CT(si) + ", " + CT(lsi) + ", " + CT(dom)
00264 + ", " + CT(Rhs) + " )" );
00265 TAU_PROFILE("SIndexExpLoop::evaluate()", taustr, TAU_SPARSE );
00266 int n0 = dom[0].length();
00267 int n1 = dom[1].length();
00268 int n2 = dom[2].length();
00269 if (n0 > 0 && n1 > 0 && n2 > 0) {
00270 Index::iterator x2 = dom[2].begin();
00271 for (int i2 = 0; i2 < n2; ++i2, ++x2) {
00272 Index::iterator x1 = dom[1].begin();
00273 for (int i1 = 0; i1 < n1; ++i1, ++x1) {
00274 Index::iterator x0 = dom[0].begin();
00275 for (int i0 = 0; i0 < n0; ++i0, ++x0) {
00276 bool result = (for_each(Rhs, EvalFunctor_3(i0,i1,i2)) != false);
00277 SIndexAssignTraits<3U,OP>::apply(si, lsi,
00278 SOffset<3>(*x0, *x1, *x2),
00279 result);
00280 }
00281 }
00282 }
00283 }
00284 }
00285 };
00286
00287
00289
00290
00291
00292
00293
00294
00295
00296 template<unsigned Dim, class T>
00297 struct AssignActions { };
00298
00299 template<unsigned Dim>
00300 struct AssignActions<Dim, SIExprTag<true> > {
00301 template<class RHS>
00302 static void fillgc(RHS &bb, const NDIndex<Dim> &domain) {
00303
00304
00305 for_each(bb, FillGCIfNecessary(FGCINTag<Dim,double>()), PETE_NullCombiner());
00306 }
00307
00308 template<class RHS>
00309 static bool plugbase(RHS &bb, const NDIndex<Dim> &domain) {
00310
00311
00312 return for_each(bb, PlugBase<Dim>(domain), PETE_AndCombiner());
00313 }
00314
00315 template<class RHS>
00316 static void nextLField(RHS &) {
00317
00318
00319 }
00320 };
00321
00322 template<unsigned Dim>
00323 struct AssignActions<Dim, SIExprTag<false> > {
00324 template<class RHS>
00325 static void fillgc(RHS &bb, const NDIndex<Dim> &) {
00326
00327
00328
00329 for_each(bb, FillGCIfNecessary(FGCINTag<Dim,double>()), PETE_NullCombiner());
00330
00331 }
00332
00333 template<class RHS>
00334 static bool plugbase(RHS &bb, const NDIndex<Dim> &) {
00335
00336 for_each(bb, BeginLField(), PETE_NullCombiner());
00337 return true;
00338 }
00339
00340 template<class RHS>
00341 static void nextLField(RHS &bb) {
00342
00343 for_each(bb, NextLField(), PETE_NullCombiner());
00344 }
00345 };
00346
00347
00349
00350
00351
00352 template<unsigned Dim, class RHS, class Op, bool IsExpr>
00353 void assign(SIndex<Dim>& a, RHS b, Op, const NDIndex<Dim> &domain,
00354 SIExprTag<IsExpr> isexpr) {
00355 TAU_PROFILE_STMT(Op oper);
00356 TAU_TYPE_STRING(taustr, "void (" + CT(a) + ", " + CT(b) + CT(oper) + " )");
00357 TAU_PROFILE("assign()", taustr, TAU_SPARSE | TAU_ASSIGN);
00358
00359
00360
00361
00362
00363 typename RHS::Wrapped& bb = b.PETE_unwrap();
00364
00365
00366 SIndexAssignTraits<Dim,Op>::initialize(a);
00367
00368
00369 AssignActions<Dim,SIExprTag<IsExpr> >::fillgc(bb, domain);
00370
00371
00372
00373 typename SIndex<Dim>::iterator_iv la = a.begin_iv();
00374 typename SIndex<Dim>::iterator_iv aend = a.end_iv();
00375 for ( ; la != aend; ++la ) {
00376
00377 NDIndex<Dim> locdomain = domain.intersect((*la)->getDomain());
00378
00379
00380
00381
00382 if (!locdomain.empty()) {
00383
00384
00385
00386 if (AssignActions<Dim,SIExprTag<IsExpr> >::plugbase(bb, locdomain)) {
00387
00388
00389 if (OperatorTraits<Op>::IsAssign && locdomain == (*la)->getDomain() &&
00390 for_each(bb, IsCompressed(), PETE_AndCombiner())) {
00391
00392
00393 bool result = (for_each(bb, EvalFunctor_0()) != false);
00394 (*la)->Compress(result);
00395
00396
00397
00398
00399 } else {
00400
00401
00402
00403 SIndexExpLoop<Op,Dim>::evaluate(a, la, locdomain, bb);
00404
00405
00406
00407 }
00408 } else {
00409 ERRORMSG("All Fields in an expression must be aligned. ");
00410 ERRORMSG("(Do you have enough guard cells?)" << endl);
00411 ERRORMSG("This error occurred while evaluating an SIndex expression ");
00412 ERRORMSG("for an LField with domain " << (*la)->getDomain() << endl);
00413 Ippl::abort();
00414 }
00415
00416
00417 }
00418
00419
00420 AssignActions<Dim,SIExprTag<IsExpr> >::nextLField(bb);
00421 }
00422
00423
00424
00425 a.setDomain(domain);
00426 }
00427
00428
00429
00430
00431
00432
00433