[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