freepooma-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Allow custom evaluation domain for ScalarCode


From: Jeffrey D. Oldham
Subject: Re: [PATCH] Allow custom evaluation domain for ScalarCode
Date: Wed, 18 Aug 2004 08:40:27 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5

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 <address@hidden>

        * 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 address@hidden,
+// 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
address@hidden

reply via email to

[Prev in Thread] Current Thread [Next in Thread]