[PATCH] Allow custom evaluation domain for ScalarCode
Richard Guenther
rguenth at tat.physik.uni-tuebingen.de
Wed Aug 18 10:03:10 UTC 2004
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?
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.
-------------- next part --------------
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)
+ *
+ * where fM+1 to fN are input fields read from and f1 to fM are output
+ * 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
More information about the pooma-dev
mailing list