[PATCH] Support reductions over where(), 2nd try
Jeffrey D. Oldham
oldham at codesourcery.com
Fri Nov 21 21:23:37 UTC 2003
Richard Guenther wrote:
> Hi!
>
> This version doesnt break any use of where as the first version did.
> Double-checked with a full build and regression test using Intel
> icpc 8.0 in -ansi mode.
>
> This also adds the where cases I broke with the first patch to the
> array and field tests.
>
> Ok?
Yes, but see the correction and three suggestions below.
> Richard.
>
>
> 2003Nov21 Richard Guenther <richard.guenther at uni-tuebingen.de>
>
> * src/Evaluator/WhereProxy.h: support reduction over
> WhereProxy<> objects by adding Element_t.
> src/Evaluator/OpMask.h: Add ReductionTraits<> specialization
> for OpMask<T>, add Unwrap<> to unwrap OpMask<>.
> src/Engine/RemoteEngine.h: use unwrapped Op for final
> reduction over patch results.
> src/Evaluator/Reduction.h: likewise. Add evaluate() method
> handling WhereProxy to main evaluator.
> src/Array/tests/array_test12.cpp: Add where reduction testcases.
> src/Field/tests/WhereTest.cpp: likewise.
>
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Array/tests/array_test12.cpp,v
> retrieving revision 1.13
> diff -u -u -r1.13 array_test12.cpp
> --- Array/tests/array_test12.cpp 10 Mar 2000 18:10:45 -0000 1.13
> +++ Array/tests/array_test12.cpp 21 Nov 2003 20:30:07 -0000
> @@ -109,6 +109,11 @@
> tester.out() << std::endl;
> tester.check("d2 < 0.000001", d2 < 0.000001);
>
> + int cnt = sum(where(d == 0.0, 1));
> + tester.check("couting zeros with where reduction", cnt == 6);
s/couting/counting/
> +
> + tester.check("where reduction", prod(where(d == 0.0, d)) == 0.0);
> +
> int ret = tester.results("array_test12");
> Pooma::finalize();
> return ret;
> Index: Engine/RemoteEngine.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Engine/RemoteEngine.h,v
> retrieving revision 1.37
> diff -u -u -r1.37 RemoteEngine.h
> --- Engine/RemoteEngine.h 22 Oct 2003 19:38:07 -0000 1.37
> +++ Engine/RemoteEngine.h 21 Nov 2003 20:30:08 -0000
> @@ -2069,7 +2069,7 @@
> {
> ret = vals[0];
> for (j = 1; j < n; j++)
> - op(ret, vals[j]);
> + Unwrap<Op>::unwrap(op)(ret, vals[j]);
> }
>
> delete [] vals;
> Index: Evaluator/OpMask.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Evaluator/OpMask.h,v
> retrieving revision 1.20
> diff -u -u -r1.20 OpMask.h
> --- Evaluator/OpMask.h 22 Oct 2003 20:43:26 -0000 1.20
> +++ Evaluator/OpMask.h 21 Nov 2003 20:30:08 -0000
> @@ -169,6 +169,28 @@
> typedef T1 &Type_t;
> };
>
> +template <class Op>
> +struct Unwrap {
> + typedef Op Op_t;
> + static inline const Op_t& unwrap(const Op &op) { return op; }
> +};
> +
> +template <class Op>
> +struct Unwrap<OpMask<Op> > {
> + typedef typename Unwrap<Op>::Op_t Op_t;
> + static inline const Op_t& unwrap(const OpMask<Op> &op) { return Unwrap<Op>::unwrap(op.op_m); }
> +};
> +
> +template <class Op, class T>
> +struct ReductionTraits;
> +
> +template <class Op, class T>
> +struct ReductionTraits<OpMask<Op>, T>
> +{
> + static T identity() { return ReductionTraits<Op, T>::identity(); }
> +};
> +
> +
> //-----------------------------------------------------------------------------
> //
> //-----------------------------------------------------------------------------
> Index: Evaluator/Reduction.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Evaluator/Reduction.h,v
> retrieving revision 1.12
> diff -u -u -r1.12 Reduction.h
> --- Evaluator/Reduction.h 21 Nov 2003 17:36:10 -0000 1.12
> +++ Evaluator/Reduction.h 21 Nov 2003 20:30:08 -0000
> @@ -53,7 +53,9 @@
> #include "Engine/IntersectEngine.h"
> #include "Evaluator/ReductionKernel.h"
> #include "Evaluator/EvaluatorTags.h"
> +#include "Evaluator/WhereProxy.h"
> #include "Threads/PoomaCSem.h"
> +#include "Utilities/PerformUpdate.h"
>
> #include <vector>
> #include <iterator>
> @@ -109,6 +111,14 @@
> return e.centeringSize() == 1 && e.numMaterials() == 1;
> }
>
> + /// Un-wrap where() expression operation and pass on to generic evaluator.
> +
> + template<class T, class Op, class Cond, class Expr>
> + void evaluate(T &ret, const Op &op, const WhereProxy<Cond, Expr> &w) const
> + {
> + evaluate(ret, w.opMask(op), w.whereMask());
> + }
> +
> /// Input an expression and cause it to be reduced.
> /// We just pass the buck to a special reduction after updating
> /// the expression leafs and checking its validity (we can handle
> @@ -249,7 +259,7 @@
>
> ret = vals[0];
> for (j = 1; j < n; j++)
> - op(ret, vals[j]);
> + Unwrap<Op>::unwrap(op)(ret, vals[j]);
> delete [] vals;
> }
> };
> Index: Evaluator/WhereProxy.h
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Evaluator/WhereProxy.h,v
> retrieving revision 1.5
> diff -u -u -r1.5 WhereProxy.h
> --- Evaluator/WhereProxy.h 22 Oct 2003 20:43:26 -0000 1.5
> +++ Evaluator/WhereProxy.h 21 Nov 2003 20:30:08 -0000
> @@ -48,6 +48,7 @@
>
> #include "Evaluator/OpMask.h"
> #include "Pooma/PETE/ExpressionTraits.h"
> +#include "Engine/ExpressionEngine.h"
>
> //-----------------------------------------------------------------------------
> /// We need the tools to convert a WhereProxy into an Array or Field or
> @@ -84,6 +85,8 @@
> typedef typename ExpressionTraits<Tree_t>::Type_t ETrait_t;
> typedef typename ConvertWhereProxy<ETrait_t,Tree_t>::Make_t MakeFromTree_t;
> typedef typename MakeFromTree_t::Expression_t WhereMask_t;
> + typedef typename ForEach<typename CreateLeaf<B>::Leaf_t,
> + EvalLeaf<1>, OpCombine>::Type_t Element_t;
>
> inline WhereMask_t
> whereMask() const
> Index: Field/tests/WhereTest.cpp
> ===================================================================
> RCS file: /home/pooma/Repository/r2/src/Field/tests/WhereTest.cpp,v
> retrieving revision 1.2
> diff -u -u -r1.2 WhereTest.cpp
> --- Field/tests/WhereTest.cpp 23 Jan 2003 19:21:49 -0000 1.2
> +++ Field/tests/WhereTest.cpp 21 Nov 2003 20:30:09 -0000
> @@ -86,6 +86,7 @@
> // Now, we can declare a field.
>
> Centering<2> allFace = canonicalCentering<2>(FaceType, Continuous);
> + Centering<2> allCell = canonicalCentering<2>(CellType, Continuous);
>
> typedef UniformRectilinearMesh<2> Geometry_t;
>
> @@ -103,6 +104,9 @@
> Field_t a(allFace, layout, origin, spacings);
> Field_t b(allFace, layout, origin, spacings);
> Field_t c(allFace, layout, origin, spacings);
> + Field_t d(allCell, layout, origin, spacings);
> + Field_t e(allCell, layout, origin, spacings);
> + Field_t f(allCell, layout, origin, spacings);
>
> PositionsTraits<Geometry_t>::Type_t x = positions(a);
>
> @@ -154,6 +158,43 @@
> tester.check("twoarg where result dirtied part, centering one",
> all(where(dot(x.subField(0, 1), line) > 8.0,
> b.subField(0, 1), c.subField(0, 1)) == a.subField(0, 1)));
> +
> + // 2-arg where reduction
> +
> + d = 1.0;
> + e = positions(e).read(e.physicalDomain()).comp(0);
> + tester.check("reduction over twoarg where",
> + sum(where(e(e.physicalDomain()) < 4.0, d)) == 4.0*9.0);
> +
> + // 3-arg where reduction
> +
> + d = 1.0;
> + f = 0.0;
> + e = positions(e).read(e.physicalDomain()).comp(0);
> + tester.check("reduction over twoarg where",
> + sum(where(e(e.physicalDomain()) < 4.0, d, f)) == 4.0*9.0);
> +
> + // 2-arg where with scalar expression and reduction variant thereof
> +
> + d = where(e(e.physicalDomain()) >= 4.0, 0.0);
> + tester.check("counting reduction",
> + sum(where(d(d.physicalDomain()) != 0.0, 1)) == 4*9);
> +
> + // 2-arg where with scalar test and reduction variant thereof
> +
> + d = where(true, f);
> + tester.check("stupid where", all(d(d.physicalDomain()) == 0.0));
> + tester.check("stupid where reduction", prod(where(true, d)) == 0.0);
I would prefer to use the word "simple", not "stupid".
> +
> + // note that where with both expression and test being scalar does not
> + // work because of
> + // src/Pooma/PETE/ExpressionTraits.h:121:
> + // error: no type named `Type_t' in
> + // `struct CombineExpressionTraits<ExpressionIsScalar, ExpressionIsScalar>'
> + // and that is probably not the only reason.
> + //
> + // d = where(true, 1.0);
> + // tester.check("even more stupid where", all(d(d.physicalDomain()) == 1.0));
Likewise.
>
> int ret = tester.results("WhereTest");
> Pooma::finalize();
--
Jeffrey D. Oldham
oldham at codesourcery.com
More information about the pooma-dev
mailing list