00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifdef __GNUC__
00041 #define TOON_ALIGN8 __attribute__ ((aligned(8)))
00042 #else
00043 #define TOON_ALIGN8
00044 #endif
00045
00046 namespace TooN {
00047
00048 namespace Internal
00049 {
00050
00051 template<int Size, class Precision, bool heap> class StackOrHeap;
00052
00053 template<int Size, class Precision> class StackOrHeap<Size,Precision,0>
00054 {
00055 public:
00056 StackOrHeap()
00057 {
00058 debug_initialize(my_data, Size);
00059 }
00060 Precision my_data[Size];
00061 };
00062
00063 template<int Size> class StackOrHeap<Size,double,0>
00064 {
00065 public:
00066 StackOrHeap()
00067 {
00068 debug_initialize(my_data, Size);
00069 }
00070 double my_data[Size] TOON_ALIGN8 ;
00071 };
00072
00073
00074 template<int Size, class Precision> class StackOrHeap<Size, Precision, 1>
00075 {
00076 public:
00077 StackOrHeap()
00078 :my_data(new Precision[Size])
00079 {
00080 debug_initialize(my_data, Size);
00081 }
00082
00083
00084 ~StackOrHeap()
00085 {
00086 delete[] my_data;
00087 }
00088
00089 Precision *my_data;
00090
00091 StackOrHeap(const StackOrHeap& from)
00092 :my_data(new Precision[Size])
00093 {
00094 for(int i=0; i < Size; i++)
00095 my_data[i] = from.my_data[i];
00096 }
00097 };
00098
00099
00100
00101
00102
00103
00104
00105 template<int Size, class Precision> class StaticSizedAllocator: public StackOrHeap<Size, Precision, (sizeof(Precision)*Size>max_bytes_on_stack) >
00106 {
00107 };
00108
00109
00110
00111
00112
00113 template<int Size, class Precision> struct VectorAlloc : public StaticSizedAllocator<Size, Precision> {
00114
00115
00116 VectorAlloc() { }
00117
00118
00119 VectorAlloc(int ) { }
00120
00121
00122 template<class Op>
00123 VectorAlloc(const Operator<Op>&) {}
00124
00125
00126 int size() const {
00127 return Size;
00128 }
00129
00130 using StaticSizedAllocator<Size, Precision>::my_data;
00131
00132 Precision *get_data_ptr()
00133 {
00134 return my_data;
00135 };
00136
00137 const Precision *get_data_ptr() const
00138 {
00139 return my_data;
00140 }
00141
00142 protected:
00143
00144 Precision *data()
00145 {
00146 return my_data;
00147 };
00148
00149 const Precision *data() const
00150 {
00151 return my_data;
00152 };
00153
00154 };
00155
00156 template<class Precision> struct VectorAlloc<Dynamic, Precision> {
00157 Precision * const my_data;
00158 const int my_size;
00159
00160 VectorAlloc(const VectorAlloc& v)
00161 :my_data(new Precision[v.my_size]), my_size(v.my_size)
00162 {
00163 for(int i=0; i < my_size; i++)
00164 my_data[i] = v.my_data[i];
00165 }
00166
00167 VectorAlloc(int s)
00168 :my_data(new Precision[s]), my_size(s)
00169 {
00170 debug_initialize(my_data, my_size);
00171 }
00172
00173 template <class Op>
00174 VectorAlloc(const Operator<Op>& op)
00175 : my_data(new Precision[op.size()]), my_size(op.size())
00176 {
00177 debug_initialize(my_data, my_size);
00178 }
00179
00180 int size() const {
00181 return my_size;
00182 }
00183
00184 ~VectorAlloc(){
00185 delete[] my_data;
00186 }
00187
00188 Precision *get_data_ptr()
00189 {
00190 return my_data;
00191 };
00192
00193 const Precision *get_data_ptr() const
00194 {
00195 return my_data;
00196 }
00197
00198 protected:
00199
00200 Precision *data()
00201 {
00202 return my_data;
00203 };
00204
00205 const Precision *data() const
00206 {
00207 return my_data;
00208 };
00209 };
00210
00211
00212 template<class Precision> struct VectorAlloc<Resizable, Precision> {
00213 protected:
00214 std::vector<Precision> numbers;
00215
00216 public:
00217
00218 VectorAlloc()
00219 {
00220 }
00221
00222 VectorAlloc(int s)
00223 :numbers(s)
00224 {
00225 debug_initialize(data(), size());
00226 }
00227
00228 template <class Op>
00229 VectorAlloc(const Operator<Op>& op)
00230 :numbers(op.size())
00231 {
00232 debug_initialize(data(), size());
00233 }
00234
00235 int size() const {
00236 return numbers.size();
00237 }
00238
00239 Precision *get_data_ptr()
00240 {
00241 return data();
00242 };
00243
00244 const Precision *get_data_ptr() const
00245 {
00246 return data();
00247 }
00248
00249 protected:
00250
00251 Precision* data() {
00252 return &numbers[0];
00253 }
00254
00255 const Precision* data()const {
00256 return &numbers[0];
00257 }
00258
00259 public:
00260
00261 void resize(int s)
00262 {
00263 int old_size = size();
00264 numbers.resize(s);
00265 if(s > old_size)
00266 debug_initialize(data()+old_size, s-old_size);
00267 }
00268 };
00269
00270 template<int S, class Precision> struct VectorSlice
00271 {
00272 int size() const {
00273 return S;
00274 }
00275
00276
00277
00278 Precision* const my_data;
00279 VectorSlice(Precision* p)
00280 :my_data(p){}
00281
00282 VectorSlice(Precision* p, int )
00283 :my_data(p){}
00284
00285 template<class Op>
00286 VectorSlice(const Operator<Op>& op) : my_data(op.data()) {}
00287
00288 protected:
00289 Precision *data()
00290 {
00291 return my_data;
00292 };
00293
00294 const Precision *data() const
00295 {
00296 return my_data;
00297 };
00298 };
00299
00300 template<class Precision> struct VectorSlice<-1, Precision>
00301 {
00302 Precision* const my_data;
00303 const int my_size;
00304
00305 VectorSlice(Precision* d, int s)
00306 :my_data(d), my_size(s)
00307 { }
00308
00309 template<class Op>
00310 VectorSlice(const Operator<Op>& op) : my_data(op.data()), my_size(op.size()) {}
00311
00312 int size() const {
00313 return my_size;
00314 }
00315
00316 protected:
00317
00318 Precision *data()
00319 {
00320 return my_data;
00321 };
00322
00323 const Precision *data() const
00324 {
00325 return my_data;
00326 };
00327 };
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 template<int s> struct SizeHolder
00343 {
00344
00345 SizeHolder(){}
00346 SizeHolder(int){}
00347
00348
00349 int size() const{
00350 return s;
00351 }
00352 };
00353
00354
00355
00356
00357 template<> struct SizeHolder<-1>
00358 {
00359
00360
00361 SizeHolder(int s)
00362 :my_size(s){}
00363
00364
00365 const int my_size;
00366
00367 int size() const {
00368 return my_size;
00369 }
00370 };
00371
00372
00373
00374
00375
00376
00377
00378 template<int S> struct RowSizeHolder: private SizeHolder<S>
00379 {
00380
00381
00382
00383 RowSizeHolder(int i)
00384 :SizeHolder<S>(i){}
00385
00386 RowSizeHolder()
00387 {}
00388
00389
00390
00391
00392 template<typename Op>
00393 RowSizeHolder(const Operator<Op>& op) : SizeHolder<S>(op.num_rows()) {}
00394
00395
00396 int num_rows() const {return SizeHolder<S>::size();}
00397 };
00398
00399
00400
00401
00402
00403
00404 template<int S> struct ColSizeHolder: private SizeHolder<S>
00405 {
00406
00407
00408
00409 ColSizeHolder(int i)
00410 :SizeHolder<S>(i){}
00411
00412 ColSizeHolder()
00413 {}
00414
00415
00416
00417
00418 template<typename Op>
00419 ColSizeHolder(const Operator<Op>& op) : SizeHolder<S>(op.num_cols()) {}
00420
00421
00422 int num_cols() const {return SizeHolder<S>::size();}
00423 };
00424
00425
00426
00427 template<int R, int C, class Precision, bool FullyStatic=(R>=0 && C>=0)>
00428 struct MatrixAlloc: public StaticSizedAllocator<R*C, Precision>
00429 {
00430 MatrixAlloc(int,int)
00431 {}
00432
00433 MatrixAlloc()
00434 {}
00435
00436 template <class Op>
00437 MatrixAlloc(const Operator<Op>&)
00438 {}
00439
00440 int num_rows() const {
00441 return R;
00442 }
00443
00444 int num_cols() const {
00445 return C;
00446 }
00447
00448 using StaticSizedAllocator<R*C, Precision>::my_data;
00449
00450 Precision* get_data_ptr()
00451 {
00452 return my_data;
00453 }
00454
00455 const Precision* get_data_ptr() const
00456 {
00457 return my_data;
00458 }
00459 };
00460
00461
00462 template<int R, int C, class Precision> struct MatrixAlloc<R, C, Precision, false>
00463 : public RowSizeHolder<R>,
00464 ColSizeHolder<C>
00465 {
00466 Precision* const my_data;
00467
00468 using RowSizeHolder<R>::num_rows;
00469 using ColSizeHolder<C>::num_cols;
00470
00471
00472 MatrixAlloc(const MatrixAlloc& m)
00473 :RowSizeHolder<R>(m.num_rows()),
00474 ColSizeHolder<C>(m.num_cols()),
00475 my_data(new Precision[num_rows()*num_cols()]) {
00476 const int size=num_rows()*num_cols();
00477 for(int i=0; i < size; i++) {
00478 my_data[i] = m.my_data[i];
00479 }
00480 }
00481
00482 MatrixAlloc(int r, int c)
00483 :RowSizeHolder<R>(r),
00484 ColSizeHolder<C>(c),
00485 my_data(new Precision[num_rows()*num_cols()])
00486 {
00487 debug_initialize(my_data, num_rows()*num_cols());
00488 }
00489
00490 template <class Op> MatrixAlloc(const Operator<Op>& op)
00491 :RowSizeHolder<R>(op),
00492 ColSizeHolder<C>(op),
00493 my_data(new Precision[num_rows()*num_cols()])
00494 {
00495 debug_initialize(my_data, num_rows()*num_cols());
00496 }
00497
00498 ~MatrixAlloc() {
00499 delete[] my_data;
00500 }
00501
00502 Precision* get_data_ptr()
00503 {
00504 return my_data;
00505 }
00506
00507 const Precision* get_data_ptr() const
00508 {
00509 return my_data;
00510 }
00511 };
00512
00513
00514 template<int R, int C, class Precision> struct MatrixSlice
00515 : public RowSizeHolder<R>,
00516 ColSizeHolder<C>
00517 {
00518 Precision* const my_data;
00519
00520 using RowSizeHolder<R>::num_rows;
00521 using ColSizeHolder<C>::num_cols;
00522
00523
00524 MatrixSlice(Precision* p)
00525 :my_data(p){}
00526
00527 MatrixSlice(Precision* p, int r, int c)
00528 :RowSizeHolder<R>(r),
00529 ColSizeHolder<C>(c),
00530 my_data(p){}
00531
00532 template<class Op>
00533 MatrixSlice(const Operator<Op>& op)
00534 :RowSizeHolder<R>(op),
00535 ColSizeHolder<C>(op),
00536 my_data(op.data())
00537 {}
00538 };
00539
00540
00541
00542
00543
00544
00545
00546 template<int s> struct StrideHolder
00547 {
00548
00549 StrideHolder(){}
00550 StrideHolder(int){}
00551
00552 template<class Op>
00553 StrideHolder(const Operator<Op>&) {}
00554
00555 int stride() const{
00556 return s;
00557 }
00558 };
00559
00560 template<> struct StrideHolder<-1>
00561 {
00562 StrideHolder(int s)
00563 :my_stride(s){}
00564
00565 template<class Op>
00566 StrideHolder(const Operator<Op>& op) : my_stride(op.stride()) {}
00567
00568 const int my_stride;
00569 int stride() const {
00570 return my_stride;
00571 }
00572 };
00573
00574
00575 template<int S> struct RowStrideHolder: public StrideHolder<S>
00576 {
00577 RowStrideHolder(int i)
00578 :StrideHolder<S>(i){}
00579
00580 RowStrideHolder()
00581 {}
00582
00583 template<class Op>
00584 RowStrideHolder(const Operator<Op>& op)
00585 : StrideHolder<S>(op)
00586 {}
00587
00588 };
00589
00590
00591 template<int S> struct ColStrideHolder: public StrideHolder<S>
00592 {
00593 ColStrideHolder(int i)
00594 :StrideHolder<S>(i){}
00595
00596 ColStrideHolder()
00597 {}
00598
00599 template<class Op>
00600 ColStrideHolder(const Operator<Op>& op)
00601 : StrideHolder<S>(op)
00602 {}
00603 };
00604
00605 }
00606
00607 }
00608
00609
00610 #undef TOON_ALIGN8