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