1 /*
  2  *   Copyright (c) 2007, Michael Lehn
  3  *
  4  *   All rights reserved.
  5  *
  6  *   Redistribution and use in source and binary forms, with or without
  7  *   modification, are permitted provided that the following conditions
  8  *   are met:
  9  *
 10  *   1) Redistributions of source code must retain the above copyright
 11  *      notice, this list of conditions and the following disclaimer.
 12  *   2) Redistributions in binary form must reproduce the above copyright
 13  *      notice, this list of conditions and the following disclaimer in
 14  *      the documentation and/or other materials provided with the
 15  *      distribution.
 16  *   3) Neither the name of the FLENS development group nor the names of
 17  *      its contributors may be used to endorse or promote products derived
 18  *      from this software without specific prior written permission.
 19  *
 20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31  */
 32 
 33 #ifndef FLENS_BLAS_CLOSURES_DEBUGCLOSURE_TCC
 34 #define FLENS_BLAS_CLOSURES_DEBUGCLOSURE_TCC 1
 35 
 36 #include <flens/aux/aux.h>
 37 #include <flens/vectortypes/vectortypes.h>
 38 
 39 //
 40 //  Default implementation and specializations of DEBUGCLOSURE::identical
 41 //
 42 
 43 namespace flens { namespace DEBUGCLOSURE {
 44 
 45 template <typename X, typename Y>
 46 typename RestrictTo<!HasFullStorage<X>::value || !HasFullStorage<Y>::value,
 47          bool>::Type
 48 identical(const X &x, const Y &y)
 49 {
 50     std::cerr << "V1" << std::endl;
 51     return ADDRESS(x)==ADDRESS(y);
 52 }
 53 
 54 //
 55 // Two DenseVectors are identical if they reference the same memory
 56 //
 57 template <typename VX, typename VY>
 58 bool
 59 identical(const DenseVector<VX> &x, const DenseVector<VY> &y)
 60 {
 61 //
 62 //  Quick return if possible
 63 //
 64     if (ADDRESS(x)==ADDRESS(y)) {
 65         return true;
 66     }
 67 
 68     typedef typename DenseVector<VX>::ElementType  TX;
 69     typedef typename DenseVector<VY>::ElementType  TY;
 70 
 71     if (! IsSame<TX, TY>::value) {
 72         return false;
 73     }
 74 //
 75 //  Compare referenced memory
 76 //
 77     if (RAWPOINTER(x.data())!=RAWPOINTER(y.data())) {
 78         return false;
 79     }
 80     if (x.stride()!=y.stride()) {
 81         return false;
 82     }
 83     if (x.length()!=y.length()) {
 84         return false;
 85     }
 86     return true;
 87 }
 88 
 89 //
 90 // Two matrices with full storage are identical if they reference the
 91 // same memory region
 92 //
 93 template <typename MA, typename MB>
 94 typename RestrictTo<HasFullStorage<MA>::value && HasFullStorage<MB>::value,
 95          bool>::Type
 96 identical(const MA &A, const MB &B)
 97 {
 98     std::cerr << "V2" << std::endl;
 99 //
100 //  Quick return if possible
101 //
102     if (ADDRESS(A)==ADDRESS(B)) {
103         return true;
104     }
105 
106     typedef typename MA::ElementType  TA;
107     typedef typename MB::ElementType  TB;
108 
109     if (! IsSame<TA, TB>::value) {
110         return false;
111     }
112 
113     if (MA::Engine::order!=MB::Engine::order) {
114         return false;
115     }
116 //
117 //  Compare referenced memory
118 //
119     if (RAWPOINTER(A.data())!=RAWPOINTER(B.data())) {
120         return false;
121     }
122     if (A.leadingDimension()!=B.leadingDimension()) {
123         return false;
124     }
125     if (A.numRows()!=B.numRows()) {
126         return false;
127     }
128     if (A.numCols()!=B.numCols()) {
129         return false;
130     }
131     return true;
132 }
133 
134 }} // namespace DEBUGCLOSURE, flens
135 
136 //
137 //  Search mechanism for closures
138 //
139 
140 namespace flens {
141 
142 template <typename X, typename Y>
143 bool
144 DebugClosure::search(const X &x, const Y &y)
145 {
146     return DEBUGCLOSURE::identical(x, y);
147 }
148 
149 template <typename Op, typename L, typename R, typename Y>
150 bool
151 DebugClosure::search(const VectorClosure<Op, L, R> &closure, const Y &y)
152 {
153     return search(closure.left(), y) || search(closure.right(), y);
154 }
155 
156 template <typename Op, typename L, typename R, typename Y>
157 bool
158 DebugClosure::search(const MatrixClosure<Op, L, R> &closure, const Y &y)
159 {
160     return search(closure.left(), y) || search(closure.right(), y);
161 }
162 
163 // namespace flens
164 
165 #endif // FLENS_BLAS_CLOSURES_DEBUGCLOSURE_TCC