DMatDMatEqualExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATDMATEQUALEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATDMATEQUALEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
46 #include <blaze/math/shims/Equal.h>
47 #include <blaze/math/SIMD.h>
50 #include <blaze/system/Blocking.h>
52 #include <blaze/util/DisableIf.h>
53 #include <blaze/util/EnableIf.h>
54 #include <blaze/util/Types.h>
56 
57 
58 namespace blaze {
59 
60 //=================================================================================================
61 //
62 // CLASS DEFINITION
63 //
64 //=================================================================================================
65 
66 //*************************************************************************************************
71 template< typename MT1 // Type of the left-hand side dense matrix
72  , typename MT2 > // Type of the right-hand side dense matrix
73 struct DMatDMatEqualExprHelper
74 {
75  //**Type definitions****************************************************************************
77  using CT1 = RemoveReference_t< CompositeType_t<MT1> >;
78 
80  using CT2 = RemoveReference_t< CompositeType_t<MT2> >;
81  //**********************************************************************************************
82 
83  //**********************************************************************************************
84  static constexpr bool value =
85  ( useOptimizedKernels &&
86  CT1::simdEnabled &&
87  CT2::simdEnabled &&
88  HasSIMDEqual_v< ElementType_t<CT1>, ElementType_t<CT2> > );
89  //**********************************************************************************************
90 };
92 //*************************************************************************************************
93 
94 
95 
96 
97 //=================================================================================================
98 //
99 // GLOBAL BINARY RELATIONAL OPERATORS
100 //
101 //=================================================================================================
102 
103 //*************************************************************************************************
116 template< bool RF // Relaxation flag
117  , typename MT1 // Type of the left-hand side dense matrix
118  , typename MT2 > // Type of the right-hand side dense matrix
119 inline auto equal( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,false>& rhs )
120  -> DisableIf_t< DMatDMatEqualExprHelper<MT1,MT2>::value, bool >
121 {
122  using CT1 = CompositeType_t<MT1>;
123  using CT2 = CompositeType_t<MT2>;
124 
125  // Early exit in case the matrix sizes don't match
126  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
127  return false;
128 
129  // Evaluation of the two dense matrix operands
130  CT1 A( ~lhs );
131  CT2 B( ~rhs );
132 
133  // In order to compare the two matrices, the data values of the lower-order data
134  // type are converted to the higher-order data type within the equal function.
135  for( size_t i=0UL; i<A.rows(); ++i ) {
136  for( size_t j=0UL; j<A.columns(); ++j ) {
137  if( !equal( A(i,j), B(i,j) ) ) return false;
138  }
139  }
140 
141  return true;
142 }
144 //*************************************************************************************************
145 
146 
147 //*************************************************************************************************
160 template< bool RF // Relaxation flag
161  , typename MT1 // Type of the left-hand side dense matrix
162  , typename MT2 > // Type of the right-hand side dense matrix
163 inline auto equal( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,false>& rhs )
164  -> EnableIf_t< DMatDMatEqualExprHelper<MT1,MT2>::value, bool >
165 {
166  using CT1 = CompositeType_t<MT1>;
167  using CT2 = CompositeType_t<MT2>;
168  using XT1 = RemoveReference_t<CT1>;
169  using XT2 = RemoveReference_t<CT2>;
170 
171  // Early exit in case the matrix sizes don't match
172  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
173  return false;
174 
175  // Evaluation of the two dense matrix operands
176  CT1 A( ~lhs );
177  CT2 B( ~rhs );
178 
179  constexpr size_t SIMDSIZE = SIMDTrait< ElementType_t<MT1> >::size;
180  constexpr bool remainder( !usePadding || !IsPadded_v<XT1> || !IsPadded_v<XT2> );
181 
182  const size_t M( A.rows() );
183  const size_t N( A.columns() );
184 
185  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
186  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
187 
188  for( size_t i=0UL; i<M; ++i )
189  {
190  size_t j( 0UL );
191 
192  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
193  if( !equal( A.load(i,j ), B.load(i,j ) ) ) return false;
194  if( !equal( A.load(i,j+SIMDSIZE ), B.load(i,j+SIMDSIZE ) ) ) return false;
195  if( !equal( A.load(i,j+SIMDSIZE*2UL), B.load(i,j+SIMDSIZE*2UL) ) ) return false;
196  if( !equal( A.load(i,j+SIMDSIZE*3UL), B.load(i,j+SIMDSIZE*3UL) ) ) return false;
197  }
198  for( ; (j+SIMDSIZE) < jpos; j+=SIMDSIZE*2UL ) {
199  if( !equal( A.load(i,j ), B.load(i,j ) ) ) return false;
200  if( !equal( A.load(i,j+SIMDSIZE), B.load(i,j+SIMDSIZE) ) ) return false;
201  }
202  for( ; j<jpos; j+=SIMDSIZE ) {
203  if( !equal( A.load(i,j), B.load(i,j) ) ) return false;
204  }
205  for( ; remainder && j<A.columns(); ++j ) {
206  if( !equal( A(i,j), B(i,j) ) ) return false;
207  }
208  }
209 
210  return true;
211 }
213 //*************************************************************************************************
214 
215 
216 //*************************************************************************************************
229 template< bool RF // Relaxation flag
230  , typename MT1 // Type of the left-hand side dense matrix
231  , typename MT2 > // Type of the right-hand side dense matrix
232 inline auto equal( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,true>& rhs )
233  -> DisableIf_t< DMatDMatEqualExprHelper<MT1,MT2>::value, bool >
234 {
235  using CT1 = CompositeType_t<MT1>;
236  using CT2 = CompositeType_t<MT2>;
237 
238  // Early exit in case the matrix sizes don't match
239  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
240  return false;
241 
242  // Evaluation of the two dense matrix operands
243  CT1 A( ~lhs );
244  CT2 B( ~rhs );
245 
246  // In order to compare the two matrices, the data values of the lower-order data
247  // type are converted to the higher-order data type within the equal function.
248  for( size_t j=0UL; j<A.columns(); ++j ) {
249  for( size_t i=0UL; i<A.rows(); ++i ) {
250  if( !equal( A(i,j), B(i,j) ) ) return false;
251  }
252  }
253 
254  return true;
255 }
257 //*************************************************************************************************
258 
259 
260 //*************************************************************************************************
273 template< bool RF // Relaxation flag
274  , typename MT1 // Type of the left-hand side dense matrix
275  , typename MT2 > // Type of the right-hand side dense matrix
276 inline auto equal( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,true>& rhs )
277  -> EnableIf_t< DMatDMatEqualExprHelper<MT1,MT2>::value, bool >
278 {
279  using CT1 = CompositeType_t<MT1>;
280  using CT2 = CompositeType_t<MT2>;
281  using XT1 = RemoveReference_t<CT1>;
282  using XT2 = RemoveReference_t<CT2>;
283 
284  // Early exit in case the matrix sizes don't match
285  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
286  return false;
287 
288  // Evaluation of the two dense matrix operands
289  CT1 A( ~lhs );
290  CT2 B( ~rhs );
291 
292  constexpr size_t SIMDSIZE = SIMDTrait< ElementType_t<MT1> >::size;
293  constexpr bool remainder( !usePadding || !IsPadded_v<XT1> || !IsPadded_v<XT2> );
294 
295  const size_t M( A.rows() );
296  const size_t N( A.columns() );
297 
298  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
299  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
300 
301  for( size_t j=0UL; j<N; ++j )
302  {
303  size_t i( 0UL );
304 
305  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
306  if( !equal( A.load(i ,j), B.load(i ,j) ) ) return false;
307  if( !equal( A.load(i+SIMDSIZE ,j), B.load(i+SIMDSIZE ,j) ) ) return false;
308  if( !equal( A.load(i+SIMDSIZE*2UL,j), B.load(i+SIMDSIZE*2UL,j) ) ) return false;
309  if( !equal( A.load(i+SIMDSIZE*3UL,j), B.load(i+SIMDSIZE*3UL,j) ) ) return false;
310  }
311  for( ; (i+SIMDSIZE) < ipos; i+=SIMDSIZE*2UL ) {
312  if( !equal( A.load(i ,j), B.load(i ,j) ) ) return false;
313  if( !equal( A.load(i+SIMDSIZE,j), B.load(i+SIMDSIZE,j) ) ) return false;
314  }
315  for( ; i<ipos; i+=SIMDSIZE ) {
316  if( !equal( A.load(i,j), B.load(i,j) ) ) return false;
317  }
318  for( ; remainder && i<M; ++i ) {
319  if( !equal( A(i,j), B(i,j) ) ) return false;
320  }
321  }
322 
323  return true;
324 }
326 //*************************************************************************************************
327 
328 
329 //*************************************************************************************************
342 template< bool RF // Relaxation flag
343  , typename MT1 // Type of the left-hand side dense matrix
344  , typename MT2 // Type of the right-hand side dense matrix
345  , bool SO > // Storage order
346 inline bool equal( const DenseMatrix<MT1,SO>& lhs, const DenseMatrix<MT2,!SO>& rhs )
347 {
348  using CT1 = CompositeType_t<MT1>;
349  using CT2 = CompositeType_t<MT2>;
350 
351  // Early exit in case the matrix sizes don't match
352  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
353  return false;
354 
355  // Evaluation of the two dense matrix operands
356  CT1 A( ~lhs );
357  CT2 B( ~rhs );
358 
359  // In order to compare the two matrices, the data values of the lower-order data
360  // type are converted to the higher-order data type within the equal function.
361  const size_t rows ( A.rows() );
362  const size_t columns( A.columns() );
363  const size_t block ( BLOCK_SIZE );
364 
365  for( size_t ii=0UL; ii<rows; ii+=block ) {
366  const size_t iend( ( rows < ii+block )?( rows ):( ii+block ) );
367  for( size_t jj=0UL; jj<columns; jj+=block ) {
368  const size_t jend( ( columns < jj+block )?( columns ):( jj+block ) );
369  for( size_t i=ii; i<iend; ++i ) {
370  for( size_t j=jj; j<jend; ++j ) {
371  if( !equal( A(i,j), B(i,j) ) ) return false;
372  }
373  }
374  }
375  }
376 
377  return true;
378 }
380 //*************************************************************************************************
381 
382 
383 //*************************************************************************************************
391 template< typename MT1 // Type of the left-hand side dense matrix
392  , bool SO1 // Storage order of the left-hand side dense matrix
393  , typename MT2 // Type of the right-hand side dense matrix
394  , bool SO2 > // Storage order of the right-hand side dense matrix
395 inline bool operator==( const DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
396 {
397  return equal<relaxed>( lhs, rhs );
398 }
399 //*************************************************************************************************
400 
401 
402 //*************************************************************************************************
410 template< typename MT1 // Type of the left-hand side dense matrix
411  , bool SO1 // Storage order of the left-hand side dense matrix
412  , typename MT2 // Type of the right-hand side dense matrix
413  , bool SO2 > // Storage order of the right-hand side dense matrix
414 inline bool operator!=( const DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
415 {
416  return !equal<relaxed>( lhs, rhs );
417 }
418 //*************************************************************************************************
419 
420 } // namespace blaze
421 
422 #endif
Header file for auxiliary alias declarations.
Header file for kernel specific block sizes.
Header file for basic type definitions.
System settings for performance optimizations.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the DenseMatrix base class.
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:253
Header file for all SIMD functionality.
Header file for the equal shim.
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Header file for the EnableIf class template.
Header file for the IsPadded type trait.
Header file for the relaxation flag types.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
Header file for the RemoveReference type trait.
Header file for the HasSIMDEqual type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:342