[PATCH] Fix ScalarCode with expression arguments
Jeffrey D. Oldham
oldham at codesourcery.com
Wed Aug 18 15:48:35 UTC 2004
Richard Guenther wrote:
>This patch fixes expression arguments with (read-only) arguments
>to ScalarCode. Before this patch there were several problems with
>this:
>- updating of the engine state did not handle expression engines
>- internal guards were not updated correctly
>
>With fixing the above ScalarCode also gains from the previous guard
>layer update optimizations.
>
>Tested with all ScalarCode tests and Evaluator tests.
>
>Ok?
>
>
>
I guess so. I do not understand, but that is because of my ignorance.
>Richard.
>
>Btw. the test is evaluatorTest10 - patches to merge other tests are on the
>way.
>
>
>2004Aug18 Richard Guenther <richard.guenther at uni-tuebingen.de>
>
> * 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 pooma at acl.lanl.gov,
>+// 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
>
>
--
Jeffrey D. Oldham
oldham at codesourcery.com
More information about the pooma-dev
mailing list