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

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 12.8 KB
Line 
1// -*- C++ -*-
2/***************************************************************************
3 * blitz/tinyvec.h      Declaration of the TinyVector<T, N> class
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
32#ifndef BZ_TINYVEC_H
33#define BZ_TINYVEC_H
34
35#include <blitz/blitz.h>
36#include <blitz/listinit.h>
37#include <blitz/et-forward.h>
38#include <blitz/etbase.h>
39#include <blitz/simdtypes.h>
40#include <blitz/array/slice.h>
41
42#ifdef BZ_HAVE_BOOST_SERIALIZATION
43#include <boost/serialization/serialization.hpp>
44#endif
45#ifdef BZ_HAVE_BOOST_MPI
46#include <boost/mpi/datatype.hpp>
47#endif
48
49#ifdef BZ_HAVE_CSTRING
50#include <cstring> // For memcpy
51#endif
52
53BZ_NAMESPACE(blitz)
54
55/*****************************************************************************
56 * Forward declarations
57 */
58
59template<typename P_numtype, int N_length>
60class FastTV2Iterator;
61template<typename P_numtype, int N_length>
62class FastTV2CopyIterator;
63
64
65/** The TinyVector class is a one-dimensional, fixed length vector
66    that implements the blitz expression template
67    machinery. TinyVector-only expressions are very fast because they
68    usually get reduced to just the unrolled (and vectorized, if
69    enabled) assembly instructions. TinyVectors can also be used in
70    mixed expressions with other ET classes. */
71template<typename P_numtype, int N_length>
72class TinyVector : public ETBase<TinyVector<P_numtype, N_length> >
73{
74public:
75
76    //////////////////////////////////////////////
77    // Public Types
78    //////////////////////////////////////////////
79
80    typedef P_numtype                                    T_numtype;
81    typedef TinyVector<T_numtype,N_length>               T_vector;
82    typedef FastTV2Iterator<T_numtype,N_length>         T_iterator;
83    typedef T_numtype*                                   iterator;
84    typedef const T_numtype*                             const_iterator;
85  typedef FastTV2CopyIterator<P_numtype, N_length> T_range_result;
86
87    static const int 
88    //numArrayOperands = 1,
89    //numIndexPlaceholders = 0,
90        rank_ = 1;
91
92    TinyVector()  { }
93    ~TinyVector() { }
94
95  TinyVector(const TinyVector<T_numtype,N_length>& x);
96
97    template <typename T_numtype2>
98    TinyVector(const TinyVector<T_numtype2,N_length>& x);
99
100  /** This constructor creates a TinyVector from another ETBase
101      object. It needs to be explicit to avoid all kinds of
102      ambiguities. */
103    template <typename T_expr>
104    inline explicit TinyVector(const ETBase<T_expr>& expr) {
105      *this = expr; }
106
107  /** This constructor creates a TinyVector specifically from an
108      expression. This one we do NOT want to be explicit because that
109      breaks simple construction assignments like "TinyVector<double,
110      1> v = a+b;", forcing the user to explicitly write it like a
111      construction. */
112    template <typename T_expr>
113    inline TinyVector(const _bz_ArrayExpr<T_expr>& expr) {
114      *this = expr; }
115
116    inline TinyVector(const T_numtype initValue);
117
118    inline TinyVector(const T_numtype x[]) {
119        memcpy(data_,x,N_length*sizeof(T_numtype));
120    }
121
122 
123    TinyVector(T_numtype x0, T_numtype x1)
124    {
125        data_[0] = x0;
126        data_[1] = x1;
127    }
128
129    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2)
130    {
131        data_[0] = x0;
132        data_[1] = x1;
133        data_[2] = x2;
134    }
135
136    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
137        T_numtype x3)
138    {
139        data_[0] = x0;
140        data_[1] = x1;
141        data_[2] = x2;
142        data_[3] = x3;
143    }
144
145    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
146        T_numtype x3, T_numtype x4)
147    {
148        data_[0] = x0;
149        data_[1] = x1;
150        data_[2] = x2;
151        data_[3] = x3;
152        data_[4] = x4;
153    }
154
155    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
156        T_numtype x3, T_numtype x4, T_numtype x5)
157    {
158        data_[0] = x0;
159        data_[1] = x1;
160        data_[2] = x2;
161        data_[3] = x3;
162        data_[4] = x4;
163        data_[5] = x5;
164    }
165
166    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
167        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6)
168    {
169        data_[0] = x0;
170        data_[1] = x1;
171        data_[2] = x2;
172        data_[3] = x3;
173        data_[4] = x4;
174        data_[5] = x5;
175        data_[6] = x6;
176    }
177
178    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
179        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
180        T_numtype x7)
181    {
182        data_[0] = x0;
183        data_[1] = x1;
184        data_[2] = x2;
185        data_[3] = x3;
186        data_[4] = x4;
187        data_[5] = x5;
188        data_[6] = x6;
189        data_[7] = x7;
190    }
191
192    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
193        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
194        T_numtype x7, T_numtype x8)
195    {
196        data_[0] = x0;
197        data_[1] = x1;
198        data_[2] = x2;
199        data_[3] = x3;
200        data_[4] = x4;
201        data_[5] = x5;
202        data_[6] = x6;
203        data_[7] = x7;
204        data_[8] = x8;
205    }
206
207    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
208        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
209        T_numtype x7, T_numtype x8, T_numtype x9)
210    {
211        data_[0] = x0;
212        data_[1] = x1;
213        data_[2] = x2;
214        data_[3] = x3;
215        data_[4] = x4;
216        data_[5] = x5;
217        data_[6] = x6;
218        data_[7] = x7;
219        data_[8] = x8;
220        data_[9] = x9;
221    }
222
223    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
224        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
225        T_numtype x7, T_numtype x8, T_numtype x9, T_numtype x10)
226    {
227        data_[0] = x0;
228        data_[1] = x1;
229        data_[2] = x2;
230        data_[3] = x3;
231        data_[4] = x4;
232        data_[5] = x5;
233        data_[6] = x6;
234        data_[7] = x7;
235        data_[8] = x8;
236        data_[9] = x9;
237        data_[10] = x10;
238    }
239
240  static int base() 
241  { return 0; }
242
243  static int                               base(int rank) 
244  { BZPRECONDITION(rank==0); return 0; }
245
246
247    T_iterator      beginFast() const       { return T_iterator(*this);      }
248
249    iterator       begin()       { return data_; }
250    const_iterator begin() const { return data_; }
251
252  static int                               dimensions()
253    { return 1; }
254
255    iterator       end()       { return data_ + N_length; }
256    const_iterator end() const { return data_ + N_length; }
257
258    T_numtype * restrict data()
259    { return data_; }
260
261    const T_numtype * restrict data() const
262    { return data_; }
263
264    T_numtype * restrict dataFirst()
265    { return data_; }
266
267    const T_numtype * restrict dataFirst() const
268    { return data_; }
269
270    const TinyVector<int, rank_>    shape() const
271    { return N_length; }
272
273  static int                               lbound(int rank) 
274  { BZPRECONDITION(rank==0); return 0; }
275  static int            lbound() 
276  { return 0; }
277
278  static int                               length(int rank) 
279  { BZPRECONDITION(rank==0); return N_length; }
280  static int    length() 
281  { return N_length; }
282
283  static int                               extent(int rank)
284  { BZPRECONDITION(rank==0); return N_length; }
285
286  static int                               ordering(int storageRankIndex) 
287  { return 0; }
288
289  static int    ordering() 
290  { return 0; }
291
292  static  int                               rank()
293    { return rank_; }
294
295    static sizeType                               numElements() 
296  { return length(); }
297
298    static diffType    stride() 
299    { return 1; }
300
301  static diffType                               stride(int rank) 
302    { BZPRECONDITION(rank==0); return 1; }
303
304  static int                               ubound(int rank) 
305  { BZPRECONDITION(rank==0); return length()-1; }
306
307  static int           ubound() 
308  { return length()-1; }
309
310     template<typename P_expr, typename P_updater>
311     void _bz_assign(P_expr, P_updater);
312
313    T_numtype operator*() const
314    { return *data_; }
315
316    //////////////////////////////////////////////
317    // Subscripting operators
318    //////////////////////////////////////////////
319
320    T_vector& noConst() const
321    { return const_cast<T_vector&>(*this); }
322
323  static bool lengthCheck(unsigned i) 
324    {
325        BZPRECHECK(i < N_length, 
326            "TinyVector<" << BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_numtype) 
327            << "," << N_length << "> index out of bounds: " << i);
328        return true;
329    }
330
331    const T_numtype& operator()(unsigned i) const
332    {
333        BZPRECONDITION(lengthCheck(i));
334        return data_[i];
335    }
336
337    T_numtype& restrict operator()(unsigned i)
338    { 
339        BZPRECONDITION(lengthCheck(i));
340        return data_[i];
341    }
342
343  T_numtype operator()(TinyVector<int,1> i) const
344    {
345        BZPRECONDITION(lengthCheck(i[0]));
346        return data_[i[0]];
347    }
348
349    template<int N0>
350    _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_vector>::T_expr, N0> >
351    operator()(IndexPlaceholder<N0>) const;
352
353    const T_numtype& operator[](unsigned i) const
354    {
355        BZPRECONDITION(lengthCheck(i));
356        return data_[i];
357    }
358
359    T_numtype& restrict operator[](unsigned i)
360    {
361        BZPRECONDITION(lengthCheck(i));
362        return data_[i];
363    }
364
365  // must return reference so the iterator can turn it into an
366  // iterator for the contained in case we have a multicomponent.
367  const T_numtype& fastRead(diffType i) const
368    { return data_[i]; }
369
370  /** Since data_ is simd aligned by construction, we just have
371      to check the offest. */
372  bool isVectorAligned(diffType offset) const 
373  { return (offset%simdTypes<T_numtype>::vecWidth)==0; }
374
375  bool canCollapse(int outerLoopRank, int innerLoopRank) const
376  {
377    BZPRECONDITION(outerLoopRank==0);
378    BZPRECONDITION(innerLoopRank==0);
379    return true;
380  }
381
382    //////////////////////////////////////////////
383    // Assignment operators
384    //////////////////////////////////////////////
385
386    // Scalar operand
387    ListInitializationSwitch<T_vector,T_numtype*> operator=(T_numtype x)
388    {
389        return ListInitializationSwitch<T_vector,T_numtype*>(*this, x);
390    }
391
392  T_vector& initialize(T_numtype);
393
394    template<typename T_expr>
395    T_vector& operator=(const ETBase<T_expr>&);
396
397    template<typename T> T_vector& operator+=(const T&);
398    template<typename T> T_vector& operator-=(const T&);
399    template<typename T> T_vector& operator*=(const T&);
400    template<typename T> T_vector& operator/=(const T&);
401    template<typename T> T_vector& operator%=(const T&);
402    template<typename T> T_vector& operator^=(const T&);
403    template<typename T> T_vector& operator&=(const T&);
404    template<typename T> T_vector& operator|=(const T&);
405    template<typename T> T_vector& operator>>=(const T&);
406    template<typename T> T_vector& operator<<=(const T&);
407
408    T_numtype* restrict getInitializationIterator()
409    { return dataFirst(); }
410
411  // // vectors can't be sliced
412  // template<typename T1, typename T2 = nilArraySection,
413  //       class T3 = nilArraySection, typename T4 = nilArraySection,
414  //       class T5 = nilArraySection, typename T6 = nilArraySection,
415  //       class T7 = nilArraySection, typename T8 = nilArraySection,
416  //       class T9 = nilArraySection, typename T10 = nilArraySection,
417  //       class T11 = nilArraySection>
418  // class SliceInfo {
419  // public:   
420  //   typedef void T_slice;
421  // };
422
423private:
424  template<typename T_expr, typename T_update>
425  void _tv_evaluate(const T_expr& expr, T_update);
426
427#ifdef BZ_HAVE_BOOST_SERIALIZATION
428  friend class boost::serialization::access;
429 
430  template<class T_arch>
431  void serialize(T_arch& ar, const unsigned int version) {
432    ar & data_;
433  };
434#endif
435
436
437  BZ_ALIGN_VARIABLE(T_numtype, data_[N_length], BZ_SIMD_WIDTH)
438};
439
440// Specialization for N = 0: KCC is giving some
441// peculiar errors, perhaps this will fix.
442
443template<typename T>
444class TinyVector<T,0> {
445};
446
447BZ_NAMESPACE_END
448
449#ifdef BZ_HAVE_BOOST_SERIALIZATION
450namespace boost {
451  namespace mpi {
452    template<typename T> struct is_mpi_datatype;
453    template <typename T, int N>
454    struct is_mpi_datatype<blitz::TinyVector<T, N> > 
455      : public is_mpi_datatype<T> { };
456  } };
457#endif
458
459
460#endif // BZ_TINYVEC_H
461
Note: See TracBrowser for help on using the repository browser.