Blaze 3.9
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>
48#include <blaze/math/SIMD.h>
53#include <blaze/util/EnableIf.h>
54#include <blaze/util/Types.h>
56
57
58namespace blaze {
59
60//=================================================================================================
61//
62// CLASS DEFINITION
63//
64//=================================================================================================
65
66//*************************************************************************************************
71template< typename MT1 // Type of the left-hand side dense matrix
72 , typename MT2 > // Type of the right-hand side dense matrix
73struct 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//*************************************************************************************************
116template< RelaxationFlag 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
119inline 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<RF>( A(i,j), B(i,j) ) ) return false;
138 }
139 }
140
141 return true;
142}
144//*************************************************************************************************
145
146
147//*************************************************************************************************
160template< RelaxationFlag 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
163inline 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( !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 ? prevMultiple( N, SIMDSIZE ) : N );
186 BLAZE_INTERNAL_ASSERT( jpos <= N, "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<RF>( A.load(i,j ), B.load(i,j ) ) ) return false;
194 if( !equal<RF>( A.load(i,j+SIMDSIZE ), B.load(i,j+SIMDSIZE ) ) ) return false;
195 if( !equal<RF>( A.load(i,j+SIMDSIZE*2UL), B.load(i,j+SIMDSIZE*2UL) ) ) return false;
196 if( !equal<RF>( 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<RF>( A.load(i,j ), B.load(i,j ) ) ) return false;
200 if( !equal<RF>( A.load(i,j+SIMDSIZE), B.load(i,j+SIMDSIZE) ) ) return false;
201 }
202 for( ; j<jpos; j+=SIMDSIZE ) {
203 if( !equal<RF>( A.load(i,j), B.load(i,j) ) ) return false;
204 }
205 for( ; remainder && j<A.columns(); ++j ) {
206 if( !equal<RF>( A(i,j), B(i,j) ) ) return false;
207 }
208 }
209
210 return true;
211}
213//*************************************************************************************************
214
215
216//*************************************************************************************************
229template< RelaxationFlag 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
232inline 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<RF>( A(i,j), B(i,j) ) ) return false;
251 }
252 }
253
254 return true;
255}
257//*************************************************************************************************
258
259
260//*************************************************************************************************
273template< RelaxationFlag 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
276inline 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( !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 ? prevMultiple( M, SIMDSIZE ) : M );
299 BLAZE_INTERNAL_ASSERT( ipos <= M, "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<RF>( A.load(i ,j), B.load(i ,j) ) ) return false;
307 if( !equal<RF>( A.load(i+SIMDSIZE ,j), B.load(i+SIMDSIZE ,j) ) ) return false;
308 if( !equal<RF>( A.load(i+SIMDSIZE*2UL,j), B.load(i+SIMDSIZE*2UL,j) ) ) return false;
309 if( !equal<RF>( 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<RF>( A.load(i ,j), B.load(i ,j) ) ) return false;
313 if( !equal<RF>( A.load(i+SIMDSIZE,j), B.load(i+SIMDSIZE,j) ) ) return false;
314 }
315 for( ; i<ipos; i+=SIMDSIZE ) {
316 if( !equal<RF>( A.load(i,j), B.load(i,j) ) ) return false;
317 }
318 for( ; remainder && i<M; ++i ) {
319 if( !equal<RF>( A(i,j), B(i,j) ) ) return false;
320 }
321 }
322
323 return true;
324}
326//*************************************************************************************************
327
328
329//*************************************************************************************************
342template< RelaxationFlag 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
346inline 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<RF>( A(i,j), B(i,j) ) ) return false;
372 }
373 }
374 }
375 }
376
377 return true;
378}
380//*************************************************************************************************
381
382
383//*************************************************************************************************
391template< 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
395inline bool operator==( const DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
396{
397 return equal<relaxed>( lhs, rhs );
398}
399//*************************************************************************************************
400
401
402//*************************************************************************************************
410template< 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
414inline 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 the EnableIf class template.
Header file for the HasSIMDEqual type trait.
Header file for the IsPadded type trait.
Header file for the prevMultiple shim.
Header file for the relaxation flag enumeration.
Header file for the RemoveReference type trait.
Header file for all SIMD functionality.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Header file for the DenseMatrix base class.
bool operator!=(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Inequality operator for the comparison of two dense matrices.
Definition: DMatDMatEqualExpr.h:414
bool operator==(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Equality operator for the comparison of two dense matrices.
Definition: DMatDMatEqualExpr.h:395
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:343
Header file for the equal shim.
System settings for performance optimizations.
Header file for basic type definitions.