1 //=================================================================================================
2 /*!
3 //  \file blazemark/util/DynamicSparseRun.h
4 //  \brief Header file for the DynamicSparseRun class
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 _BLAZEMARK_UTIL_DYNAMICSPARSERUN_H_
36 #define _BLAZEMARK_UTIL_DYNAMICSPARSERUN_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iomanip>
44 #include <istream>
45 #include <ostream>
46 #include <stdexcept>
47 #include <blaze/math/Infinity.h>
48 #include <blaze/math/shims/Equal.h>
49 #include <blaze/util/algorithms/Min.h>
50 #include <blaze/util/UnsignedValue.h>
51 #include <blazemark/system/Types.h>
52 
53 
54 namespace blazemark {
55 
56 //=================================================================================================
57 //
58 //  CLASS DEFINITION
59 //
60 //=================================================================================================
61 
62 //*************************************************************************************************
63 /*!\brief Data structure for the parameters of a benchmark run with sparse vectors and/or matrices.
64 //
65 // This auxiliary data structure represents the necessary parameters for a benchmark run with
66 // sparse vectors and/or matrices.
67 */
68 class DynamicSparseRun
69 {
70  private:
71    //**Constructors********************************************************************************
72    /*!\name Constructors */
73    //@{
74    explicit inline DynamicSparseRun();
75    //@}
76    //**********************************************************************************************
77 
78  public:
79    //**Constructors********************************************************************************
80    /*!\name Constructors */
81    //@{
82    explicit inline DynamicSparseRun( size_t size, size_t nonzeros );
83    explicit inline DynamicSparseRun( size_t size, size_t nonzeros, size_t steps );
84    // No explicitly declared copy constructor.
85    //@}
86    //**********************************************************************************************
87 
88    //**Destructor**********************************************************************************
89    // No explicitly declared destructor.
90    //**********************************************************************************************
91 
92    //**Copy assignment operator********************************************************************
93    // No explicitly declared copy assignment operator.
94    //**********************************************************************************************
95 
96    //**Utility functions***************************************************************************
97    /*!\name Utility functions */
98    //@{
99    inline size_t getSize           () const;
100    inline size_t getNonZeros       () const;
101    inline float  getFillingDegree  () const;
102    inline size_t getSteps          () const;
103    inline size_t getFlops          () const;
104    inline double getClikeResult    () const;
105    inline double getClassicResult  () const;
106    inline double getBlazeResult    () const;
107    inline double getBoostResult    () const;
108    inline double getBlitzResult    () const;
109    inline double getGMMResult      () const;
110    inline double getArmadilloResult() const;
111    inline double getFLENSResult    () const;
112    inline double getMTLResult      () const;
113    inline double getEigenResult    () const;
114 
115    inline void   setSize    ( size_t newSize     );
116    inline void   setNonZeros( size_t newNonZeros );
117    inline void   setSteps   ( size_t newSteps    );
118    inline void   setFlops   ( size_t newFlops    );
119    inline void   setClikeResult    ( double result );
120    inline void   setClassicResult  ( double result );
121    inline void   setBlazeResult    ( double result );
122    inline void   setBoostResult    ( double result );
123    inline void   setBlitzResult    ( double result );
124    inline void   setGMMResult      ( double result );
125    inline void   setArmadilloResult( double result );
126    inline void   setFLENSResult    ( double result );
127    inline void   setMTLResult      ( double result );
128    inline void   setEigenResult    ( double result );
129    //@}
130    //**********************************************************************************************
131 
132  private:
133    //**Member variables****************************************************************************
134    /*!\name Member variables */
135    //@{
136    size_t size_;       //!< The target size of the sparse vectors/matrices.
137                        /*!< In case of a sparse vector, this value directly corresponds to the size
138                             of the vector, in case of a sparse matrix \a size_ corresponds to the
139                             number of rows and columns. */
140    size_t nonzeros_;   //!< The number of non-zero elements in the sparse vectors/matrices.
141                        /*!< In case of a sparse vector, this value directly corresponds to the
142                             number of sparse elements. In case of a sparse matrix, the value
143                             specifies the number of non-zero elements per row. */
144    size_t steps_;      //!< The number of steps for the benchmark run.
145                        /*!< The (composite) arithmetic operation of each benchmark is run several
146                             times to guarantee reasonable runtimes. \a steps_ corresponds to the
147                             number of performed iterations. */
148    size_t flops_;      //!< The number of flops required for the benchmark run.
149                        /*!< This value corresponds to the total number of floating point operations
150                             (Flops) required for a single computation of the (composite) arithmetic
151                             operation. */
152    double clike_;      //!< Benchmark result of the C-like implementation.
153    double classic_;    //!< Benchmark result of classic C++ operator overloading.
154    double blaze_;      //!< Benchmark result of the Blaze library.
155    double boost_;      //!< Benchmark result of the Boost uBLAS library.
156    double blitz_;      //!< Benchmark result of the Blitz++ library.
157    double gmm_;        //!< Benchmark result of the GMM++ library.
158    double armadillo_;  //!< Benchmark result of the Armadillo library.
159    double flens_;      //!< Benchmark result of the FLENS library.
160    double mtl_;        //!< Benchmark result of the MTL4 library.
161    double eigen_;      //!< Benchmark result of the Eigen3 library.
162    //@}
163    //**********************************************************************************************
164 
165    //**Friend declarations*************************************************************************
166    /*! \cond BLAZE_INTERNAL */
167    template< typename > friend class Parser;
168    /*! \endcond */
169    //**********************************************************************************************
170 };
171 //*************************************************************************************************
172 
173 
174 
175 
176 //=================================================================================================
177 //
178 //  CONSTRUCTORS
179 //
180 //=================================================================================================
181 
182 //*************************************************************************************************
183 /*!\brief Default constructor for the DynamicSparseRun class.
184 //
185 // The default constructor in exclusively accessible for the blazemark::Parser class.
186 */
DynamicSparseRun()187 inline DynamicSparseRun::DynamicSparseRun()
188    : size_     ( 0UL )  // The target size of the sparse vectors/matrices
189    , nonzeros_ ( 0UL )  // The number of non-zero elements in the sparse vectors/matrices.
190    , steps_    ( 0UL )  // The number of steps for the benchmark run
191    , flops_    ( 0UL )  // The number of flops required for the benchmark run
192    , clike_    ( 0.0 )  // Benchmark result of the C-like implementation
193    , classic_  ( 0.0 )  // Benchmark result of the classic C++ implementation
194    , blaze_    ( 0.0 )  // Benchmark result of the Blaze library
195    , boost_    ( 0.0 )  // Benchmark result of the Boost uBLAS library
196    , blitz_    ( 0.0 )  // Benchmark result of the Blitz++ library
197    , gmm_      ( 0.0 )  // Benchmark result of the GMM++ library
198    , armadillo_( 0.0 )  // Benchmark result of the Armadillo library
199    , flens_    ( 0.0 )  // Benchmark result of the FLENS library
200    , mtl_      ( 0.0 )  // Benchmark result of the MTL4 library
201    , eigen_    ( 0.0 )  // Benchmark result of the Eigen3 library
202 {}
203 //*************************************************************************************************
204 
205 
206 //*************************************************************************************************
207 /*!\brief Two-argument constructor for the DynamicSparseRun class.
208 //
209 // \param size The size of the sparse vector or matrix \f$ [1..\infty) \f$.
210 // \param nonzeros The number of non-zero elements in the sparse vectors/matrices \f$ [1..size] \f$.
211 // \exception std::invalid_argument Invalid size parameter.
212 // \exception std::invalid_argument Invalid number of non-zero elements.
213 //
214 // This constructor creates a sparse run with a specified target size for the sparse vectors
215 // and/or matrices and a specified number of non-zero elements. The number of steps will
216 // automatically be evaluated to guarantuee an approximate runtime of blazemark::runtime
217 // seconds (see for the 'blazemark/config/Config.h' file for more details).
218 */
DynamicSparseRun(size_t size,size_t nonzeros)219 inline DynamicSparseRun::DynamicSparseRun( size_t size, size_t nonzeros )
220    : size_     ( size     )  // The target size of the sparse vectors/matrices
221    , nonzeros_ ( nonzeros )  // The number of non-zero elements in the sparse vectors/matrices.
222    , steps_    ( 0UL      )  // The number of steps for the benchmark run
223    , flops_    ( 0UL      )  // The number of flops required for the benchmark run
224    , clike_    ( 0.0      )  // Benchmark result of the C-like implementation
225    , classic_  ( 0.0      )  // Benchmark result of the classic C++ implementation
226    , blaze_    ( 0.0      )  // Benchmark result of the Blaze library
227    , boost_    ( 0.0      )  // Benchmark result of the Boost uBLAS library
228    , blitz_    ( 0.0      )  // Benchmark result of the Blitz++ library
229    , gmm_      ( 0.0      )  // Benchmark result of the GMM++ library
230    , armadillo_( 0.0      )  // Benchmark result of the Armadillo library
231    , flens_    ( 0.0      )  // Benchmark result of the FLENS library
232    , mtl_      ( 0.0      )  // Benchmark result of the MTL4 library
233    , eigen_    ( 0.0      )  // Benchmark result of the Eigen3 library
234 {
235    // Checking the target size for the sparse vectors/matrices
236    if( size_ == size_t(0) )
237       throw std::invalid_argument( "Invalid size parameter" );
238 
239    // Checking the number of non-zero elements
240    if( nonzeros_ == size_t(0) || nonzeros_ > size_ )
241       throw std::invalid_argument( "Invalid number of non-zero elements" );
242 }
243 //*************************************************************************************************
244 
245 
246 //*************************************************************************************************
247 /*!\brief Three-argument constructor for the DynamicSparseRun class.
248 //
249 // \param size The size of the sparse vector or matrix \f$ [1..\infty) \f$.
250 // \param nonzeros The number of non-zero elements in the sparse vectors/matrices \f$ [1..size] \f$.
251 // \param steps The number of steps for the benchmark \f$ [1..\infty) \f$.
252 // \exception std::invalid_argument Invalid size parameter.
253 // \exception std::invalid_argument Invalid number of non-zero elements.
254 //
255 // This constructor creates a sparse run with a specified target size for the sparse vectors
256 // and/or matrcies, a specfied number of non-zero elements, and a specified number of steps
257 // for the benchmark. In case \a steps is zero, the number of steps will automatically be
258 // evaluated to guarantee an approximate runtime of blazemark::runtime seconds (see for
259 // the 'blazemark/config/Config.h' file for more details).
260 */
DynamicSparseRun(size_t size,size_t nonzeros,size_t steps)261 inline DynamicSparseRun::DynamicSparseRun( size_t size, size_t nonzeros, size_t steps )
262    : size_     ( size     )  // The target size of the sparse vectors/matrices
263    , nonzeros_ ( nonzeros )  // The number of non-zero elements in the sparse vectors/matrices
264    , steps_    ( steps    )  // The number of steps for the benchmark run
265    , flops_    ( 0UL      )  // The number of flops required for the benchmark run
266    , clike_    ( 0.0      )  // Benchmark result of the C-like implementation
267    , classic_  ( 0.0      )  // Benchmark result of the classic C++ implementation
268    , blaze_    ( 0.0      )  // Benchmark result of the Blaze library
269    , boost_    ( 0.0      )  // Benchmark result of the Boost uBLAS library
270    , blitz_    ( 0.0      )  // Benchmark result of the Blitz++ library
271    , gmm_      ( 0.0      )  // Benchmark result of the GMM++ library
272    , armadillo_( 0.0      )  // Benchmark result of the Armadillo library
273    , flens_    ( 0.0      )  // Benchmark result of the FLENS library
274    , mtl_      ( 0.0      )  // Benchmark result of the MTL4 library
275    , eigen_    ( 0.0      )  // Benchmark result of the Eigen3 library
276 {
277    // Checking the target size for the sparse vectors/matrices
278    if( size_ == size_t(0) )
279       throw std::invalid_argument( "Invalid size parameter" );
280 
281    // Checking the number of non-zero elements
282    if( nonzeros_ == size_t(0) || nonzeros_ > size_ )
283       throw std::invalid_argument( "Invalid number of non-zero elements" );
284 }
285 //*************************************************************************************************
286 
287 
288 
289 
290 //=================================================================================================
291 //
292 //  UTILITY FUNCTIONS
293 //
294 //=================================================================================================
295 
296 //*************************************************************************************************
297 /*!\brief Returns the target size of the sparse vectors/matrices of the benchmark run.
298 //
299 // \return The target size of the vectors/matrices.
300 */
getSize()301 inline size_t DynamicSparseRun::getSize() const
302 {
303    return size_;
304 }
305 //*************************************************************************************************
306 
307 
308 //*************************************************************************************************
309 /*!\brief Returns the number of non-zero elements of the sparse vectors/matrices of the benchmark run.
310 //
311 // \return The number of non-zero elements of the vectors/matrices.
312 */
getNonZeros()313 inline size_t DynamicSparseRun::getNonZeros() const
314 {
315    return nonzeros_;
316 }
317 //*************************************************************************************************
318 
319 
320 //*************************************************************************************************
321 /*!\brief Returns the filling degree of the sparse vectors/matrices of the benchmark run.
322 //
323 // \return The filling degree of the vectors/matrices in percent.
324 */
getFillingDegree()325 inline float DynamicSparseRun::getFillingDegree() const
326 {
327    return float(nonzeros_) / float(size_) * 100.0F;
328 }
329 //*************************************************************************************************
330 
331 
332 //*************************************************************************************************
333 /*!\brief Returns the number of steps of the benchmark run.
334 //
335 // \return The number of steps of the benchmark run.
336 */
getSteps()337 inline size_t DynamicSparseRun::getSteps() const
338 {
339    return steps_;
340 }
341 //*************************************************************************************************
342 
343 
344 //*************************************************************************************************
345 /*!\brief Returns the number of required floating point operations.
346 //
347 // \return The number of required floating point operations.
348 */
getFlops()349 inline size_t DynamicSparseRun::getFlops() const
350 {
351    return flops_;
352 }
353 //*************************************************************************************************
354 
355 
356 //*************************************************************************************************
357 /*!\brief Returns the benchmark result of the C-like implementation.
358 //
359 // \return The result of the C-like implementation.
360 */
getClikeResult()361 inline double DynamicSparseRun::getClikeResult() const
362 {
363    return clike_;
364 }
365 //*************************************************************************************************
366 
367 
368 //*************************************************************************************************
369 /*!\brief Returns the benchmark result of the classic C++ implementation.
370 //
371 // \return The result of the classic C++ implementation.
372 */
getClassicResult()373 inline double DynamicSparseRun::getClassicResult() const
374 {
375    return classic_;
376 }
377 //*************************************************************************************************
378 
379 
380 //*************************************************************************************************
381 /*!\brief Returns the benchmark result of the Blaze library.
382 //
383 // \return The result of the Blaze library.
384 */
getBlazeResult()385 inline double DynamicSparseRun::getBlazeResult() const
386 {
387    return blaze_;
388 }
389 //*************************************************************************************************
390 
391 
392 //*************************************************************************************************
393 /*!\brief Returns the benchmark result of the Boost uBLAS library.
394 //
395 // \return The result of the Boost uBLAS library.
396 */
getBoostResult()397 inline double DynamicSparseRun::getBoostResult() const
398 {
399    return boost_;
400 }
401 //*************************************************************************************************
402 
403 
404 //*************************************************************************************************
405 /*!\brief Returns the benchmark result of the Blitz++ library.
406 //
407 // \return The result of the Blitz++ library.
408 */
getBlitzResult()409 inline double DynamicSparseRun::getBlitzResult() const
410 {
411    return blitz_;
412 }
413 //*************************************************************************************************
414 
415 
416 //*************************************************************************************************
417 /*!\brief Returns the benchmark result of the GMM++ library.
418 //
419 // \return The result of the GMM++ library.
420 */
getGMMResult()421 inline double DynamicSparseRun::getGMMResult() const
422 {
423    return gmm_;
424 }
425 //*************************************************************************************************
426 
427 
428 //*************************************************************************************************
429 /*!\brief Returns the benchmark result of the Armadillo library.
430 //
431 // \return The result of the Armadillo library.
432 */
getArmadilloResult()433 inline double DynamicSparseRun::getArmadilloResult() const
434 {
435    return armadillo_;
436 }
437 //*************************************************************************************************
438 
439 
440 //*************************************************************************************************
441 /*!\brief Returns the benchmark result of the FLENS library.
442 //
443 // \return The result of the FLENS library.
444 */
getFLENSResult()445 inline double DynamicSparseRun::getFLENSResult() const
446 {
447    return flens_;
448 }
449 //*************************************************************************************************
450 
451 
452 //*************************************************************************************************
453 /*!\brief Returns the benchmark result of the MTL4 library.
454 //
455 // \return The result of the MTL4 library.
456 */
getMTLResult()457 inline double DynamicSparseRun::getMTLResult() const
458 {
459    return mtl_;
460 }
461 //*************************************************************************************************
462 
463 
464 //*************************************************************************************************
465 /*!\brief Returns the benchmark result of the Eigen3 library.
466 //
467 // \return The result of the Eigen3 library.
468 */
getEigenResult()469 inline double DynamicSparseRun::getEigenResult() const
470 {
471    return eigen_;
472 }
473 //*************************************************************************************************
474 
475 
476 //*************************************************************************************************
477 /*!\brief Setting the target size of the vectors/matrices of the benchmark run.
478 //
479 // \param newSize The new target size of the vectors/matrices of the benchmark run.
480 // \return void
481 // \exception std::invalid_argument Invalid size parameter.
482 */
setSize(size_t newSize)483 inline void DynamicSparseRun::setSize( size_t newSize )
484 {
485    if( newSize == size_t(0) )
486       throw std::invalid_argument( "Invalid size parameter" );
487    size_ = newSize;
488 }
489 //*************************************************************************************************
490 
491 
492 //*************************************************************************************************
493 /*!\brief Setting the number of non-zero elements of the vectors/matrices of the benchmark run.
494 //
495 // \param newNonZeros The new number of non-zero elements of the vectors/matrices of the benchmark run.
496 // \return void
497 // \exception std::invalid_argument Invalid number of non-zero elements.
498 */
setNonZeros(size_t newNonZeros)499 inline void DynamicSparseRun::setNonZeros( size_t newNonZeros )
500 {
501    if( newNonZeros == size_t(0) || newNonZeros > size_ )
502       throw std::invalid_argument( "Invalid number of non-zero elements" );
503    nonzeros_ = newNonZeros;
504 }
505 //*************************************************************************************************
506 
507 
508 //*************************************************************************************************
509 /*!\brief Setting the number of steps of the benchmark run.
510 //
511 // \param newSteps The new number of steps of the benchmark run.
512 // \return void
513 */
setSteps(size_t newSteps)514 inline void DynamicSparseRun::setSteps( size_t newSteps )
515 {
516    steps_ = newSteps;
517 }
518 //*************************************************************************************************
519 
520 
521 //*************************************************************************************************
522 /*!\brief Setting the number of required floating point operations.
523 //
524 // \param newFlops The new number of required floating point operations.
525 // \return void
526 */
setFlops(size_t newFlops)527 inline void DynamicSparseRun::setFlops( size_t newFlops )
528 {
529    flops_ = newFlops;
530 }
531 //*************************************************************************************************
532 
533 
534 //*************************************************************************************************
535 /*!\brief Setting the benchmark result of the C-like implementation.
536 //
537 // \param result The result of the C-like implementation.
538 // \return void
539 // \exception std::invalid_argument Invalid result value.
540 */
setClikeResult(double result)541 inline void DynamicSparseRun::setClikeResult( double result )
542 {
543    if( result < 0.0 )
544       throw std::invalid_argument( "Invalid result value" );
545    clike_ = result;
546 }
547 //*************************************************************************************************
548 
549 
550 //*************************************************************************************************
551 /*!\brief Setting the benchmark result of the classic C++ implementation.
552 //
553 // \param result The result of the classic C++ implementation.
554 // \return void
555 // \exception std::invalid_argument Invalid result value.
556 */
setClassicResult(double result)557 inline void DynamicSparseRun::setClassicResult( double result )
558 {
559    if( result < 0.0 )
560       throw std::invalid_argument( "Invalid result value" );
561    classic_ = result;
562 }
563 //*************************************************************************************************
564 
565 
566 //*************************************************************************************************
567 /*!\brief Setting the benchmark result of the Blaze library.
568 //
569 // \param result The result of the Blaze library.
570 // \return void
571 // \exception std::invalid_argument Invalid result value.
572 */
setBlazeResult(double result)573 inline void DynamicSparseRun::setBlazeResult( double result )
574 {
575    if( result < 0.0 )
576       throw std::invalid_argument( "Invalid result value" );
577    blaze_ = result;
578 }
579 //*************************************************************************************************
580 
581 
582 //*************************************************************************************************
583 /*!\brief Setting the benchmark result of the Boost uBLAS library.
584 //
585 // \param result The result of the Boost uBLAS library.
586 // \return void
587 // \exception std::invalid_argument Invalid result value.
588 */
setBoostResult(double result)589 inline void DynamicSparseRun::setBoostResult( double result )
590 {
591    if( result < 0.0 )
592       throw std::invalid_argument( "Invalid result value" );
593    boost_ = result;
594 }
595 //*************************************************************************************************
596 
597 
598 //*************************************************************************************************
599 /*!\brief Setting the benchmark result of the Blitz++ library.
600 //
601 // \param result The result of the Blitz++ library.
602 // \return void
603 // \exception std::invalid_argument Invalid result value.
604 */
setBlitzResult(double result)605 inline void DynamicSparseRun::setBlitzResult( double result )
606 {
607    if( result < 0.0 )
608       throw std::invalid_argument( "Invalid result value" );
609    blitz_ = result;
610 }
611 //*************************************************************************************************
612 
613 
614 //*************************************************************************************************
615 /*!\brief Setting the benchmark result of the GMM++ library.
616 //
617 // \param result The result of the GMM++ library.
618 // \return void
619 // \exception std::invalid_argument Invalid result value.
620 */
setGMMResult(double result)621 inline void DynamicSparseRun::setGMMResult( double result )
622 {
623    if( result < 0.0 )
624       throw std::invalid_argument( "Invalid result value" );
625    gmm_ = result;
626 }
627 //*************************************************************************************************
628 
629 
630 //*************************************************************************************************
631 /*!\brief Setting the benchmark result of the Armadillo library.
632 //
633 // \param result The result of the Armadillo library.
634 // \return void
635 // \exception std::invalid_argument Invalid result value.
636 */
setArmadilloResult(double result)637 inline void DynamicSparseRun::setArmadilloResult( double result )
638 {
639    if( result < 0.0 )
640       throw std::invalid_argument( "Invalid result value" );
641    armadillo_ = result;
642 }
643 //*************************************************************************************************
644 
645 
646 //*************************************************************************************************
647 /*!\brief Setting the benchmark result of the FLENS library.
648 //
649 // \param result The result of the FLENS library.
650 // \return void
651 // \exception std::invalid_argument Invalid result value.
652 */
setFLENSResult(double result)653 inline void DynamicSparseRun::setFLENSResult( double result )
654 {
655    if( result < 0.0 )
656       throw std::invalid_argument( "Invalid result value" );
657    flens_ = result;
658 }
659 //*************************************************************************************************
660 
661 
662 //*************************************************************************************************
663 /*!\brief Setting the benchmark result of the MTL4 library.
664 //
665 // \param result The result of the MTL4 library.
666 // \return void
667 // \exception std::invalid_argument Invalid result value.
668 */
setMTLResult(double result)669 inline void DynamicSparseRun::setMTLResult( double result )
670 {
671    if( result < 0.0 )
672       throw std::invalid_argument( "Invalid result value" );
673    mtl_ = result;
674 }
675 //*************************************************************************************************
676 
677 
678 //*************************************************************************************************
679 /*!\brief Setting the benchmark result of the Eigen3 library.
680 //
681 // \param result The result of the Eigen3 library.
682 // \return void
683 // \exception std::invalid_argument Invalid result value.
684 */
setEigenResult(double result)685 inline void DynamicSparseRun::setEigenResult( double result )
686 {
687    if( result < 0.0 )
688       throw std::invalid_argument( "Invalid result value" );
689    eigen_ = result;
690 }
691 //*************************************************************************************************
692 
693 
694 
695 
696 //=================================================================================================
697 //
698 //  GLOBAL OPERATORS
699 //
700 //=================================================================================================
701 
702 //*************************************************************************************************
703 /*!\brief Less-than comparison between two DynamicSparseRun objects.
704 //
705 // \param lhs The left-hand side DynamicSparseRun object.
706 // \param rhs The right-hand side DynamicSparseRun object.
707 // \return \a true if the left value is less than the right value, \a false if not.
708 //
709 // DynamicSparseRun objects are primarily sorted according to the number of non-zero elements
710 // and secondarily according to the size of the vectors/matrices: In case the nonzeros value
711 // of the left-hand side DynamicSparseRun object is smaller or in case both nonzeros values
712 // are equal and the size value of the left-hand side is smaller the function returns \a true.
713 // Otherwise the function returns \a false.
714 */
715 inline bool operator<( const DynamicSparseRun& lhs, const DynamicSparseRun& rhs )
716 {
717    return ( lhs.getFillingDegree() < rhs.getFillingDegree() ) ||
718           ( ::blaze::equal( lhs.getFillingDegree(), rhs.getFillingDegree() ) && lhs.getSize() < rhs.getSize() );
719 }
720 //*************************************************************************************************
721 
722 
723 //*************************************************************************************************
724 /*!\brief Global output operator for the DynamicSparseRun class.
725 //
726 // \param os Reference to the output stream.
727 // \param run Reference to a DynamicSparseRun object.
728 // \return The output stream.
729 */
730 inline std::ostream& operator<<( std::ostream& os, const DynamicSparseRun& run )
731 {
732    const std::ios::fmtflags flags( os.flags() );
733 
734    os << std::left << "   N=" << run.getSize() << ", fill level=" << run.getFillingDegree() << "%, steps=" << run.getSteps() << "\n";
735 
736    const double clike    ( run.getClikeResult()     );
737    const double classic  ( run.getClassicResult()   );
738    const double blaze    ( run.getBlazeResult()     );
739    const double boost    ( run.getBoostResult()     );
740    const double blitz    ( run.getBlitzResult()     );
741    const double gmm      ( run.getGMMResult()       );
742    const double armadillo( run.getArmadilloResult() );
743    const double flens    ( run.getFLENSResult()     );
744    const double mtl      ( run.getMTLResult()       );
745    const double eigen    ( run.getEigenResult()     );
746 
747    double minTime = ::blaze::inf;
748 
749    if( clike     != 0.0 ) minTime = ::blaze::min( minTime, clike     );
750    if( classic   != 0.0 ) minTime = ::blaze::min( minTime, classic   );
751    if( blaze     != 0.0 ) minTime = ::blaze::min( minTime, blaze     );
752    if( boost     != 0.0 ) minTime = ::blaze::min( minTime, boost     );
753    if( blitz     != 0.0 ) minTime = ::blaze::min( minTime, blitz     );
754    if( gmm       != 0.0 ) minTime = ::blaze::min( minTime, gmm       );
755    if( armadillo != 0.0 ) minTime = ::blaze::min( minTime, armadillo );
756    if( flens     != 0.0 ) minTime = ::blaze::min( minTime, flens     );
757    if( mtl       != 0.0 ) minTime = ::blaze::min( minTime, mtl       );
758    if( eigen     != 0.0 ) minTime = ::blaze::min( minTime, eigen     );
759 
760    if( clike     != 0.0 ) os << "     C-like      = " << std::setw(8) << ( clike     / minTime ) << " (" << clike     << ")\n";
761    if( classic   != 0.0 ) os << "     Classic     = " << std::setw(8) << ( classic   / minTime ) << " (" << classic   << ")\n";
762    if( blaze     != 0.0 ) os << "     Blaze       = " << std::setw(8) << ( blaze     / minTime ) << " (" << blaze     << ")\n";
763    if( boost     != 0.0 ) os << "     Boost uBLAS = " << std::setw(8) << ( boost     / minTime ) << " (" << boost     << ")\n";
764    if( blitz     != 0.0 ) os << "     Blitz++     = " << std::setw(8) << ( blitz     / minTime ) << " (" << blitz     << ")\n";
765    if( gmm       != 0.0 ) os << "     GMM++       = " << std::setw(8) << ( gmm       / minTime ) << " (" << gmm       << ")\n";
766    if( armadillo != 0.0 ) os << "     Armadillo   = " << std::setw(8) << ( armadillo / minTime ) << " (" << armadillo << ")\n";
767    if( flens     != 0.0 ) os << "     FLENS       = " << std::setw(8) << ( flens     / minTime ) << " (" << flens     << ")\n";
768    if( mtl       != 0.0 ) os << "     MTL         = " << std::setw(8) << ( mtl       / minTime ) << " (" << mtl       << ")\n";
769    if( eigen     != 0.0 ) os << "     Eigen       = " << std::setw(8) << ( eigen     / minTime ) << " (" << eigen     << ")\n";
770 
771    os << std::flush;
772 
773    os.flags( flags );
774    return os;
775 }
776 //*************************************************************************************************
777 
778 
779 //*************************************************************************************************
780 /*!\brief Global input operator for the DynamicSparseRun class.
781 //
782 // \param is Reference to the input stream.
783 // \param run Reference to a DynamicSparseRun object.
784 // \return The input stream.
785 //
786 // The input operator guarantees that this object is not changed in the case of an input error.
787 // Only values suitable for the according built-in unsigned integral data type \a T are allowed.
788 // Otherwise, the input stream's position is returned to its previous position and the
789 // \a std::istream::failbit is set.
790 */
791 inline std::istream& operator>>( std::istream& is, DynamicSparseRun& run )
792 {
793    char c1, c2, c3;
794    ::blaze::UnsignedValue<size_t> size, nonzeros, steps;
795    const std::istream::pos_type pos( is.tellg() );
796 
797    if( !(is >> c1 >> size >> c2 >> nonzeros >> c3) ||
798        c1 != '(' || size == 0 || c2 != ',' || nonzeros == 0 ||
799        ( c3 != ')' && ( c3 != ',' || ( !(is >> steps >> c1) || c1 != ')' || steps == 0 ) ) ) )
800    {
801       is.clear();
802       is.seekg( pos );
803       is.setstate( std::istream::failbit );
804       return is;
805    }
806 
807    run.setSize( size );
808    run.setNonZeros( nonzeros );
809    run.setSteps( steps );
810 
811    return is;
812 }
813 //*************************************************************************************************
814 
815 } // namespace blazemark
816 
817 #endif
818