[PATCH] Allow custom evaluation domain for ScalarCode

Jeffrey D. Oldham oldham at codesourcery.com
Wed Aug 18 15:40:27 UTC 2004


Richard Guenther wrote:

>This patch adds the ability to provide a custom evaluation domain
>for a ScalarCode expression (like including external guards or
>excluding the boundary from vertex centered fields).  This is much
>less fragile than trying to pass appropriate views as arguments.
>
>Tested with Evaluator and ScalarCode tests.
>
>Ok?
>
>  
>
This is good.  The existing interface is maintained but also extended.  
Please commit it.  I have one small correction about thirty lines below.

>Richard.
>
>
>2004Aug18  Richard Guenther <richard.guenther at uni-tuebingen.de>
>
>	* src/Evaluator/ScalarCode.h: add variants of operator()
>	with specified evaluation domain.
>	src/Evaluator/tests/evaluatorTest9.cpp: new.
>  
>
>------------------------------------------------------------------------
>
>Index: ScalarCode.h
>===================================================================
>RCS file: /home/pooma/Repository/r2/src/Evaluator/ScalarCode.h,v
>retrieving revision 1.13
>diff -u -u -r1.13 ScalarCode.h
>--- ScalarCode.h	7 Apr 2004 16:38:23 -0000	1.13
>+++ ScalarCode.h	18 Aug 2004 09:52:47 -0000
>@@ -391,6 +391,19 @@
>   Interval<Dim> domain_m;
> };
> 
>+
>+/**
>+ * ScalarCode is a Stencil like operation that allows for more than one
>+ * field to be operated on. Generally the functor is a local (set of)
>+ * function(s) which could be described as
>+ *
>+ *   (f1..fM) = op(fM+1..fN)
>+ *
>  
>
I assume commas are needed:

(f1, ..., fM) = op(F1, ..., FN)

Also, fM+1 is ambiguous: f_{M+1} or (fM)+1

>+ * where fM+1 to fN are input fields read from and f1 to fM are output
>  
>
g1 to gN

>+ * fields written to (this distinction nor its ordering is strictly
>+ * required, but both will result in the least possible surprises).
>+ */
>+
> template<class Function>
> struct ScalarCode
> {
>@@ -427,113 +440,149 @@
>     return f.centeringSize() == 1 && f.numMaterials() == 1;
>   }
> 
>+  /// @name Evaluators
>+  /// Evaluate the ScalarCode functor on the fields f1 to fN using the
>+  /// specified evaluation domain. Note that views of the evaluation domain
>+  /// are taken of every field, so domains of the fields should be strictly
>+  /// conforming (in fact, passing views to these operators is a bug unless
>+  /// you really know what you are doing).
>+  ///
>+  /// The evaluation domain defaults to the physical domain of
>+  /// the first field which should usually be (on of) the left hand side(s).
>+  /// If you want the functor to operate on a different domain use the
>+  /// operators with the explicit specified evaluation domain.
>+  //@{
>+
>   template<class F1>
>-  void operator()(const F1 &f1) const
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg1<F1> multiArg(f1);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>+  }
>+
>+  template<class F1>
>+  inline void operator()(const F1 &f1) const
>+  {
>+    (*this)(f1, f1.physicalDomain());
>   }
> 
>+
>   template<class F1, class F2>
>-  void operator()(const F1 &f1, const F2 &f2) const
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
>+                  const F2 &f2) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg2<F1, F2> multiArg(f1, f2);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>   }
> 
>+  template<class F1, class F2>
>+  inline void operator()(const F1 &f1, const F2 &f2) const
>+  {
>+    (*this)(f1, f1.physicalDomain(), f2);
>+  }
>+
>+
>   template<class F1, class F2, class F3>
>-  void operator()(const F1 &f1, const F2 &f2, const F3 &f3) const
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
>+                  const F2 &f2, const F3 &f3) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg3<F1, F2, F3> multiArg(f1, f2, f3);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>   }
> 
>+  template<class F1, class F2, class F3>
>+  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3) const
>+  {
>+    (*this)(f1, f1.physicalDomain(), f2, f3);
>+  }
>+
>+
>   template<class F1, class F2, class F3, class F4>
>-  void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4) const
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
>+		  const F2 &f2, const F3 &f3, const F4 &f4) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg4<F1, F2, F3, F4> multiArg(f1, f2, f3, f4);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>   }
> 
>+  template<class F1, class F2, class F3, class F4>
>+  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4) const
>+  {
>+    (*this)(f1, f1.physicalDomain(), f2, f3, f4);
>+  }
>+
>+
>   template<class F1, class F2, class F3, class F4, class F5>
>-  void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
>-		  const F5 &f5) const
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
>+		  const F2 &f2, const F3 &f3, const F4 &f4, const F5 &f5) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg5<F1, F2, F3, F4, F5> multiArg(f1, f2, f3, f4, f5);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>   }
> 
>+  template<class F1, class F2, class F3, class F4, class F5>
>+  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
>+			 const F5 &f5) const
>+  {
>+    (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5);
>+  }
>+
>+
>   template<class F1, class F2, class F3, class F4, class F5, class F6>
>-  void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
>-		  const F5 &f5, const F6 &f6) const
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
>+		  const F2 &f2, const F3 &f3, const F4 &f4, const F5 &f5,
>+		  const F6 &f6) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg6<F1, F2, F3, F4, F5, F6> multiArg(f1, f2, f3, f4, f5, f6);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>   }
> 
>+  template<class F1, class F2, class F3, class F4, class F5, class F6>
>+  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
>+			 const F5 &f5, const F6 &f6) const
>+  {
>+    (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5, f6);
>+  }
>+
>+
>   template<class F1, class F2, class F3, class F4, class F5, class F6, class F7>
>-  void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
>+  void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
>+		  const F2 &f2, const F3 &f3, const F4 &f4,
> 		  const F5 &f5, const F6 &f6, const F7 &f7) const
>   {
>     PAssert(checkValidity(f1, WrappedInt<F1::hasRelations>()));
>-    enum { dimensions = F1::dimensions };
>     MultiArg7<F1, F2, F3, F4, F5, F6, F7> multiArg(f1, f2, f3, f4, f5, f6, f7);
>-    EvaluateLocLoop<Function, dimensions> kernel(function_m,
>-						 f1.physicalDomain());
>-
>+    EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
>     MultiArgEvaluator<MainEvaluatorTag>::
>-      evaluate(multiArg, function_m,
>-	       f1.physicalDomain(),
>-	       kernel);
>+      evaluate(multiArg, function_m, evalDom, kernel);
>   }
>+
>+  template<class F1, class F2, class F3, class F4, class F5, class F6, class F7>
>+  inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
>+			 const F5 &f5, const F6 &f6, const F7 &f7) const
>+  {
>+    (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5, f6, f7);
>+  }
>+
>+  //@}
> 
>   Function function_m;
> };
>--- /dev/null	Tue May 18 17:20:27 2004
>+++ tests/evaluatorTest9.cpp	Wed Aug 18 11:51:07 2004
>@@ -0,0 +1,121 @@
>+// -*- 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
>+
>+//-----------------------------------------------------------------------------
>+// evaluatorTest9 - testing ScalarCode and custom evaluation domain
>+//-----------------------------------------------------------------------------
>+
>+#include "Pooma/Pooma.h"
>+#include "Pooma/Arrays.h"
>+#include "Pooma/Fields.h" // for PerformUpdateTag() only!
>+#include "Evaluator/ScalarCode.h"
>+#include "Utilities/Tester.h"
>+#include <iostream>
>+
>+
>+// dummy operation
>+
>+template <int Dim>
>+struct Copy
>+{
>+  Copy(int val) : val_m(val) {}
>+
>+  template<class A>
>+  inline void operator()(const A &a, const Loc<Dim> &i) const
>+  {
>+     a(i) = val_m;
>+  }
>+
>+  void scalarCodeInfo(ScalarCodeInfo& i) const
>+  {
>+    i.arguments(1);
>+    i.dimensions(Dim);
>+    i.write(1, true);
>+    i.useGuards(0, false);
>+  }
>+
>+  const int val_m;
>+};
>+
>+
>+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<2> domain(16, 16);
>+  Loc<2> blocks(4, 4);
>+  UniformGridLayout<2> layout(domain, blocks, GuardLayers<2>(1), DistributedTag());
>+  UniformRectilinearMesh<2> mesh(layout);
>+  Centering<2> cell = canonicalCentering<2>(CellType, Continuous);
>+
>+  Field<UniformRectilinearMesh<2>, int, MultiPatch<UniformTag, Remote<Brick> > >
>+    a(cell, layout, mesh),
>+    b(cell, layout, mesh);
>+
>+  // initialize with zero
>+  a.all() = 0;
>+  b.all() = 0;
>+
>+  // do assignments to various subdomains with both expression engine
>+  // and scalar code functor and compare the full results.
>+  Interval<2> I;
>+
>+  (ScalarCode<Copy<2> >(1))(a);
>+  b = 1;
>+  tester.check("default (physical) domain", all(a.all() == b.all()));
>+
>+  I = Interval<2>(Interval<1>(8, 14), Interval<1>(0, 14));
>+  (ScalarCode<Copy<2> >(2))(a, I);
>+  b(I) = 2;
>+  tester.check("partial set of physical patches", all(a.all() == b.all()));
>+
>+  I = Interval<2>(Interval<1>(6, 9), Interval<1>(6, 9));
>+  (ScalarCode<Copy<2> >(3))(a, I);
>+  b(I) = 3;
>+  tester.check("arbitrary physical domain", all(a.all() == b.all()));
>+
>+  I = Interval<2>(Interval<1>(0, 15), Interval<1>(-1, 2));
>+  (ScalarCode<Copy<2> >(4))(a, I);
>+  b(I) = 4;
>+  tester.check("arbitrary domain", all(a.all() == b.all()));
>+
>+  int retval = tester.results("evaluatorTest9 (ScalarCode, evaluation domain)");
>+  Pooma::finalize();
>+  return retval;  
>+}
>+
>+// ACL:rcsinfo
>+// ----------------------------------------------------------------------
>+// $RCSfile: evaluatorTest2.cpp,v $   $Author: pooma $
>+// $Revision: 1.7 $   $Date: 2003/01/29 19:32:07 $
>+// ----------------------------------------------------------------------
>+// ACL:rcsinfo
>  
>


-- 
Jeffrey D. Oldham
oldham at codesourcery.com




More information about the pooma-dev mailing list