FreePOOMA
2.4.1
|
Stencil objects are a way to build an object which applies a stencil to an array, and returns a new Array for the expression. More...
#include "Domain/Interval.h"
#include "Evaluator/EngineTraits.h"
#include "Engine/Engine.h"
#include "Engine/Intersector.h"
#include "Engine/IntersectEngine.h"
#include "Engine/EngineFunctor.h"
#include "PETE/ErrorType.h"
#include "Pooma/View.h"
#include "Pooma/FunctorResult.h"
#include "Engine/ViewEngine.h"
#include "Utilities/WrappedInt.h"
Stencil objects are a way to build an object which applies a stencil to an array, and returns a new Array for the expression.
There are several reasons one might want to do this:
A base class from which users would inherit to produce a specific stencil. This mainly implements operator()(expr), which constructs the expression with the stencil applied to the expression.
StencilEngine<D,T2,Expression>
An engine for Arrays which applies a stencil. This takes another engine as a template argument and applies the stencil to that engine.
Defines the type of StencilEngine you get when you subset it. It just subsets the engine inside of it.
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
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.
Interval<D> insetDomain | ( | const Function & | f, |
const Interval< D > & | domain | ||
) | [inline] |
insetDomain() computes the insetDomain domain of the stencil for users (it's not zero-based).
If you just got a random stencil from who knows where and want to apply it to another array, you could say:
b(st.insetDomain(a.domain())) = st(a);
Note that you can always just say:
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.
Referenced by Engine< D, T, StencilEngine< Function, Expression > >::Engine(), View1< Stencil< Function >, Array< D, T, E > >::make(), and View2< Stencil< Function >, ArrayIn, Dom >::make().