source: XIOS/dev/dev_olga/src/extern/blitz/include/blitz/array/stencils.h @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 10.2 KB
Line 
1// -*- C++ -*-
2/***************************************************************************
3 * blitz/array/stencils.h  Stencils for arrays
4 *
5 * $Id$
6 *
7 * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
8 *
9 * This file is a part of Blitz.
10 *
11 * Blitz is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3
14 * of the License, or (at your option) any later version.
15 *
16 * Blitz is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with Blitz.  If not, see <http://www.gnu.org/licenses/>.
23 *
24 * Suggestions:          blitz-devel@lists.sourceforge.net
25 * Bugs:                 blitz-support@lists.sourceforge.net   
26 *
27 * For more information, please see the Blitz++ Home Page:
28 *    https://sourceforge.net/projects/blitz/
29 *
30 ****************************************************************************/
31#ifndef BZ_ARRAYSTENCILS_H
32#define BZ_ARRAYSTENCILS_H
33
34#ifndef BZ_ARRAY_H
35 #error <blitz/array/stencils.h> must be included after <blitz/array.h>
36#endif
37
38#include <blitz/array/stencilops.h>
39
40// NEEDS_WORK: currently stencilExtent returns int(1).  What if the
41// stencil contains calls to math functions, or divisions, etc.?
42// Should at least return a number of the appropriate type.  Probably
43// return a sequence of quasi-random floating point numbers.
44
45/*
46 * These macros make it easier for users to declare stencil objects.
47 * The syntax is:
48 *
49 * BZ_DECLARE_STENCILN(stencilname, Array1, Array2, ..., ArrayN)
50 *    // stencil operations go here
51 * BZ_END_STENCIL
52 */
53
54#define BZ_DECLARE_STENCIL2(name,A,B)    \
55  struct name {                          \
56    template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6, \
57             typename T7,typename T8,typename T9,typename T10,typename T11>         \
58    static inline void apply(T1& A, T2& B, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
59    {
60
61#define BZ_END_STENCIL_WITH_SHAPE(MINS,MAXS) } \
62    template<int N> \
63    void getExtent(BZ_BLITZ_SCOPE(TinyVector)<int,N>& minb, \
64                   BZ_BLITZ_SCOPE(TinyVector)<int,N>& maxb) const \
65    { \
66        minb = MINS; \
67        maxb = MAXS; \
68    } \
69    static const bool hasExtent = true; \
70};
71
72#define BZ_END_STENCIL } static const bool hasExtent = false; };
73#define BZ_STENCIL_END BZ_END_STENCIL
74
75#define BZ_DECLARE_STENCIL3(name,A,B,C)         \
76  struct name {                                 \
77    template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6, \
78             typename T7,typename T8,typename T9,typename T10,typename T11>      \
79    static inline void apply(T1& A, T2& B, T3& C, T4, T5, T6, T7, T8, T9,  \
80        T10, T11)      \
81    {
82
83#define BZ_DECLARE_STENCIL4(name,A,B,C,D)             \
84  struct name {                                       \
85    template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6,  \
86             typename T7,typename T8,typename T9,typename T10,typename T11>  \
87    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5, T6, T7, \
88        T8, T9, T10, T11)     \
89    {
90
91#define BZ_DECLARE_STENCIL5(name,A,B,C,D,E) \
92  struct name { \
93    template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6, \
94             typename T7,typename T8,typename T9,typename T10,typename T11> \
95    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6, T7, T8, \
96        T9, T10, T11) \
97    {
98
99#define BZ_DECLARE_STENCIL6(name,A,B,C,D,E,F) \
100  struct name { \
101    template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6, \
102             typename T7,typename T8,typename T9,typename T10,typename T11> \
103    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6& F, \
104        T7, T8, T9, T10, T11) \
105    {
106
107#define BZ_DECLARE_STENCIL7(name,A,B,C,D,E,F,G) \
108  struct name { \
109    template<typename T1,typename T2,typename T3,typename T4, \
110             typename T5,typename T6,typename T7,typename T8,typename T9,typename T10,typename T11> \
111    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6& F, T7& G, \
112        T8, T9, T10, T11) \
113    {
114
115#define BZ_DECLARE_STENCIL8(name,A,B,C,D,E,F,G,H) \
116  struct name { \
117    template<typename T1,typename T2,typename T3,typename T4, \
118             typename T5,typename T6,typename T7,typename T8,typename T9,typename T10,typename T11> \
119    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6& F, T7& G, \
120      T8& H, T9, T10, T11) \
121    {
122
123#define BZ_DECLARE_STENCIL9(name,A,B,C,D,E,F,G,H,I) \
124  struct name { \
125    template<typename T1,typename T2,typename T3,typename T4, \
126             typename T5,typename T6,typename T7,typename T8,typename T9,typename T10, \
127             typename T11> \
128    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6& F, T7& G, \
129      T8& H, T9& I, T10, T11) \
130    {
131
132#define BZ_DECLARE_STENCIL10(name,A,B,C,D,E,F,G,H,I,J) \
133  struct name { \
134    template<typename T1,typename T2,typename T3,typename T4, \
135             typename T5,typename T6,typename T7,typename T8,typename T9,typename T10,typename T11> \
136    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6& F, T7& G, \
137      T8& H, T9& I, T10& J, T11) \
138    {
139
140#define BZ_DECLARE_STENCIL11(name,A,B,C,D,E,F,G,H,I,J,K) \
141  struct name { \
142    template<typename T1,typename T2,typename T3,typename T4, \
143             typename T5,typename T6,typename T7,typename T8,typename T9,typename T10, \
144             typename T11> \
145    static inline void apply(T1& A, T2& B, T3& C, T4& D, T5& E, T6& F, T7& G, \
146      T8& H, T9& I, T10& J, T11& K) \
147    {
148
149
150BZ_NAMESPACE(blitz)
151
152
153/*
154 * dummyArray is used to provide "dummy" padding parameters to applyStencil(),
155 * so that any number of arrays (up to 11) can be given as arguments.
156 */
157
158template<typename T> class dummy;
159
160struct dummyArray {
161    typedef dummy<double> T_iterator;
162
163    const dummyArray& shape() const { return *this; }
164};
165
166_bz_global dummyArray _dummyArray;
167
168/*
169 * This dummy class pretends to be a scalar of type T, or an array iterator
170 * of type T, but really does nothing.
171 */
172template<typename T>
173class dummy {
174public:
175    dummy() { }
176
177    dummy(T value)
178      : value_(value)
179    { }
180
181    dummy(const dummyArray&)
182    { }
183
184    operator T() const { return value_; };
185
186    template<typename T2>
187    void operator=(T2) { }
188
189    _bz_typename multicomponent_traits<T>::T_element operator[](int i) const
190    { return value_[i]; }
191
192    void loadStride(int) { }
193    void moveTo(int) { }
194    void moveTo(int,int) { }
195    void moveTo(int,int,int) { }
196    void moveTo(int,int,int,int) { }
197    void advance() { }
198    T shift(int,int) { return T(); }
199
200private:
201    T value_;
202};
203
204
205/*
206 * The stencilExtent object is passed to stencil objects to find out
207 * the spatial extent of the stencil.  It pretends it's an array,
208 * but really it's just recording the locations of the array reads
209 * via operator().
210 */
211
212template<int N_rank,typename P_numtype>
213class stencilExtent : public ETBase<stencilExtent<N_rank, P_numtype> > {
214public:
215    typedef P_numtype T_numtype;
216
217    stencilExtent()
218    {
219        min_ = 0;
220        max_ = 0;
221    }
222 
223    dummy<T_numtype> operator()(int i) const
224    {
225        update(0, i);
226        return dummy<T_numtype>(1);
227    }
228 
229    dummy<T_numtype> operator()(int i, int j) const
230    {
231        update(0, i);
232        update(1, j);
233        return dummy<T_numtype>(1);
234    }
235
236    dummy<T_numtype> operator()(int i, int j, int k) const
237    {
238        update(0, i);
239        update(1, j);
240        update(2, k);
241        return dummy<T_numtype>(1);
242    }
243
244    dummy<T_numtype> shift(int offset, int dim) const
245    {
246        update(dim, offset);
247        return dummy<T_numtype>(1);
248    }
249 
250    dummy<T_numtype> shift(int offset1, int dim1, int offset2, int dim2) const
251    {
252        update(dim1, offset1);
253        update(dim2, offset2);
254        return dummy<T_numtype>(1);
255    }
256 
257    dummy<_bz_typename multicomponent_traits<T_numtype>::T_element> 
258        operator[](int) const
259    {
260        return dummy<_bz_typename multicomponent_traits<T_numtype>::T_element>
261            (1);
262    }
263 
264    void update(int rank, int offset) const
265    {
266        if (offset < min_[rank])
267            min_[rank] = offset;
268        if (offset > max_[rank])
269            max_[rank] = offset;
270    }
271
272    template<typename T_numtype2>
273    void combine(const stencilExtent<N_rank,T_numtype2>& x) const
274    {
275        for (int i=0; i < N_rank; ++i)
276        {
277            min_[i] = (extrema::min)(min_[i], (x.min)(i));
278            max_[i] = (extrema::max)(max_[i], (x.max)(i));
279        }
280    }
281
282    template<typename T_numtype2>
283    void combine(const dummy<T_numtype2>&) const
284    { }
285
286    int (min)(int i) const
287    { return min_[i]; }
288
289    int (max)(int i) const
290    { return max_[i]; }
291
292    const TinyVector<int,N_rank>& (min)() const
293    { return min_; }
294
295    const TinyVector<int,N_rank>& (max)() const
296    { return max_; }
297
298    template<typename T>
299    void operator=(T)
300    { }
301
302    // NEEDS_WORK: other operators
303    template<typename T> void operator+=(T) { }
304    template<typename T> void operator-=(T) { }
305    template<typename T> void operator*=(T) { }
306    template<typename T> void operator/=(T) { }
307
308    operator T_numtype()
309    { return T_numtype(1); }
310
311    T_numtype operator*() const
312    { return T_numtype(1); }
313 
314private:
315    mutable TinyVector<int,N_rank> min_, max_;
316};
317
318
319/*
320 * stencilExtent_traits gives a stencilExtent<N,T> object for arrays,
321 * and a dummy object for dummy arrays.
322 */
323template<typename T>
324struct stencilExtent_traits {
325    typedef dummy<double> T_stencilExtent;
326};
327
328template<typename T_numtype, int N_rank>
329struct stencilExtent_traits<Array<T_numtype,N_rank> > {
330    typedef stencilExtent<N_rank,T_numtype> T_stencilExtent;
331};
332
333/*
334 * Specialization of areShapesConformable(), originally
335 * defined in <blitz/shapecheck.h>
336 */
337
338template<typename T_shape1>
339inline bool areShapesConformable(const T_shape1&, const dummyArray&) {
340    return true;
341}
342
343BZ_NAMESPACE_END
344
345#include <blitz/array/stencils.cc>
346
347#endif // BZ_ARRAYSTENCILS_H
348
Note: See TracBrowser for help on using the repository browser.