1 //=================================================================================================
2 /*!
3 //  \file blazetest/mathtest/matrices/custommatrix/UnalignedPaddedTest.h
4 //  \brief Header file for the unaligned/padded CustomMatrix class test
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZETEST_MATHTEST_MATRICES_CUSTOMMATRIX_UNALIGNEDPADDEDTEST_H_
36 #define _BLAZETEST_MATHTEST_MATRICES_CUSTOMMATRIX_UNALIGNEDPADDEDTEST_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <sstream>
44 #include <stdexcept>
45 #include <string>
46 #include <blaze/math/constraints/ColumnMajorMatrix.h>
47 #include <blaze/math/constraints/DenseMatrix.h>
48 #include <blaze/math/constraints/RequiresEvaluation.h>
49 #include <blaze/math/constraints/RowMajorMatrix.h>
50 #include <blaze/math/CustomMatrix.h>
51 #include <blaze/math/typetraits/IsRowMajorMatrix.h>
52 #include <blaze/util/constraints/SameType.h>
53 #include <blazetest/system/Types.h>
54 
55 
56 namespace blazetest {
57 
58 namespace mathtest {
59 
60 namespace matrices {
61 
62 namespace custommatrix {
63 
64 //=================================================================================================
65 //
66 //  CLASS DEFINITION
67 //
68 //=================================================================================================
69 
70 //*************************************************************************************************
71 /*!\brief Auxiliary class for all tests of the unaligned/padded CustomMatrix class template.
72 //
73 // This class represents a test suite for the specialization of the blaze::CustomMatrix class
74 // template for unaligned and padded custom matrices. It performs a series of both compile time
75 // as well as runtime tests.
76 */
77 class UnalignedPaddedTest
78 {
79  public:
80    //**Constructors********************************************************************************
81    /*!\name Constructors */
82    //@{
83    explicit UnalignedPaddedTest();
84    // No explicitly declared copy constructor.
85    //@}
86    //**********************************************************************************************
87 
88    //**Destructor**********************************************************************************
89    // No explicitly declared destructor.
90    //**********************************************************************************************
91 
92  private:
93    //**Test functions******************************************************************************
94    /*!\name Test functions */
95    //@{
96    void testConstructors();
97    void testAssignment  ();
98    void testAddAssign   ();
99    void testSubAssign   ();
100    void testSchurAssign ();
101    void testMultAssign  ();
102    void testScaling     ();
103    void testFunctionCall();
104    void testAt          ();
105    void testIterator    ();
106    void testNonZeros    ();
107    void testReset       ();
108    void testClear       ();
109    void testSwap        ();
110    void testTranspose   ();
111    void testCTranspose  ();
112    void testIsDefault   ();
113 
114    template< typename Type >
115    void checkRows( const Type& matrix, size_t expectedRows ) const;
116 
117    template< typename Type >
118    void checkColumns( const Type& matrix, size_t expectedColumns ) const;
119 
120    template< typename Type >
121    void checkCapacity( const Type& matrix, size_t minCapacity ) const;
122 
123    template< typename Type >
124    void checkNonZeros( const Type& matrix, size_t expectedNonZeros ) const;
125 
126    template< typename Type >
127    void checkNonZeros( const Type& matrix, size_t index, size_t expectedNonZeros ) const;
128    //@}
129    //**********************************************************************************************
130 
131    //**Member variables****************************************************************************
132    /*!\name Member variables */
133    //@{
134    std::string test_;  //!< Label of the currently performed test.
135    //@}
136    //**********************************************************************************************
137 
138    //**Type definitions****************************************************************************
139    //! Type of the row-major custom matrix.
140    using MT = blaze::CustomMatrix<int,blaze::unaligned,blaze::padded,blaze::rowMajor>;
141 
142    //! Type of the column-major custom matrix.
143    using OMT = blaze::CustomMatrix<int,blaze::unaligned,blaze::padded,blaze::columnMajor>;
144 
145    using RMT  = MT::Rebind<const double>::Other;   //!< Rebound row-major custom matrix type.
146    using ORMT = OMT::Rebind<const double>::Other;  //!< Rebound column-major custom matrix type.
147    //**********************************************************************************************
148 
149    //**Compile time checks*************************************************************************
150    /*! \cond BLAZE_INTERNAL */
151    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( MT                  );
152    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( MT::ResultType      );
153    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( MT::OppositeType    );
154    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( MT::TransposeType   );
155    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OMT                 );
156    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OMT::ResultType     );
157    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OMT::OppositeType   );
158    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OMT::TransposeType  );
159    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RMT                 );
160    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RMT::ResultType     );
161    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RMT::OppositeType   );
162    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RMT::TransposeType  );
163    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORMT                );
164    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORMT::ResultType    );
165    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORMT::OppositeType  );
166    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORMT::TransposeType );
167 
168    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( MT                  );
169    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( MT::ResultType      );
170    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( MT::OppositeType    );
171    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( MT::TransposeType   );
172    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( OMT                 );
173    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( OMT::ResultType     );
174    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( OMT::OppositeType   );
175    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( OMT::TransposeType  );
176    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( RMT                 );
177    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( RMT::ResultType     );
178    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( RMT::OppositeType   );
179    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( RMT::TransposeType  );
180    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( ORMT                );
181    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( ORMT::ResultType    );
182    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( ORMT::OppositeType  );
183    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( ORMT::TransposeType );
184 
185    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( MT::ResultType      );
186    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( MT::OppositeType    );
187    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( MT::TransposeType   );
188    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( OMT::ResultType     );
189    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( OMT::OppositeType   );
190    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( OMT::TransposeType  );
191    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RMT::ResultType     );
192    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RMT::OppositeType   );
193    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RMT::TransposeType  );
194    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ORMT::ResultType    );
195    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ORMT::OppositeType  );
196    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ORMT::TransposeType );
197 
198    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MT::ElementType,   MT::ResultType::ElementType      );
199    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MT::ElementType,   MT::OppositeType::ElementType    );
200    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MT::ElementType,   MT::TransposeType::ElementType   );
201    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( OMT::ElementType,  OMT::ResultType::ElementType     );
202    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( OMT::ElementType,  OMT::OppositeType::ElementType   );
203    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( OMT::ElementType,  OMT::TransposeType::ElementType  );
204    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( RMT::ElementType,  RMT::ResultType::ElementType     );
205    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( RMT::ElementType,  RMT::OppositeType::ElementType   );
206    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( RMT::ElementType,  RMT::TransposeType::ElementType  );
207    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ORMT::ElementType, ORMT::ResultType::ElementType    );
208    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ORMT::ElementType, ORMT::OppositeType::ElementType  );
209    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ORMT::ElementType, ORMT::TransposeType::ElementType );
210    /*! \endcond */
211    //**********************************************************************************************
212 };
213 //*************************************************************************************************
214 
215 
216 
217 
218 //=================================================================================================
219 //
220 //  TEST FUNCTIONS
221 //
222 //=================================================================================================
223 
224 //*************************************************************************************************
225 /*!\brief Checking the number of rows of the given custom matrix.
226 //
227 // \param matrix The custom matrix to be checked.
228 // \param expectedRows The expected number of rows of the custom matrix.
229 // \return void
230 // \exception std::runtime_error Error detected.
231 //
232 // This function checks the number of rows of the given custom matrix. In case the actual number
233 // of rows does not correspond to the given expected number of rows, a \a std::runtime_error
234 // exception is thrown.
235 */
236 template< typename Type >  // Type of the custom matrix
checkRows(const Type & matrix,size_t expectedRows)237 void UnalignedPaddedTest::checkRows( const Type& matrix, size_t expectedRows ) const
238 {
239    if( rows( matrix ) != expectedRows ) {
240       std::ostringstream oss;
241       oss << " Test: " << test_ << "\n"
242           << " Error: Invalid number of rows detected\n"
243           << " Details:\n"
244           << "   Number of rows         : " << rows( matrix ) << "\n"
245           << "   Expected number of rows: " << expectedRows << "\n";
246       throw std::runtime_error( oss.str() );
247    }
248 }
249 //*************************************************************************************************
250 
251 
252 //*************************************************************************************************
253 /*!\brief Checking the number of columns of the given custom matrix.
254 //
255 // \param matrix The custom matrix to be checked.
256 // \param expectedRows The expected number of columns of the custom matrix.
257 // \return void
258 // \exception std::runtime_error Error detected.
259 //
260 // This function checks the number of columns of the given custom matrix. In case the
261 // actual number of columns does not correspond to the given expected number of columns,
262 // a \a std::runtime_error exception is thrown.
263 */
264 template< typename Type >  // Type of the custom matrix
checkColumns(const Type & matrix,size_t expectedColumns)265 void UnalignedPaddedTest::checkColumns( const Type& matrix, size_t expectedColumns ) const
266 {
267    if( columns( matrix ) != expectedColumns ) {
268       std::ostringstream oss;
269       oss << " Test: " << test_ << "\n"
270           << " Error: Invalid number of columns detected\n"
271           << " Details:\n"
272           << "   Number of columns         : " << columns( matrix ) << "\n"
273           << "   Expected number of columns: " << expectedColumns << "\n";
274       throw std::runtime_error( oss.str() );
275    }
276 }
277 //*************************************************************************************************
278 
279 
280 //*************************************************************************************************
281 /*!\brief Checking the capacity of the given custom matrix.
282 //
283 // \param matrix The custom matrix to be checked.
284 // \param minCapacity The expected minimum capacity of the custom matrix.
285 // \return void
286 // \exception std::runtime_error Error detected.
287 //
288 // This function checks the capacity of the given custom matrix. In case the actual capacity
289 // is smaller than the given expected minimum capacity, a \a std::runtime_error exception is
290 // thrown.
291 */
292 template< typename Type >  // Type of the custom matrix
checkCapacity(const Type & matrix,size_t minCapacity)293 void UnalignedPaddedTest::checkCapacity( const Type& matrix, size_t minCapacity ) const
294 {
295    if( capacity( matrix ) < minCapacity ) {
296       std::ostringstream oss;
297       oss << " Test: " << test_ << "\n"
298           << " Error: Invalid capacity detected\n"
299           << " Details:\n"
300           << "   Capacity                 : " << capacity( matrix ) << "\n"
301           << "   Expected minimum capacity: " << minCapacity << "\n";
302       throw std::runtime_error( oss.str() );
303    }
304 }
305 //*************************************************************************************************
306 
307 
308 //*************************************************************************************************
309 /*!\brief Checking the number of non-zero elements of the given custom matrix.
310 //
311 // \param matrix The custom matrix to be checked.
312 // \param expectedNonZeros The expected number of non-zero elements of the custom matrix.
313 // \return void
314 // \exception std::runtime_error Error detected.
315 //
316 // This function checks the number of non-zero elements of the given custom matrix. In
317 // case the actual number of non-zero elements does not correspond to the given expected
318 // number, a \a std::runtime_error exception is thrown.
319 */
320 template< typename Type >  // Type of the custom matrix
checkNonZeros(const Type & matrix,size_t expectedNonZeros)321 void UnalignedPaddedTest::checkNonZeros( const Type& matrix, size_t expectedNonZeros ) const
322 {
323    if( nonZeros( matrix ) != expectedNonZeros ) {
324       std::ostringstream oss;
325       oss << " Test: " << test_ << "\n"
326           << " Error: Invalid number of non-zero elements\n"
327           << " Details:\n"
328           << "   Number of non-zeros         : " << nonZeros( matrix ) << "\n"
329           << "   Expected number of non-zeros: " << expectedNonZeros << "\n";
330       throw std::runtime_error( oss.str() );
331    }
332 
333    if( capacity( matrix ) < nonZeros( matrix ) ) {
334       std::ostringstream oss;
335       oss << " Test: " << test_ << "\n"
336           << " Error: Invalid capacity detected\n"
337           << " Details:\n"
338           << "   Number of non-zeros: " << nonZeros( matrix ) << "\n"
339           << "   Capacity           : " << capacity( matrix ) << "\n";
340       throw std::runtime_error( oss.str() );
341    }
342 }
343 //*************************************************************************************************
344 
345 
346 //*************************************************************************************************
347 /*!\brief Checking the number of non-zero elements in a specific row/column of the given custom matrix.
348 //
349 // \param matrix The custom matrix to be checked.
350 // \param index The row/column to be checked.
351 // \param expectedNonZeros The expected number of non-zero elements in the specified row/column.
352 // \return void
353 // \exception std::runtime_error Error detected.
354 //
355 // This function checks the number of non-zero elements in the specified row/column of the
356 // given custom matrix. In case the actual number of non-zero elements does not correspond
357 // to the given expected number, a \a std::runtime_error exception is thrown.
358 */
359 template< typename Type >  // Type of the custom matrix
checkNonZeros(const Type & matrix,size_t index,size_t expectedNonZeros)360 void UnalignedPaddedTest::checkNonZeros( const Type& matrix, size_t index, size_t expectedNonZeros ) const
361 {
362    if( nonZeros( matrix, index ) != expectedNonZeros ) {
363       std::ostringstream oss;
364       oss << " Test: " << test_ << "\n"
365           << " Error: Invalid number of non-zero elements in "
366           << ( blaze::IsRowMajorMatrix<Type>::value ? "row " : "column " ) << index << "\n"
367           << " Details:\n"
368           << "   Number of non-zeros         : " << nonZeros( matrix, index ) << "\n"
369           << "   Expected number of non-zeros: " << expectedNonZeros << "\n";
370       throw std::runtime_error( oss.str() );
371    }
372 
373    if( capacity( matrix, index ) < nonZeros( matrix, index ) ) {
374       std::ostringstream oss;
375       oss << " Test: " << test_ << "\n"
376           << " Error: Invalid capacity detected in "
377           << ( blaze::IsRowMajorMatrix<Type>::value ? "row " : "column " ) << index << "\n"
378           << " Details:\n"
379           << "   Number of non-zeros: " << nonZeros( matrix, index ) << "\n"
380           << "   Capacity           : " << capacity( matrix, index ) << "\n";
381       throw std::runtime_error( oss.str() );
382    }
383 }
384 //*************************************************************************************************
385 
386 
387 
388 
389 //=================================================================================================
390 //
391 //  GLOBAL TEST FUNCTIONS
392 //
393 //=================================================================================================
394 
395 //*************************************************************************************************
396 /*!\brief Testing the functionality of the unaligned/padded CustomMatrix class template.
397 //
398 // \return void
399 */
runTest()400 void runTest()
401 {
402    UnalignedPaddedTest();
403 }
404 //*************************************************************************************************
405 
406 
407 
408 
409 //=================================================================================================
410 //
411 //  MACRO DEFINITIONS
412 //
413 //=================================================================================================
414 
415 //*************************************************************************************************
416 /*! \cond BLAZE_INTERNAL */
417 /*!\brief Macro for the execution of the unaligned/padded CustomMatrix class test.
418 */
419 #define RUN_CUSTOMMATRIX_UNALIGNED_PADDED_TEST \
420    blazetest::mathtest::matrices::custommatrix::runTest()
421 /*! \endcond */
422 //*************************************************************************************************
423 
424 } // namespace custommatrix
425 
426 } // namespace matrices
427 
428 } // namespace mathtest
429 
430 } // namespace blazetest
431 
432 #endif
433