RFA: Improving StencilEngine Comments
Jeffrey Oldham
oldham at codesourcery.com
Sat Jun 30 00:21:03 UTC 2001
OK to commit this patch? Does it meet Pooma comment guidelines?
When working on implementing restriction operators for arrays, I read
through src/Engine/Stencil.h. The most confusing aspect was that
"domain" is used for both stencil input and stencil output. Also, the
invariants and data members for the StencilEngine were not documented.
I wrote comments that, I hope, clarify these aspects.
2001-06-29 Jeffrey D. Oldham <oldham at codesourcery.com>
* Stencil.h: Fix typographical errors.
Add stencil concept comments.
(insetDomain): Modify initial comments.
(Engine<D,T,StencilEngine>): Fix typographical error.
(Engine::Engine): Modify initial comments.
(Engine::read): Likewise.
(Engine::domain): Likewise.
(Engine::first): Likewise.
(Engine::viewDomain): Likewise. Add other comments.
(Engine::intersectDomain): Add initial comment.
(View1): Modify initial comments.
(View2): Likewise.
(Stencil): Fix typographical error in initial comments.
(DataObjectRequest): Likewise.
Tested on sequential Linux using gcc 3.0 by compiling Pooma library
Approved by ???you???
Thanks,
Jeffrey D. Oldham
oldham at codesourcery.com
-------------- next part --------------
Index: Stencil.h
===================================================================
RCS file: /home/pooma/Repository/r2/src/Engine/Stencil.h,v
retrieving revision 1.42
diff -c -p -r1.42 Stencil.h
*** Stencil.h 2000/09/20 16:22:07 1.42
--- Stencil.h 2001/06/29 23:03:06
***************
*** 32,38 ****
// StencilEngine - An tag for an engine for representing a stencil
// ArrayStencil - contains utility functions for building stencils
// on arrays
! // View1 - Specialization for Stencil
// Engine - Specialization for StencilEngine
// NewEngine - Specialization for StencilEngine
// EvaluatorEngineTraits - Specialization for StencilEngine
--- 32,38 ----
// StencilEngine - An tag for an engine for representing a stencil
// ArrayStencil - contains utility functions for building stencils
// on arrays
! // View1 - Specialization for Stencil
// Engine - Specialization for StencilEngine
// NewEngine - Specialization for StencilEngine
// EvaluatorEngineTraits - Specialization for StencilEngine
***************
*** 93,98 ****
--- 93,153 ----
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
+ //
+ // Stencil Concepts:
+ //
+ // A stencil is a pattern repeatedly applied to elements in an input domain to
+ // yield elements in the output domain. For example, the simplest
+ // stencil copies each element in the input domain to exactly the same
+ // element in the output domain. A second-order difference stencil can
+ // be represented by the formula
+ //
+ // out(i) = 2 in(i-1) + in(i) + in(i+1)
+ //
+ // where in(i) and out(i) indicate the ith input and output elements,
+ // respectively. This stencil illustrates that a stencil can use more
+ // than one input element, but that all input elements must be
+ // contiguous.
+ //
+ // A StencilEngine is an engine applying a stencil to an input array.
+ // When invoked, the result is an array filled with values from applying
+ // the stencil to the input array. We explain the engine's data members
+ // and assumptions. Even though a StencilEngine stores the data for its
+ // computation, actually performing the computation only when requested,
+ // we use the slang of its "output" to avoid writing "its output when the
+ // computation is invoked." Also, in the explanation below, we use
+ // one-dimensional terminology. The only supported domains and ranges
+ // are Cartesian products so the one-dimensional terminology is easily
+ // generalized.
+ //
+ // When created, engines frequently are given the desired array output
+ // range indices, e.g., -3, ..., 5. Any such range can be shifted so the
+ // leftmost element's index is zero, i.e., zero-based. For example, 0,
+ // ..., 8 with an offset of -3. To return to the "original," desired
+ // range, add the offset to each index. The `domain_m' variable records
+ // the number of output elements.
+ //
+ // Assume the engine's stencil uses input array elements with indices
+ // lowerExtent, lowerExtent+1, ..., 0, ..., upperExtent. Thus, to
+ // produce out(0) requires knowing in(lowerExtent), ..., in(upperExtent).
+ // The input domain to consisting of the values used to compute the
+ // zero-based output range is in(lowerExtent), ..., in(domain_m +
+ // upperExtent).
+ //
+ // The StencilEngine's data members are
+ // 1) function_m representing the stencil
+ // 2) expression_m which is approximately the input
+ // 3) domain_m representing the indices for the output
+ // 4) offset_m representing the 'shift' to yield zero-based output indices
+ // Note all members concern output, not input.
+ //
+ // When reading the source code below, "domain" is used for both input
+ // and output indices. The reader must decide the meaning of each
+ // occurrence.
+ //
+ //-----------------------------------------------------------------------------
+
+ //-----------------------------------------------------------------------------
// Includes:
//-----------------------------------------------------------------------------
*************** struct StencilEngine
*** 158,163 ****
--- 213,221 ----
// b(range) = st(a,range);
//
// because that version doesn't inset.
+ //
+ // In other words, given a stencil and an input domain, return the
+ // resulting output indices.
//---------------------------------------------------------------------------
template<class Function, int D>
*************** Interval<D> insetDomain(const Function &
*** 186,192 ****
//
// Typedefs for the tag, element types, domain and dimensions.
// Operator() with integers to evaluate elements quickly.
! // Operator() with a doman to subset.
// Accessor for the domain.
//
//-----------------------------------------------------------------------------
--- 244,250 ----
//
// Typedefs for the tag, element types, domain and dimensions.
// Operator() with integers to evaluate elements quickly.
! // Operator() with a domain to subset.
// Accessor for the domain.
//
//-----------------------------------------------------------------------------
*************** public:
*** 215,226 ****
enum { zeroBased = true };
//============================================================
! // Construct from a Function object and an expression.
//============================================================
Engine(const Function &f, const Expression &e)
: function_m(f), expression_m(e), domain_m(Pooma::NoInit())
{
Interval<D> inset = insetDomain(f, e.domain());
int d;
for (d = 0; d < D; ++d)
--- 273,287 ----
enum { zeroBased = true };
//============================================================
! // Construct from a Function object (effectively a stencil)
! // and an expression (effectively the input array), and
! // sometimes an output (not input) domain.
//============================================================
Engine(const Function &f, const Expression &e)
: function_m(f), expression_m(e), domain_m(Pooma::NoInit())
{
+ // inset is the indices for the stencil's output.
Interval<D> inset = insetDomain(f, e.domain());
int d;
for (d = 0; d < D; ++d)
*************** public:
*** 241,246 ****
--- 302,309 ----
}
}
+ // Construct an engine for composing stencils, e.g.,
+ // stencil1(stencil2(array)).
template<class OtherE>
Engine(const Engine<D, T, StencilEngine<Function, OtherE> > &e,
const INode<D> &node)
*************** public:
*** 271,281 ****
}
//============================================================
! // Element access via ints for speed.
//============================================================
inline Element_t read(int i) const
{
return function()(expression_m,
i + offset_m[0]);
}
--- 334,346 ----
}
//============================================================
! // Element access via ints for speed. The arguments correspond to
! // output elements, not input elements.
//============================================================
inline Element_t read(int i) const
{
+ // Input index `i + offset_m[0]' corresponds to output index `i'.
return function()(expression_m,
i + offset_m[0]);
}
*************** public:
*** 333,345 ****
}
//============================================================
! // Return the domain.
//============================================================
inline Domain_t domain() const { return domain_m; }
//============================================================
! // Return the first index value for the specified direction
// (always zero since this engine is zero-based).
//============================================================
--- 398,410 ----
}
//============================================================
! // Return the output domain.
//============================================================
inline Domain_t domain() const { return domain_m; }
//============================================================
! // Return the first output index value for the specified direction
// (always zero since this engine is zero-based).
//============================================================
*************** public:
*** 351,357 ****
//---------------------------------------------------------------------------
// viewDomain() gives the region of the expression needed to compute a given
! // region of the stencil.
//---------------------------------------------------------------------------
inline
--- 416,423 ----
//---------------------------------------------------------------------------
// viewDomain() gives the region of the expression needed to compute a given
! // region of the stencil. That is, viewDomain(outputDomain) yields
! // the corresponding input domain.
//---------------------------------------------------------------------------
inline
*************** public:
*** 361,366 ****
--- 427,434 ----
int d;
for (d = 0; d < D; ++d)
{
+ // The computation subtracts and adds the stencil's extent from
+ // the "original", unshifted output domain.
ret[d] =
Interval<1>(
domain[d].first() + offset_m[d]
*************** public:
*** 377,382 ****
--- 445,454 ----
return INode<D>(inode, viewDomain(inode.domain()));
}
+ //---------------------------------------------------------------------------
+ // intersectDomain() gives the "original", unshifted output domain.
+ //---------------------------------------------------------------------------
+
inline
Interval<D> intersectDomain() const
{
*************** private:
*** 411,417 ****
//-----------------------------------------------------------------------------
// View types for stencil objects. Stencils define operator() to return a
! // stencil engine object. If you wanted to store that object, you could write:
//
// A a;
// Laplace laplace;
--- 483,492 ----
//-----------------------------------------------------------------------------
// View types for stencil objects. Stencils define operator() to return a
! // stencil engine object, which, when invoked, yields the result of
! // applying the stencil to the given array.
! //
! // If you wanted to store that object, you could write:
//
// A a;
// Laplace laplace;
*************** struct View1<Stencil<Function>, Array<D,
*** 438,444 ****
//-----------------------------------------------------------------------------
// View2 is used to construct the return type for stencils where the
! // domain is given as well.
//-----------------------------------------------------------------------------
template<class Function, class ArrayIn, int Dim>
--- 513,519 ----
//-----------------------------------------------------------------------------
// View2 is used to construct the return type for stencils where the
! // output domain is given as well.
//-----------------------------------------------------------------------------
template<class Function, class ArrayIn, int Dim>
*************** struct View2<Stencil<Function>, ArrayIn,
*** 517,523 ****
//
// The return type is whatever the stencil outputs. If this is not
// the same type as the elements of 'expr', you must specialize
! // the pooma FunctorResult class (see Pooma/FunctorResult.h).
//
// To apply a stencil, create an instance of the Stencil<> class.
//
--- 592,598 ----
//
// The return type is whatever the stencil outputs. If this is not
// the same type as the elements of 'expr', you must specialize
! // the Pooma FunctorResult class (see Pooma/FunctorResult.h).
//
// To apply a stencil, create an instance of the Stencil<> class.
//
*************** struct LeafFunctor<Engine<D,T,StencilEng
*** 795,801 ****
};
//---------------------------------------------------------------------------
! // Specialization of DataObjectRequest engineFunctor to pass the request to
// the contained engine.
//---------------------------------------------------------------------------
--- 870,876 ----
};
//---------------------------------------------------------------------------
! // Specialization of DataObjectRequest engineFunctor to pass the request to
// the contained engine.
//---------------------------------------------------------------------------
More information about the pooma-dev
mailing list