2
/***************************************************************************
3
* blitz/array/stencil-et.h Expression-template-capabale stencils
5
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* Suggestions: blitz-dev@oonumerics.org
18
* Bugs: blitz-bugs@oonumerics.org
20
* For more information, please see the Blitz++ Home Page:
21
* http://oonumerics.org/blitz/
23
****************************************************************************/
24
#ifndef BZ_ARRAY_STENCIL_ET_H
25
#define BZ_ARRAY_STENCIL_ET_H
29
template<typename T_ArrayNumtype, int N_rank, typename T_result>
33
typedef T_result T_numtype;
34
typedef Array<T_ArrayNumtype,N_rank> T_array;
35
typedef const T_array& T_ctorArg1;
36
typedef int T_ctorArg2;
40
numIndexPlaceholders = 0,
43
StencilExpr(const T_array& array)
50
// operator* must be declared by subclass
52
int ascending(int rank)
53
{ return iter_.ascending(rank); }
55
int ordering(int rank)
56
{ return iter_.ordering(rank); }
59
{ return iter_.lbound(rank); }
62
{ return iter_.ubound(rank); }
64
void push(int position)
65
{ iter_.push(position); }
67
void pop(int position)
68
{ iter_.pop(position); }
76
void loadStride(int rank)
77
{ iter_.loadStride(rank); }
79
bool isUnitStride(int rank) const
80
{ return iter_.isUnitStride(rank); }
82
void advanceUnitStride()
83
{ iter_.advanceUnitStride(); }
85
bool canCollapse(int outerLoopRank, int innerLoopRank) const
87
// BZ_DEBUG_MESSAGE("_bz_ArrayExpr<>::canCollapse()");
88
return iter_.canCollapse(outerLoopRank, innerLoopRank);
91
// T_numtype operator[](int i) -- don't know how to do that.
93
// T_numtype fastRead(int i) -- ditto
95
int suggestStride(int rank) const
96
{ return iter_.suggestStride(rank); }
98
bool isStride(int rank, int stride) const
99
{ return iter_.isStride(rank,stride); }
101
void prettyPrint(BZ_STD_SCOPE(string) &str) const
103
str += "(stencil)"; // lame, needs work
106
void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat&) const
107
{ str += "(stencil)"; }
109
template<typename T_shape>
110
bool shapeCheck(const T_shape& shape)
111
{ return iter_.shapeCheck(shape); }
113
void moveTo(const TinyVector<int,N_rank>& i)
119
FastArrayIterator<T_ArrayNumtype,N_rank> iter_;
122
#define BZ_ET_STENCIL(name,result) \
123
template<typename P_numtype, int N_rank> \
124
class name ## _et : public StencilExpr<P_numtype,N_rank,result>, \
125
public ETBase<name ## _et<P_numtype,N_rank> > \
128
typedef StencilExpr<P_numtype,N_rank,result> T_base; \
129
using T_base::iter_; \
131
name ## _et(const Array<P_numtype,N_rank>& A) \
132
: StencilExpr<P_numtype,N_rank,result>(A) \
135
{ return name(iter_); } \
136
result operator()(const TinyVector<int,N_rank>& a) \
137
{ iter_.moveTo(a); return name(iter_); } \
138
result fastRead(int i) \
140
const P_numtype* tmp = iter_.data(); \
141
iter_._bz_setData(tmp + i); \
142
P_numtype r = name(iter_); \
143
iter_._bz_setData(tmp); \
147
template<typename P_numtype, int N_rank> \
148
inline _bz_ArrayExpr<name ## _et<P_numtype, N_rank> > \
149
name(Array<P_numtype,N_rank>& A) \
151
return _bz_ArrayExpr<name ## _et<P_numtype, N_rank> >(A); \
154
#define BZ_ET_STENCILV(name,rank) \
155
template<typename P_numtype, int N_rank> \
156
class name ## _et : public StencilExpr<P_numtype,N_rank, \
157
TinyVector<P_numtype,rank> >, \
158
public ETBase<name ## _et<P_numtype,N_rank> > \
161
typedef StencilExpr<P_numtype,N_rank,TinyVector<P_numtype,rank> > T_base; \
162
using T_base::iter_; \
164
typedef TinyVector<P_numtype,rank> result; \
165
name ## _et(const Array<P_numtype,N_rank>& A) \
166
: StencilExpr<P_numtype,N_rank,result>(A) \
169
{ return name(iter_); } \
170
result operator()(const TinyVector<int,N_rank>& a) \
171
{ iter_.moveTo(a); return name(iter_); } \
172
result fastRead(int i) \
174
const P_numtype* tmp = iter_.data(); \
175
iter_._bz_setData(tmp + i); \
176
P_numtype r = name(iter_); \
177
iter_._bz_setData(tmp); \
181
template<typename P_numtype, int N_rank> \
182
inline _bz_ArrayExpr<name ## _et<P_numtype, N_rank> > \
183
name(Array<P_numtype,N_rank>& A) \
185
return _bz_ArrayExpr< name ## _et<P_numtype, N_rank> >(A); \
188
#define BZ_ET_STENCIL_DIFF(name) \
189
template<typename P_numtype, int N_rank> \
190
class name ## _et : public StencilExpr<P_numtype,N_rank,P_numtype>, \
191
public ETBase<name ## _et<P_numtype,N_rank> > \
194
typedef StencilExpr<P_numtype,N_rank,P_numtype> T_base; \
195
using T_base::iter_; \
197
name ## _et(const Array<P_numtype,N_rank>& A, int dim) \
198
: StencilExpr<P_numtype,N_rank,P_numtype>(A), dim_(dim) \
200
P_numtype operator*() \
201
{ return name(iter_); } \
202
P_numtype operator()(const TinyVector<int,N_rank>& a) \
203
{ iter_.moveTo(a); return name(iter_,dim_); } \
204
P_numtype fastRead(int i) \
206
const P_numtype* tmp = iter_.data(); \
207
iter_._bz_setData(tmp + i); \
208
P_numtype r = name(iter_,dim_); \
209
iter_._bz_setData(tmp); \
215
template<typename P_numtype, int N_rank> \
216
inline _bz_ArrayExpr<name ## _et<P_numtype, N_rank> > \
217
name(Array<P_numtype,N_rank>& A, int dim) \
219
return _bz_ArrayExpr<name ## _et<P_numtype, N_rank> >(A,dim); \
223
BZ_ET_STENCIL(Laplacian2D, P_numtype)
224
BZ_ET_STENCIL(Laplacian3D, P_numtype)
225
BZ_ET_STENCIL(Laplacian2D4, P_numtype)
226
BZ_ET_STENCIL(Laplacian2D4n, P_numtype)
227
BZ_ET_STENCIL(Laplacian3D4, P_numtype)
228
BZ_ET_STENCIL(Laplacian3D4n, P_numtype)
229
BZ_ET_STENCILV(grad2D, 2)
230
BZ_ET_STENCILV(grad2D4, 2)
231
BZ_ET_STENCILV(grad3D, 3)
232
BZ_ET_STENCILV(grad3D4, 3)
233
BZ_ET_STENCILV(grad2Dn, 2)
234
BZ_ET_STENCILV(grad2D4n, 2)
235
BZ_ET_STENCILV(grad3Dn, 3)
236
BZ_ET_STENCILV(grad3D4n, 3)
237
BZ_ET_STENCILV(gradSqr2D, 2)
238
BZ_ET_STENCILV(gradSqr2D4, 2)
239
BZ_ET_STENCILV(gradSqr3D, 3)
240
BZ_ET_STENCILV(gradSqr3D4, 3)
241
BZ_ET_STENCILV(gradSqr2Dn, 2)
242
BZ_ET_STENCILV(gradSqr2D4n, 2)
243
BZ_ET_STENCILV(gradSqr3Dn, 3)
244
BZ_ET_STENCILV(gradSqr3D4n, 3)
252
BZ_ET_STENCIL_DIFF(central12)
253
BZ_ET_STENCIL_DIFF(central22)
254
BZ_ET_STENCIL_DIFF(central32)
255
BZ_ET_STENCIL_DIFF(central42)
256
BZ_ET_STENCIL_DIFF(central14)
257
BZ_ET_STENCIL_DIFF(central24)
258
BZ_ET_STENCIL_DIFF(central34)
259
BZ_ET_STENCIL_DIFF(central44)
260
BZ_ET_STENCIL_DIFF(central12n)
261
BZ_ET_STENCIL_DIFF(central22n)
262
BZ_ET_STENCIL_DIFF(central32n)
263
BZ_ET_STENCIL_DIFF(central42n)
264
BZ_ET_STENCIL_DIFF(central14n)
265
BZ_ET_STENCIL_DIFF(central24n)
266
BZ_ET_STENCIL_DIFF(central34n)
267
BZ_ET_STENCIL_DIFF(central44n)
269
BZ_ET_STENCIL_DIFF(backward11)
270
BZ_ET_STENCIL_DIFF(backward21)
271
BZ_ET_STENCIL_DIFF(backward31)
272
BZ_ET_STENCIL_DIFF(backward41)
273
BZ_ET_STENCIL_DIFF(backward12)
274
BZ_ET_STENCIL_DIFF(backward22)
275
BZ_ET_STENCIL_DIFF(backward32)
276
BZ_ET_STENCIL_DIFF(backward42)
277
BZ_ET_STENCIL_DIFF(backward11n)
278
BZ_ET_STENCIL_DIFF(backward21n)
279
BZ_ET_STENCIL_DIFF(backward31n)
280
BZ_ET_STENCIL_DIFF(backward41n)
281
BZ_ET_STENCIL_DIFF(backward12n)
282
BZ_ET_STENCIL_DIFF(backward22n)
283
BZ_ET_STENCIL_DIFF(backward32n)
284
BZ_ET_STENCIL_DIFF(backward42n)
286
BZ_ET_STENCIL_DIFF(forward11)
287
BZ_ET_STENCIL_DIFF(forward21)
288
BZ_ET_STENCIL_DIFF(forward31)
289
BZ_ET_STENCIL_DIFF(forward41)
290
BZ_ET_STENCIL_DIFF(forward12)
291
BZ_ET_STENCIL_DIFF(forward22)
292
BZ_ET_STENCIL_DIFF(forward32)
293
BZ_ET_STENCIL_DIFF(forward42)
294
BZ_ET_STENCIL_DIFF(forward11n)
295
BZ_ET_STENCIL_DIFF(forward21n)
296
BZ_ET_STENCIL_DIFF(forward31n)
297
BZ_ET_STENCIL_DIFF(forward41n)
298
BZ_ET_STENCIL_DIFF(forward12n)
299
BZ_ET_STENCIL_DIFF(forward22n)
300
BZ_ET_STENCIL_DIFF(forward32n)
301
BZ_ET_STENCIL_DIFF(forward42n)
306
#endif // BZ_ARRAY_STENCIL_ET_H