| 1 | #ifndef BZ_ARRAYREDUCE_H
 | 
|---|
| 2 |  #error <blitz/array/reduce.cc> must be included via <blitz/array/reduce.h>
 | 
|---|
| 3 | #endif
 | 
|---|
| 4 | 
 | 
|---|
| 5 | BZ_NAMESPACE(blitz)
 | 
|---|
| 6 | 
 | 
|---|
| 7 | template<class T_expr, class T_reduction>
 | 
|---|
| 8 | _bz_typename T_reduction::T_resulttype
 | 
|---|
| 9 | _bz_reduceWithIndexTraversal(T_expr expr, T_reduction reduction);
 | 
|---|
| 10 | 
 | 
|---|
| 11 | template<class T_expr, class T_reduction>
 | 
|---|
| 12 | _bz_typename T_reduction::T_resulttype
 | 
|---|
| 13 | _bz_reduceWithStackTraversal(T_expr expr, T_reduction reduction);
 | 
|---|
| 14 | 
 | 
|---|
| 15 | template<class T_expr, class T_reduction>
 | 
|---|
| 16 | _bz_typename T_reduction::T_resulttype
 | 
|---|
| 17 | _bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction)
 | 
|---|
| 18 | {
 | 
|---|
| 19 | #ifdef BZ_TAU_PROFILING
 | 
|---|
| 20 |     // Tau profiling code.  Provide Tau with a pretty-printed version of
 | 
|---|
| 21 |     // the expression.
 | 
|---|
| 22 |     static string exprDescription;
 | 
|---|
| 23 |     if (!exprDescription.length())      // faked static initializer
 | 
|---|
| 24 |     {
 | 
|---|
| 25 |         exprDescription = T_reduction::name();
 | 
|---|
| 26 |         exprDescription += "(";
 | 
|---|
| 27 |         prettyPrintFormat format(_bz_true);   // Terse mode on
 | 
|---|
| 28 |         expr.prettyPrint(exprDescription, format);
 | 
|---|
| 29 |         exprDescription += ")";
 | 
|---|
| 30 |     }
 | 
|---|
| 31 |     TAU_PROFILE(" ", exprDescription, TAU_BLITZ);
 | 
|---|
| 32 | #endif // BZ_TAU_PROFILING
 | 
|---|
| 33 | 
 | 
|---|
| 34 |     return _bz_reduceWithIndexTraversal(expr, reduction);
 | 
|---|
| 35 | 
 | 
|---|
| 36 | #ifdef NOT_IMPLEMENTED
 | 
|---|
| 37 |     if ((T_expr::numIndexPlaceholders > 0) || (T_reduction::needIndex))
 | 
|---|
| 38 |     {
 | 
|---|
| 39 |         // The expression involves index placeholders, so have to
 | 
|---|
| 40 |         // use index traversal rather than stack traversal.
 | 
|---|
| 41 |         return reduceWithIndexTraversal(expr, reduction);
 | 
|---|
| 42 |     }
 | 
|---|
| 43 |     else {
 | 
|---|
| 44 |         // Use a stack traversal
 | 
|---|
| 45 |         return reduceWithStackTraversal(expr, reduction);
 | 
|---|
| 46 |     }
 | 
|---|
| 47 | #endif
 | 
|---|
| 48 | }
 | 
|---|
| 49 | 
 | 
|---|
| 50 | template<class T_expr, class T_reduction>
 | 
|---|
| 51 | _bz_typename T_reduction::T_resulttype
 | 
|---|
| 52 | _bz_reduceWithIndexTraversal(T_expr expr, T_reduction reduction)
 | 
|---|
| 53 | {
 | 
|---|
| 54 |     // This is optimized assuming C-style arrays.
 | 
|---|
| 55 | 
 | 
|---|
| 56 |     reduction.reset();
 | 
|---|
| 57 | 
 | 
|---|
| 58 |     const int rank = T_expr::rank;
 | 
|---|
| 59 | 
 | 
|---|
| 60 |     TinyVector<int,rank> index, first, last;
 | 
|---|
| 61 | 
 | 
|---|
| 62 |     unsigned long count = 1;
 | 
|---|
| 63 | 
 | 
|---|
| 64 |     for (int i=0; i < rank; ++i)
 | 
|---|
| 65 |     {
 | 
|---|
| 66 |         index(i) = expr.lbound(i);
 | 
|---|
| 67 |         first(i) = index(i);
 | 
|---|
| 68 |         last(i) = expr.ubound(i) + 1;
 | 
|---|
| 69 |         count *= last(i) - first(i);
 | 
|---|
| 70 |     }
 | 
|---|
| 71 | 
 | 
|---|
| 72 |     const int maxRank = rank - 1;
 | 
|---|
| 73 |     int lastlbound = expr.lbound(maxRank);
 | 
|---|
| 74 |     int lastubound = expr.ubound(maxRank);
 | 
|---|
| 75 | 
 | 
|---|
| 76 |     int lastIndex = lastubound + 1;
 | 
|---|
| 77 | 
 | 
|---|
| 78 |     _bz_bool loopFlag = _bz_true;
 | 
|---|
| 79 | 
 | 
|---|
| 80 |     while(loopFlag) {
 | 
|---|
| 81 |         for (index[maxRank] = lastlbound; index[maxRank] < lastIndex;
 | 
|---|
| 82 |             ++index[maxRank])
 | 
|---|
| 83 |         {
 | 
|---|
| 84 |             if (!reduction(expr(index), index[maxRank]))
 | 
|---|
| 85 |             {
 | 
|---|
| 86 |                 loopFlag = _bz_false;
 | 
|---|
| 87 |                 break;
 | 
|---|
| 88 |             }
 | 
|---|
| 89 |         }
 | 
|---|
| 90 | 
 | 
|---|
| 91 | #if 0
 | 
|---|
| 92 |         int j = 1;
 | 
|---|
| 93 |         for (; j < rank; ++j)
 | 
|---|
| 94 |         {
 | 
|---|
| 95 |             index(j-1) = first(j-1);
 | 
|---|
| 96 |             ++index(j);
 | 
|---|
| 97 |             if (index(j) != last(j))
 | 
|---|
| 98 |                 break;
 | 
|---|
| 99 |         }
 | 
|---|
| 100 | 
 | 
|---|
| 101 |         if (j == rank)
 | 
|---|
| 102 |             break;
 | 
|---|
| 103 | #endif
 | 
|---|
| 104 | 
 | 
|---|
| 105 |         int j = rank-2;
 | 
|---|
| 106 |         for (; j >= 0; --j)
 | 
|---|
| 107 |         {
 | 
|---|
| 108 |             index(j+1) = first(j+1);
 | 
|---|
| 109 |             ++index(j);
 | 
|---|
| 110 |             if (index(j) != last(j))
 | 
|---|
| 111 |                 break;
 | 
|---|
| 112 |         }
 | 
|---|
| 113 | 
 | 
|---|
| 114 |         if (j < 0)
 | 
|---|
| 115 |             break;
 | 
|---|
| 116 |     }
 | 
|---|
| 117 | 
 | 
|---|
| 118 |     return reduction.result(count);
 | 
|---|
| 119 | }
 | 
|---|
| 120 | 
 | 
|---|
| 121 | BZ_NAMESPACE_END
 | 
|---|
| 122 | 
 | 
|---|