[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