blitz  Version 1.0.2
tm2fastiter.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  * blitz/array/fastiter.h Declaration of FastArrayIterator<P_numtype,N_rank>
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_ARRAY_TM2FASTITER_H
32 #define BZ_ARRAY_TM2FASTITER_H
33 
34 #ifdef BZ_HAVE_STD
35  #include <sstream>
36 #else
37  #include <strstream.h>
38 #endif
39 
41 #include <blitz/bzdebug.h>
42 #include <blitz/shapecheck.h>
43 #include <blitz/prettyprint.h>
44 
45 namespace blitz {
46 
47 // forward declaration
48 template<typename, int, int> class FastTM2Iterator;
49 template<typename, int, int> class FastTM2CopyIterator;
50 
51 
52 template<typename P_numtype, int N_rows, int N_columns, typename P_arraytype>
54 public:
55  typedef P_numtype T_numtype;
56  typedef typename opType<T_numtype>::T_optype T_optype;
57  // if T_numtype is POD, then T_result is T_numtype, but if T_numtype
58  // is an ET class, T_result will be the array class for that class.
59  typedef typename asET<T_numtype>::T_wrapped T_typeprop;
60  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
61 
66  typedef typename unwrapET<T_tvtypeprop>::T_unwrapped T_tvresult;
67 
70  typedef const T_matrix& T_ctorArg1;
71  typedef int T_ctorArg2; // dummy
73 
74  static const int
81  rank_ = 2;
82 
85  template<int N> struct tvresult {
87  };
88 
89  FastTM2IteratorBase(const T_iterator& x)
90  : data_(x.data_), array_(x.array_)
91  { }
92 
93  void operator=(const T_iterator& x)
94  {
95  BZPRECONDITION(0);
96  // doesn't this copy the data in x.array_ and then make data_
97  // point to x's array? doesn't seem right
98  array_ = x.array_;
99  data_ = x.data_;
100  stack_ = x.stack_;
101  //stride_ = x.stride_;
102  }
103 
104  FastTM2IteratorBase(const T_matrix& array)
105  : array_(array)
106  {
107  data_ = array_.data();
108  }
109 
111  { }
112 
114  {
115  return array_(i);
116  }
117 
118  static int ascending(const int r)
119  {
120  if (r<rank_)
122  else
123  return INT_MIN;
124  }
125 
126  static int ordering(const int r)
127  {
128  if (r<rank_)
129  return T_matrix::ordering(r);
130  else
131  return INT_MIN;
132  }
133 
134  static int lbound(const int r)
135  {
136  if (r<rank_)
137  return T_matrix::lbound(r);
138  else
139  return INT_MIN;
140  }
141 
142  static int ubound(const int r)
143  {
144  if (r<rank_)
145  return T_matrix::ubound(r);
146  else
147  return INT_MAX;
148  }
149 
150  //RectDomain<rank_> domain() const { return T_matrix::domain(); };
151 
152  T_result first_value() const { return *data_; }
153 
154  T_result operator*() const
155  { return *data_; }
156 
157  T_result operator[](int i) const
158  { return data_[i * stride_]; }
159 
160  T_result fastRead(diffType i) const
161  { return array_.fastRead(i); }
162 
163  template<int N>
164  typename tvresult<N>::Type fastRead_tv(diffType i) const
165  {
166  return typename tvresult<N>::Type(*reinterpret_cast<const TinyVector<T_numtype,N>*>(&data_[i])); }
167 
170  bool isVectorAligned(diffType offset) const
171  { return (offset%simdTypes<T_numtype>::vecWidth==0) ? true : false; }
172 
173  static int suggestStride(int r)
174  { return T_matrix::stride(r); }
175 
176  static bool isStride(int r, diffType stride)
177  { return T_matrix::stride(r) == stride; }
178 
179  void push(int position)
180  {
181  stack_[position] = data_;
182  }
183 
184  void pop(int position)
185  {
186  data_ = stack_[position];
187  }
188 
189  void advance()
190  {
191  data_ += stride_;
192  }
193 
194  void advance(int n)
195  {
196  data_ += n * stride_;
197  }
198 
199  void loadStride(int rank)
200  {
201  stride_ = T_matrix::stride(rank);
202  }
203 
204  // This is used as lvalue, so it should return the actual data
205  const T_numtype * restrict data() const
206  { return data_; }
207 
208  const T_matrix& array() const
209  {return array_; }
210 
211  void _bz_setData(const T_numtype* ptr)
212  { data_ = ptr; }
213 
214  // this is needed for the stencil expression fastRead to work
216  { data_ += i;}
217 
218  // and these are needed for stencil expression shift to work
219  void _bz_offsetData(sizeType offset, int dim)
220  { data_ += offset*T_matrix::stride(dim); }
221 
222  void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int dim2)
223  { data_ += offset1*T_matrix::stride(dim1);
224  data_ += offset2*T_matrix::stride(dim2); }
225 
226  int stride() const
227  { return stride_; }
228 
229  static bool isUnitStride(int r)
230  { return T_matrix::stride(r) == 1; }
231 
232  bool isUnitStride() const
233  { return stride() == 1; }
234 
236  { ++data_; }
237 
238  bool canCollapse(int outerLoopRank, int innerLoopRank) const
239  { return T_matrix::canCollapse(outerLoopRank, innerLoopRank); }
240 
241  template<typename T_shape>
242  bool shapeCheck(const T_shape& s) const
243  { return areShapesConformable(s, T_matrix::length()); }
244 
245  /*
246  // Experimental
247  T_numtype& operator()(int i) const
248  {
249  return (T_numtype&)data_[i*T_matrix::stride(0)];
250  }
251 
252  // Experimental
253  T_numtype& operator()(int i, int j) const
254  {
255  return (T_numtype&)data_[i*T_matrix::stride(0) + j*T_matrix::stride(1)];
256  }
257 
258  // Experimental
259 
260  void moveTo(int i)
261  {
262  data_ = &const_cast<T_matrix&>(array_)(i);
263  }
264 
265  void moveTo(int i, int j)
266  {
267  data_ = &const_cast<T_matrix&>(array_)(i,j);
268  }
269 
270  template<int N_rank2>
271  void moveTo(const TinyVector<int,N_rank2>& i)
272  {
273  data_ = &const_cast<T_matrix&>(array_)(i);
274  }
275 
276  // Experimental
277  void operator=(T_numtype x)
278  { *const_cast<T_numtype*>(data_) = x; }
279 
280  // Experimental
281  template<typename T_value>
282  void operator=(T_value x)
283  { *const_cast<T_numtype*>(data_) = x; }
284 
285  // Experimental
286  template<typename T_value>
287  void operator+=(T_value x)
288  { *const_cast<T_numtype*>(data_) += x; }
289 
290  // NEEDS_WORK: other operators
291 
292  // Experimental
293  operator T_numtype() const
294  { return *data_; }
295  */
296 
297  // Experimental
298  T_result shift(int offset, int dim) const
299  {
300  return data_[offset*T_matrix::stride(dim)];
301  }
302 
303  // Experimental
304  T_result shift(int offset1, int dim1, int offset2, int dim2) const
305  {
306  return data_[offset1*T_matrix::stride(dim1)
307  + offset2*T_matrix::stride(dim2)];
308  }
309 
310  void prettyPrint(std::string &str,
311  prettyPrintFormat& format) const
312  {
313  if (format.tersePrintingSelected())
314  str += format.nextArrayOperandSymbol();
315  else if (format.dumpArrayShapesMode())
316  {
317 #ifdef BZ_HAVE_STD
318  std::ostringstream ostr;
319 #else
320  ostrstream ostr;
321 #endif
322  ostr << T_matrix::shape();
323  str += ostr.str();
324  }
325  else {
326  str += "TinyMatrix<";
327  str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_numtype);
328  str += ",";
329 
330  char tmpBuf[10];
331  sprintf(tmpBuf, "%d", N_rows);
332 
333  str += tmpBuf;
334  str += ",";
335  sprintf(tmpBuf, "%d", N_columns);
336 
337  str += tmpBuf;
338  str += ">";
339  }
340  }
341 
342  // tiny matrices can't be sliced
343  template<typename T1, typename T2 = nilArraySection,
344  class T3 = nilArraySection, typename T4 = nilArraySection,
345  class T5 = nilArraySection, typename T6 = nilArraySection,
346  class T7 = nilArraySection, typename T8 = nilArraySection,
347  class T9 = nilArraySection, typename T10 = nilArraySection,
348  class T11 = nilArraySection>
349  class SliceInfo {
350  public:
351  typedef void T_slice;
352 };
353 
354 protected:
355  const T_numtype * restrict data_;
356  P_arraytype array_;
359 };
360 
361 
362 template<typename P_numtype, int N_rows, int N_columns>
363 class FastTM2CopyIterator;
364 
365 
366 template<typename P_numtype, int N_rows, int N_columns>
367 class FastTM2Iterator :
368  public FastTM2IteratorBase<P_numtype, N_rows, N_columns,
369  const TinyMatrix<P_numtype, N_rows, N_columns>&>
370 {
371 public:
372  typedef FastTM2IteratorBase<P_numtype, N_rows, N_columns,
374  typedef typename T_base::T_numtype T_numtype;
375  typedef typename T_base::T_matrix T_matrix;
376  typedef typename T_base::T_iterator T_iterator;
377  typedef typename T_base::T_ctorArg1 T_ctorArg1;
378  typedef typename T_base::T_ctorArg2 T_ctorArg2;
380 
381  using T_base::rank_;
383  using T_base::numTVOperands;
384  using T_base::numTMOperands;
386 
387  // NB: this ctor does NOT preserve stack and stride
388  // parameters. This is for speed purposes.
390  : T_base(x)
391  { }
392 
393  FastTM2Iterator(const T_matrix& array) : T_base(array) {}
394 
395  using T_base::operator=;
397  {
399  }
400 
401  using T_base::operator();
402 
403  // template<int N>
404  // T_range_result operator()(const RectDomain<N>& d) const
405  // {
406  // return T_range_result(T_base::array_(d));
407  // }
408 
409  // template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
410  // typename T7, typename T8, typename T9, typename T10, typename T11>
411  // FastTM2CopyIterator<T_numtype, T_base::template SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice::rank>
412  // operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const
413  // {
414  // typedef FastTM2CopyIterator<T_numtype, T_base::template SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice::rank> slice;
415 
416  // return slice(array_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11));
417  // }
418 
419 };
420 
421 /* This version of the FastTM2Iterator makes a COPY of the array
422  it's pointing to. This makes it possible to return expressions of
423  arrays that have gone out of scope, or to slice expressions. */
424 template<typename P_numtype, int N_rows, int N_columns>
425 class FastTM2CopyIterator :
426  public FastTM2IteratorBase<P_numtype, N_rows, N_columns, const TinyMatrix<P_numtype, N_rows, N_columns> >
427 {
428 public:
429  typedef FastTM2IteratorBase<P_numtype, N_rows, N_columns,
431  typedef typename T_base::T_numtype T_numtype;
432  typedef typename T_base::T_matrix T_matrix;
433  typedef typename T_base::T_iterator T_iterator;
434  typedef typename T_base::T_ctorArg1 T_ctorArg1;
435  typedef typename T_base::T_ctorArg2 T_ctorArg2;
437 
438  using T_base::rank_;
440  using T_base::numTVOperands;
441  using T_base::numTMOperands;
443 
444 
445  // NB: this ctor does NOT preserve stack and stride
446  // parameters. This is for speed purposes.
448  : T_base(x)
449  { }
450 
451  FastTM2CopyIterator(const T_matrix& array) : T_base(array) { }
452 
453  using T_base::operator=;
455  {
457  }
458 
459  using T_base::operator();
460 
461  // template<int N>
462  // T_range_result operator()(const RectDomain<N>& d) const
463  // {
464  // return T_range_result(T_base::array_(d));
465  // }
466 
467  // template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
468  // typename T7, typename T8, typename T9, typename T10, typename T11>
469  // FastTM2CopyIterator<T_numtype, T_base::template SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice::rank>
470  // operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const
471  // {
472  // typedef FastTM2CopyIterator<T_numtype, T_base::template SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice::rank> slice;
473 
474  // return slice(array_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11));
475  // }
476 };
477 
478 
479 }
480 
481 #endif // BZ_ARRAY_FASTITER_H
bool tersePrintingSelected() const
Definition: prettyprint.h:61
_bz_global blitz::IndexPlaceholder< 9 > r
Definition: indexexpr.h:265
asET< T_numtype >::T_wrapped T_typeprop
Definition: tm2fastiter.h:59
Definition: tm2fastiter.h:53
T_base::T_matrix T_matrix
Definition: tm2fastiter.h:375
T_base::T_numtype T_numtype
Definition: tm2fastiter.h:431
FastTM2Iterator(const T_matrix &array)
Definition: tm2fastiter.h:393
ETBase< FastTV2Iterator< T_numtype, simdTypes< T_numtype >::vecWidth > > T_tvtypeprop
Result type for fastRead_tv is a FastTVIterator.
Definition: tm2fastiter.h:65
opType< T_numtype >::T_optype T_optype
Definition: tm2fastiter.h:56
T_result fastRead(diffType i) const
Definition: tm2fastiter.h:160
_bz_global blitz::IndexPlaceholder< 0 > i
Definition: indexexpr.h:256
bool shapeCheck(const T_shape &s) const
Definition: tm2fastiter.h:242
Helper class that defines the width of the simd instructions for a given type.
Definition: simdtypes.h:31
void _bz_offsetData(sizeType i)
Definition: tm2fastiter.h:215
static TinyVector< int, 2 > length()
Definition: tinymat2.h:163
unwrapET< T_typeprop >::T_unwrapped T_result
Definition: tm2fastiter.h:60
void operator=(const T_iterator &x)
Definition: tm2fastiter.h:93
T_base::T_iterator T_iterator
Definition: tm2fastiter.h:376
void push(int position)
Definition: tm2fastiter.h:179
Definition: et-forward.h:25
T_base::T_range_result T_range_result
Definition: tm2fastiter.h:379
T_result operator*() const
Definition: tm2fastiter.h:154
static TinyVector< diffType, 2 > stride()
Definition: tinymat2.h:187
T_base::T_ctorArg2 T_ctorArg2
Definition: tm2fastiter.h:435
char nextArrayOperandSymbol()
Definition: prettyprint.h:52
void advance(int n)
Definition: tm2fastiter.h:194
TinyMatrix< T_numtype, N_rows, N_columns > T_matrix
Definition: tm2fastiter.h:68
static int suggestStride(int r)
Definition: tm2fastiter.h:173
static int ordering(const int r)
Definition: tm2fastiter.h:126
T_result operator()(TinyVector< int, 2 > i) const
Definition: tm2fastiter.h:113
static const int numArrayOperands
Definition: tm2fastiter.h:75
bool isVectorAligned(diffType offset) const
Since data_ is simd aligned by construction, we just have to check the offest.
Definition: tm2fastiter.h:170
int stride() const
Definition: tm2fastiter.h:226
Definition: et-forward.h:10
static TinyVector< int, 2 > shape()
Definition: tinymat2.h:181
const T_matrix & T_ctorArg1
Definition: tm2fastiter.h:70
FastTM2IteratorBase< P_numtype, N_rows, N_columns, const TinyMatrix< P_numtype, N_rows, N_columns > & > T_base
Definition: tm2fastiter.h:373
bool canCollapse(int outerLoopRank, int innerLoopRank) const
Definition: tm2fastiter.h:238
T_base::T_numtype T_numtype
Definition: tm2fastiter.h:374
P_numtype T_numtype
Definition: tm2fastiter.h:55
FastTM2CopyIterator(const T_matrix &array)
Definition: tm2fastiter.h:451
P_arraytype array_
Definition: tm2fastiter.h:356
void _bz_setData(const T_numtype *ptr)
Definition: tm2fastiter.h:211
void T_slice
Definition: tm2fastiter.h:351
T_base::T_ctorArg2 T_ctorArg2
Definition: tm2fastiter.h:378
Definition: et-forward.h:20
static bool isStride(int r, diffType stride)
Definition: tm2fastiter.h:176
Definition: et-forward.h:23
static int ascending(const int r)
Definition: tm2fastiter.h:118
static TinyVector< int, 2 > lbound()
Definition: tinymat2.h:158
Definition: array-impl.h:66
void _bz_offsetData(sizeType offset, int dim)
Definition: tm2fastiter.h:219
For an iterator, the vectorized result for width N is always a TinyVector.
Definition: tm2fastiter.h:85
ptrdiff_t diffType
Definition: blitz.h:111
FastTM2IteratorBase(const T_matrix &array)
Definition: tm2fastiter.h:104
T_result first_value() const
Definition: tm2fastiter.h:152
~FastTM2IteratorBase()
Definition: tm2fastiter.h:110
static TinyVector< int, 2 > ordering()
Definition: tinymat2.h:172
tvresult< N >::Type fastRead_tv(diffType i) const
Definition: tm2fastiter.h:164
FastTM2IteratorBase< P_numtype, N_rows, N_columns, P_arraytype > T_iterator
Definition: tm2fastiter.h:69
bool areShapesConformable(const T_shape1 &, const T_shape2 &)
Definition: shapecheck.h:50
void advance()
Definition: tm2fastiter.h:189
ConstPointerStack< T_numtype, rank_ > stack_
Definition: tm2fastiter.h:357
size_t sizeType
Definition: blitz.h:110
static const int minWidth
Definition: tm2fastiter.h:79
void pop(int position)
Definition: tm2fastiter.h:184
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int dim2)
Definition: tm2fastiter.h:222
static const int maxWidth
Definition: tm2fastiter.h:80
T_base::T_ctorArg1 T_ctorArg1
Definition: tm2fastiter.h:434
static bool isRankStoredAscending(int rank)
Definition: tinymat2.h:153
FastTM2CopyIterator< P_numtype, N_rows, N_columns > T_range_result
Definition: tm2fastiter.h:72
Definition: tm2fastiter.h:349
static const int numTMOperands
Definition: tm2fastiter.h:77
T_base::T_iterator T_iterator
Definition: tm2fastiter.h:433
T_result shift(int offset, int dim) const
Definition: tm2fastiter.h:298
diffType stride_
Definition: tm2fastiter.h:358
FastTM2Iterator(const FastTM2Iterator &x)
Definition: tm2fastiter.h:389
static int lbound(const int r)
Definition: tm2fastiter.h:134
void advanceUnitStride()
Definition: tm2fastiter.h:235
int T_ctorArg2
Definition: tm2fastiter.h:71
const T_numtype *restrict data() const
Definition: tm2fastiter.h:205
T_result shift(int offset1, int dim1, int offset2, int dim2) const
Definition: tm2fastiter.h:304
FastTV2Iterator< T_numtype, N > Type
Definition: tm2fastiter.h:86
void loadStride(int rank)
Definition: tm2fastiter.h:199
static TinyVector< int, 2 > ubound()
Definition: tinymat2.h:196
const T_matrix & array() const
Definition: tm2fastiter.h:208
T_base::T_range_result T_range_result
Definition: tm2fastiter.h:436
static const int numTVOperands
Definition: tm2fastiter.h:76
bool isUnitStride() const
Definition: tm2fastiter.h:232
_bz_global blitz::IndexPlaceholder< 10 > s
Definition: indexexpr.h:266
T_base::T_ctorArg1 T_ctorArg1
Definition: tm2fastiter.h:377
unwrapET< T_tvtypeprop >::T_unwrapped T_tvresult
Definition: tm2fastiter.h:66
T_base::T_matrix T_matrix
Definition: tm2fastiter.h:432
void prettyPrint(std::string &str, prettyPrintFormat &format) const
Definition: tm2fastiter.h:310
FastTM2IteratorBase< P_numtype, N_rows, N_columns, const TinyMatrix< P_numtype, N_rows, N_columns > > T_base
Definition: tm2fastiter.h:430
static const int rank_
Definition: tm2fastiter.h:81
static bool isUnitStride(int r)
Definition: tm2fastiter.h:229
#define restrict
Definition: compiler.h:95
void operator=(const FastTM2CopyIterator &x)
Definition: tm2fastiter.h:454
The TinyVector class is a one-dimensional, fixed length vector that implements the blitz expression t...
Definition: et-forward.h:14
_bz_global blitz::IndexPlaceholder< 5 > n
Definition: indexexpr.h:261
static int ubound(const int r)
Definition: tm2fastiter.h:142
FastTM2IteratorBase(const T_iterator &x)
Definition: tm2fastiter.h:89
bool dumpArrayShapesMode() const
Definition: prettyprint.h:62
const T_numtype *restrict data_
Definition: tm2fastiter.h:355
static const int numIndexPlaceholders
Definition: tm2fastiter.h:78
void operator=(const FastTM2Iterator< P_numtype, N_rows, N_columns > &x)
Definition: tm2fastiter.h:396
FastTM2CopyIterator(const FastTM2CopyIterator &x)
Definition: tm2fastiter.h:447
Definition: et-forward.h:15
T_result operator[](int i) const
Definition: tm2fastiter.h:157
static bool canCollapse(int outerRank, int innerRank)
Definition: tinymat2.h:317
Definition: prettyprint.h:40