Richard.
Btw. the test is evaluatorTest10 - patches to merge other tests are on the
way.
2004Aug18 Richard Guenther <address@hidden>
* src/Evaluator/MultiArgEvaluator.h: handle expression engines
in EngineWriteNotifier, pass stencil extent to SimpleIntersector.
src/Evaluator/SimpleIntersector.h: honour stencil extent,
recursively intersect and update expression engines.
src/Evaluator/tests/evaluatorTest10.cpp: new.
------------------------------------------------------------------------
Index: MultiArgEvaluator.h
===================================================================
RCS file: /home/pooma/Repository/r2/src/Evaluator/MultiArgEvaluator.h,v
retrieving revision 1.14
diff -u -u -r1.14 MultiArgEvaluator.h
--- MultiArgEvaluator.h 21 Nov 2003 17:36:10 -0000 1.14
+++ MultiArgEvaluator.h 18 Aug 2004 09:41:57 -0000
@@ -74,6 +74,8 @@
//-----------------------------------------------------------------------------
template<class MultiArg> struct MultiArgEvaluatorTag;
+template<class MeshTag, class T, class EngineTag> class Field;
+template<int Dim, class T, class EngineTag> class Array;
/**
* Implements: MultiArgEvaluator<MainEvaluatorTag>::evaluate
@@ -111,19 +113,30 @@
}
template<class A>
- void operator()(const A &a, bool f) const
+ void operator()(const A &a) const
{
- if (f)
- {
- // This isn't quite what we want here, because we may want to
- // write to a field containing multiple centering engines.
- // Need to rewrite notifyEngineWrite as an ExpressionApply,
- // and create a version of ExpressionApply that goes through
- // all the engines in a field.
+ // This isn't quite what we want here, because we may want to
+ // write to a field containing multiple centering engines.
+ // Need to rewrite notifyEngineWrite as an ExpressionApply,
+ // and create a version of ExpressionApply that goes through
+ // all the engines in a field.
- notifyEngineWrite(a.engine());
- dirtyRelations(a, WrappedInt<A::hasRelations>());
- }
+ notifyEngineWrite(a.engine());
+ dirtyRelations(a, WrappedInt<A::hasRelations>());
+ }
+
+ // overload for ExpressionTag engines to not fall on our faces compile time
+ template<class MeshTag, class T, class Expr>
+ void operator()(const Field<MeshTag, T, ExpressionTag<Expr> >&) const
+ {
+ // we must be able to compile this, but never execute
+ PInsist(false, "writing to expression engine?");
+ }
+ template<int Dim, class T, class Expr>
+ void operator()(const Array<Dim, T, ExpressionTag<Expr> >&) const
+ {
+ // we must be able to compile this, but never execute
+ PInsist(false, "writing to expression engine?");
}
};
@@ -172,7 +185,7 @@
MultiArgEvaluator<Evaluator_t>::evaluate(multiArg, function,
domain, info, kernel);
- applyMultiArg(multiArg, EngineWriteNotifier(), info.writers());
+ applyMultiArgIf(multiArg, EngineWriteNotifier(), info.writers());
Pooma::endExpression();
}
@@ -265,7 +278,12 @@
const Kernel &kernel)
{
typedef SimpleIntersector<Dim> Inter_t;
- Inter_t inter(domain);
+ GuardLayers<Dim> extent;
+ for (int i=0; i<Dim; ++i) {
+ extent.lower(i) = info.lowerExtent(i);
+ extent.upper(i) = info.upperExtent(i);
+ }
+ Inter_t inter(domain, extent);
applyMultiArg(multiArg, inter, info.useGuards());
@@ -368,7 +386,12 @@
const Kernel &kernel)
{
typedef SimpleIntersector<Dim> Inter_t;
- Inter_t inter(domain);
+ GuardLayers<Dim> extent;
+ for (int i=0; i<Dim; ++i) {
+ extent.lower(i) = info.lowerExtent(i);
+ extent.upper(i) = info.upperExtent(i);
+ }
+ Inter_t inter(domain, extent);
applyMultiArg(multiArg, inter, info.useGuards());
Index: SimpleIntersector.h
===================================================================
RCS file: /home/pooma/Repository/r2/src/Evaluator/SimpleIntersector.h,v
retrieving revision 1.6
diff -u -u -r1.6 SimpleIntersector.h
--- SimpleIntersector.h 22 Oct 2003 20:43:26 -0000 1.6
+++ SimpleIntersector.h 18 Aug 2004 09:41:57 -0000
@@ -91,8 +91,8 @@
// Default constructor is trival.
- inline SimpleIntersectorData(const Interval<Dim> &domain)
- : seenFirst_m(false), domain_m(domain)
+ inline SimpleIntersectorData(const Interval<Dim> &domain, const GuardLayers<Dim>
&extent)
+ : seenFirst_m(false), domain_m(domain), extent_m(extent)
{
}
@@ -105,9 +105,10 @@
inline ~SimpleIntersectorData() { }
template<class Engine>
- void intersect(const Engine &engine)
+ void intersect(const Engine &engine, bool useGuards)
{
typedef typename Engine::Layout_t Layout_t;
+ typedef typename NewEngine<Engine, Interval<Dim> >::Type_t NewEngine_t;
const Layout_t &layout(engine.layout());
// add an assertion that all layouts have the same base (probably
@@ -126,6 +127,15 @@
{
shared(layout.ID(), firstID_m);
}
+ // We need to process possible expression engines with different
+ // guard needs here. Modeled after StencilIntersector.
+ if (useGuards) {
+ expressionApply(NewEngine_t(engine, grow(domain_m, extent_m)),
+ IntersectorTag<Intersector<Dim> >(lhsi_m));
+ } else {
+ expressionApply(NewEngine_t(engine, domain_m),
+ IntersectorTag<Intersector<Dim> >(lhsi_m));
+ }
}
inline
@@ -149,10 +159,14 @@
INodeContainer_t inodes_m;
GlobalIDDataBase gidStore_m;
Interval<Dim> domain_m;
+ GuardLayers<Dim> extent_m;
+ Intersector<Dim> lhsi_m;
};
/**
- * This intersector handles matching layouts only.
+ * This intersector handles matching layouts only. It also assumes you
+ * know in advance the amount of guards used. But it allows differentiating
+ * between engines that use or do not use guards.
*
* It doesnt intersect individual layouts but is done with creating INodes
* from the first layout it sees by intersecting with the domain.
@@ -179,8 +193,8 @@
enum { dimensions = Dim };
- SimpleIntersector(const Interval<Dim> &domain)
- : pdata_m(new SimpleIntersectorData_t(domain)), useGuards_m(true)
+ SimpleIntersector(const Interval<Dim> &domain, const GuardLayers<Dim>
&extent)
+ : pdata_m(new SimpleIntersectorData_t(domain, extent)), useGuards_m(true)
{ }
SimpleIntersector(const This_t &model)
@@ -189,8 +203,10 @@
This_t &operator=(const This_t &model)
{
- if (this != &model)
+ if (this != &model) {
pdata_m = model.pdata_m;
+ useGuards_m = model.useGuards_m;
+ }
return *this;
}
@@ -221,7 +237,8 @@
inline
void intersect(const Engine &l) const
{
- data()->intersect(l);
+ data()->intersect(l, useGuards());
+
}
inline
@@ -236,7 +253,7 @@
useGuards_m = f;
}
- // Interface to be used by applyNode()
+ // Interface to be used by applyMultiArg()
template<class A>
void operator()(const A &a, bool f) const
@@ -284,39 +301,39 @@
// with the enclosed intersector.
//---------------------------------------------------------------------------
-template <int Dim, class T, class LayoutTag, class PatchTag, int D2>
+template <int Dim, class T, class LayoutTag, class PatchTag>
struct LeafFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
- ExpressionApply<SimpleIntersector<D2> > >
+ ExpressionApply<SimpleIntersector<Dim> > >
{
typedef int Type_t;
static Type_t
apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
- const ExpressionApply<SimpleIntersector<D2> > &apply)
+ const ExpressionApply<SimpleIntersector<Dim> > &apply)
{
apply.tag().intersect(engine);
if (apply.tag().useGuards())
- engine.fillGuards();
+ engine.fillGuards(apply.tag().data()->extent_m);
return 0;
}
};
-template <int Dim, class T, class LT, class PatchTag, int BD, int D2>
+template <int Dim, class T, class LT, class PatchTag, int BD>
struct LeafFunctor<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> >,
- ExpressionApply<SimpleIntersector<D2> > >
+ ExpressionApply<SimpleIntersector<Dim> > >
{
typedef int Type_t;
static Type_t
apply(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
- const ExpressionApply<SimpleIntersector<D2> > &apply)
+ const ExpressionApply<SimpleIntersector<Dim> > &apply)
{
apply.tag().intersect(engine);
if (apply.tag().useGuards())
- engine.fillGuards();
+ engine.fillGuards(apply.tag().data()->extent_m);
return 0;
}
--- /dev/null Tue May 18 17:20:27 2004
+++ tests/evaluatorTest10.cpp Wed Aug 18 11:19:58 2004
@@ -0,0 +1,108 @@
+// -*- C++ -*-
+// ACL:license
+// ----------------------------------------------------------------------
+// This software and ancillary information (herein called "SOFTWARE")
+// called POOMA (Parallel Object-Oriented Methods and Applications) is
+// made available under the terms described here. The SOFTWARE has been
+// approved for release with associated LA-CC Number LA-CC-98-65.
+//
+// Unless otherwise indicated, this SOFTWARE has been authored by an
+// employee or employees of the University of California, operator of the
+// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
+// the U.S. Department of Energy. The U.S. Government has rights to use,
+// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
+// prepare derivative works and publicly display this SOFTWARE without
+// charge, provided that this Notice and any statement of authorship are
+// reproduced on all copies. Neither the Government nor the University
+// makes any warranty, express or implied, or assumes any liability or
+// responsibility for the use of this SOFTWARE.
+//
+// If SOFTWARE is modified to produce derivative works, such modified
+// SOFTWARE should be clearly marked, so as not to confuse it with the
+// version available from LANL.
+//
+// For more information about POOMA, send e-mail to address@hidden,
+// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
+// ----------------------------------------------------------------------
+// ACL:license
+
+//-----------------------------------------------------------------------------
+// evaluatorTest5 - testing ScalarCode and expression arguments
+//-----------------------------------------------------------------------------
+
+#include "Pooma/Pooma.h"
+#include "Pooma/Arrays.h"
+#include "Evaluator/ScalarCode.h"
+#include "Utilities/Tester.h"
+#include <iostream>
+
+
+// ScalarCode just evaluating/assigning an expression
+
+struct EvaluateExpr
+{
+ EvaluateExpr() {}
+
+ template<class LHS, class RHS>
+ inline void operator()(const LHS &a, const RHS &b, const Loc<1> &i) const
+ {
+ a(i) = b.read(i);
+ }
+
+ void scalarCodeInfo(ScalarCodeInfo& i) const
+ {
+ i.arguments(2);
+ i.dimensions(1);
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ }
+};
+
+
+int main(int argc, char *argv[])
+{
+ // Initialize POOMA and output stream, using Tester class
+ Pooma::initialize(argc, argv);
+ Pooma::Tester tester(argc, argv);
+
+ Pooma::blockingExpressions(true);
+
+ Interval<1> domain(8);
+ UniformGridLayout<1> layout(domain, Loc<1>(2), GuardLayers<1>(1),
DistributedTag());
+
+ Array<1, int, MultiPatch<UniformTag, Remote<Brick> > >
+ a(layout), b(layout), c(layout);
+
+ a = 0;
+ b = 1;
+ c = 2;
+ ScalarCode<EvaluateExpr>()(a, c-b);
+ tester.check("a = c - b", all(a(domain) == 1));
+ tester.out() << a(domain) << std::endl;
+
+ a = 0;
+ ScalarCode<EvaluateExpr>()(a, b(domain-1)+c(domain+1));
+ tester.check("a = b(i-1) + c(i+1)", all(a(domain) == 3));
+ tester.out() << a(domain) << std::endl;
+
+ tester.out() << "Manually triggering igc fill" << std::endl;
+ b.engine().fillGuards();
+ c.engine().fillGuards();
+ a = 0;
+ ScalarCode<EvaluateExpr>()(a, b(domain-1)+c(domain+1));
+ tester.check("a = b(i-1) + c(i+1)", all(a(domain) == 3));
+ tester.out() << a(domain) << std::endl;
+
+ int retval = tester.results("evaluatorTest10 (ScalarCode with expressions)");
+ Pooma::finalize();
+ return retval;
+}
+
+// ACL:rcsinfo
+// ----------------------------------------------------------------------
+// $RCSfile: evaluatorTest5.cpp,v $ $Author: pooma $
+// $Revision: 1.1 $ $Date: 2003/02/20 16:39:42 $
+// ----------------------------------------------------------------------
+// ACL:rcsinfo