Blaze  3.6
DMatReduceExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATREDUCEEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATREDUCEEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
64 #include <blaze/math/SIMD.h>
72 #include <blaze/math/views/Check.h>
75 #include <blaze/util/Assert.h>
76 #include <blaze/util/DisableIf.h>
77 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/mpl/If.h>
81 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS DEFINITION
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename MT // Type of the dense matrix
103  , typename OP // Type of the reduction operation
104  , size_t RF > // Reduction flag
106 {};
107 //*************************************************************************************************
108 
109 
110 
111 
112 //=================================================================================================
113 //
114 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-WISE REDUCTION OPERATIONS OF ROW-MAJOR MATRICES
115 //
116 //=================================================================================================
117 
118 //*************************************************************************************************
125 template< typename MT // Type of the dense matrix
126  , typename OP > // Type of the reduction operation
128  : public MatReduceExpr< DenseVector< DMatReduceExpr<MT,OP,columnwise>, true >, columnwise >
129  , private Computation
130 {
131  private:
132  //**Type definitions****************************************************************************
136  //**********************************************************************************************
137 
138  //**Parallel evaluation strategy****************************************************************
140 
145  template< typename VT >
146  static constexpr bool UseSMPAssign_v = ( !MT::smpAssignable && RequiresEvaluation_v<MT> );
148  //**********************************************************************************************
149 
150  public:
151  //**Type definitions****************************************************************************
158  using ReturnType = const ElementType;
159  using CompositeType = const ResultType;
160 
162  using Operand = If_t< IsExpression_v<MT>, const MT, const MT& >;
163 
165  using Operation = OP;
166  //**********************************************************************************************
167 
168  //**Compilation flags***************************************************************************
170  static constexpr bool simdEnabled = false;
171 
173  static constexpr bool smpAssignable = MT::smpAssignable;
174  //**********************************************************************************************
175 
176  //**Constructor*********************************************************************************
182  explicit inline DMatReduceExpr( const MT& dm, OP op ) noexcept
183  : dm_( dm ) // Dense matrix of the reduction expression
184  , op_( op ) // The reduction operation
185  {}
186  //**********************************************************************************************
187 
188  //**Subscript operator**************************************************************************
194  inline ReturnType operator[]( size_t index ) const {
195  BLAZE_INTERNAL_ASSERT( index < dm_.columns(), "Invalid vector access index" );
196  return reduce( column( dm_, index, unchecked ), op_ );
197  }
198  //**********************************************************************************************
199 
200  //**At function*********************************************************************************
207  inline ReturnType at( size_t index ) const {
208  if( index >= dm_.columns() ) {
209  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
210  }
211  return (*this)[index];
212  }
213  //**********************************************************************************************
214 
215  //**Size function*******************************************************************************
220  inline size_t size() const noexcept {
221  return dm_.columns();
222  }
223  //**********************************************************************************************
224 
225  //**Operand access******************************************************************************
230  inline Operand operand() const noexcept {
231  return dm_;
232  }
233  //**********************************************************************************************
234 
235  //**Operation access****************************************************************************
240  inline Operation operation() const {
241  return op_;
242  }
243  //**********************************************************************************************
244 
245  //**********************************************************************************************
251  template< typename T >
252  inline bool canAlias( const T* alias ) const noexcept {
253  return ( dm_.isAliased( alias ) );
254  }
255  //**********************************************************************************************
256 
257  //**********************************************************************************************
263  template< typename T >
264  inline bool isAliased( const T* alias ) const noexcept {
265  return ( dm_.isAliased( alias ) );
266  }
267  //**********************************************************************************************
268 
269  //**********************************************************************************************
274  inline bool isAligned() const noexcept {
275  return false;
276  }
277  //**********************************************************************************************
278 
279  //**********************************************************************************************
284  inline bool canSMPAssign() const noexcept {
285  return dm_.canSMPAssign() || ( size() > SMP_DMATREDUCE_THRESHOLD );
286  }
287  //**********************************************************************************************
288 
289  private:
290  //**Member variables****************************************************************************
293  //**********************************************************************************************
294 
295  //**Assignment to dense vectors*****************************************************************
307  template< typename VT1 > // Type of the target dense vector
308  friend inline void assign( DenseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
309  {
311 
312  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
313 
314  const size_t M( rhs.dm_.rows() );
315 
316  if( M == 0UL ) {
317  reset( ~lhs );
318  return;
319  }
320 
321  CT tmp( serial( rhs.dm_ ) );
322 
323  assign( ~lhs, row( tmp, 0UL, unchecked ) );
324  for( size_t i=1UL; i<M; ++i ) {
325  assign( ~lhs, map( ~lhs, row( tmp, i, unchecked ), rhs.op_ ) );
326  }
327  }
329  //**********************************************************************************************
330 
331  //**Assignment to sparse vectors****************************************************************
343  template< typename VT1 > // Type of the target dense vector
344  friend inline void assign( SparseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
345  {
347 
351 
352  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
353 
354  const ResultType tmp( serial( rhs ) );
355  assign( ~lhs, tmp );
356  }
358  //**********************************************************************************************
359 
360  //**Addition assignment to dense vectors********************************************************
373  template< typename VT1 > // Type of the target dense vector
374  friend inline void addAssign( DenseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
375  {
377 
378  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
379 
380  if( rhs.dm_.rows() == 0UL ) {
381  return;
382  }
383  else if( IsSame_v<OP,Add> ) {
384  CT tmp( serial( rhs.dm_ ) );
385  const size_t M( tmp.rows() );
386  for( size_t i=0UL; i<M; ++i ) {
387  addAssign( (~lhs), row( tmp, i, unchecked ) );
388  }
389  }
390  else {
391  const ResultType tmp( serial( rhs ) );
392  addAssign( ~lhs, tmp );
393  }
394  }
396  //**********************************************************************************************
397 
398  //**Addition assignment to sparse vectors*******************************************************
411  template< typename VT1 > // Type of the target dense vector
412  friend inline void addAssign( SparseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
413  {
415 
419 
420  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
421 
422  const ResultType tmp( serial( rhs ) );
423  addAssign( ~lhs, tmp );
424  }
426  //**********************************************************************************************
427 
428  //**Subtraction assignment to dense vectors*****************************************************
441  template< typename VT1 > // Type of the target dense vector
442  friend inline void subAssign( DenseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
443  {
445 
446  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
447 
448  if( rhs.dm_.rows() == 0UL ) {
449  return;
450  }
451  else if( IsSame_v<OP,Add> ) {
452  CT tmp( serial( rhs.dm_ ) );
453  const size_t M( tmp.rows() );
454  for( size_t i=0UL; i<M; ++i ) {
455  subAssign( (~lhs), row( tmp, i, unchecked ) );
456  }
457  }
458  else {
459  const ResultType tmp( serial( rhs ) );
460  subAssign( ~lhs, tmp );
461  }
462  }
464  //**********************************************************************************************
465 
466  //**Subtraction assignment to sparse vectors****************************************************
479  template< typename VT1 > // Type of the target dense vector
480  friend inline void subAssign( SparseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
481  {
483 
487 
488  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
489 
490  const ResultType tmp( serial( rhs ) );
491  subAssign( ~lhs, tmp );
492  }
494  //**********************************************************************************************
495 
496  //**Multiplication assignment to dense vectors**************************************************
509  template< typename VT1 > // Type of the target dense vector
510  friend inline void multAssign( DenseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
511  {
513 
514  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
515 
516  if( rhs.dm_.rows() == 0UL ) {
517  reset( ~lhs );
518  }
519  else if( IsSame_v<OP,Mult> ) {
520  CT tmp( serial( rhs.dm_ ) );
521  const size_t M( tmp.rows() );
522  for( size_t i=0UL; i<M; ++i ) {
523  multAssign( (~lhs), row( tmp, i, unchecked ) );
524  }
525  }
526  else {
527  const ResultType tmp( serial( rhs ) );
528  multAssign( ~lhs, tmp );
529  }
530  }
532  //**********************************************************************************************
533 
534  //**Multiplication assignment to sparse vectors*************************************************
547  template< typename VT1 > // Type of the target dense vector
548  friend inline void multAssign( SparseVector<VT1,true>& lhs, const DMatReduceExpr& rhs )
549  {
551 
555 
556  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
557 
558  const ResultType tmp( serial( rhs ) );
559  multAssign( ~lhs, tmp );
560  }
562  //**********************************************************************************************
563 
564  //**Division assignment to vectors**************************************************************
577  template< typename VT1 > // Type of the target vector
578  friend inline void divAssign( Vector<VT1,true>& lhs, const DMatReduceExpr& rhs )
579  {
581 
585 
586  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
587 
588  const ResultType tmp( serial( rhs ) );
589  divAssign( ~lhs, tmp );
590  }
592  //**********************************************************************************************
593 
594  //**SMP assignment to vectors*******************************************************************
608  template< typename VT1 > // Type of the target vector
609  friend inline auto smpAssign( Vector<VT1,true>& lhs, const DMatReduceExpr& rhs )
610  -> EnableIf_t< UseSMPAssign_v<VT1> >
611  {
613 
614  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
615 
616  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
617  smpAssign( ~lhs, reduce<columnwise>( tmp, rhs.op_ ) );
618  }
620  //**********************************************************************************************
621 
622  //**SMP addition assignment to vectors**********************************************************
637  template< typename VT1 > // Type of the target vector
638  friend inline auto smpAddAssign( Vector<VT1,true>& lhs, const DMatReduceExpr& rhs )
639  -> EnableIf_t< UseSMPAssign_v<VT1> >
640  {
642 
643  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
644 
645  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
646  smpAddAssign( ~lhs, reduce<columnwise>( tmp, rhs.op_ ) );
647  }
649  //**********************************************************************************************
650 
651  //**SMP subtraction assignment to vectors*******************************************************
666  template< typename VT1 > // Type of the target vector
667  friend inline auto smpSubAssign( Vector<VT1,true>& lhs, const DMatReduceExpr& rhs )
668  -> EnableIf_t< UseSMPAssign_v<VT1> >
669  {
671 
672  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
673 
674  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
675  smpSubAssign( ~lhs, reduce<columnwise>( tmp, rhs.op_ ) );
676  }
678  //**********************************************************************************************
679 
680  //**SMP multiplication assignment to vectors****************************************************
695  template< typename VT1 > // Type of the target vector
696  friend inline auto smpMultAssign( Vector<VT1,true>& lhs, const DMatReduceExpr& rhs )
697  -> EnableIf_t< UseSMPAssign_v<VT1> >
698  {
700 
701  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
702 
703  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
704  smpMultAssign( ~lhs, reduce<columnwise>( tmp, rhs.op_ ) );
705  }
707  //**********************************************************************************************
708 
709  //**SMP division assignment to vectors**********************************************************
724  template< typename VT1 > // Type of the target vector
725  friend inline auto smpDivAssign( Vector<VT1,true>& lhs, const DMatReduceExpr& rhs )
726  -> EnableIf_t< UseSMPAssign_v<VT1> >
727  {
729 
730  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
731 
732  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
733  smpDivAssign( ~lhs, reduce<columnwise>( tmp, rhs.op_ ) );
734  }
736  //**********************************************************************************************
737 
738  //**Compile time checks*************************************************************************
743  //**********************************************************************************************
744 };
745 //*************************************************************************************************
746 
747 
748 
749 
750 //=================================================================================================
751 //
752 // CLASS TEMPLATE SPECIALIZATION FOR ROW-WISE REDUCTION OPERATIONS OF ROW-MAJOR MATRICES
753 //
754 //=================================================================================================
755 
756 //*************************************************************************************************
763 template< typename MT // Type of the dense matrix
764  , typename OP > // Type of the reduction operation
766  : public MatReduceExpr< DenseVector< DMatReduceExpr<MT,OP,rowwise>, false >, rowwise >
767  , private Computation
768 {
769  private:
770  //**Type definitions****************************************************************************
773  //**********************************************************************************************
774 
775  //**Serial evaluation strategy******************************************************************
777 
783  static constexpr bool useAssign = RequiresEvaluation_v<MT>;
784 
786  template< typename VT >
788  static constexpr bool UseAssign_v = useAssign;
790  //**********************************************************************************************
791 
792  //**Parallel evaluation strategy****************************************************************
794 
799  template< typename VT >
800  static constexpr bool UseSMPAssign_v = ( !MT::smpAssignable && useAssign );
802  //**********************************************************************************************
803 
804  public:
805  //**Type definitions****************************************************************************
812  using ReturnType = const ElementType;
813 
816 
818  using Operand = If_t< IsExpression_v<MT>, const MT, const MT& >;
819 
821  using Operation = OP;
822  //**********************************************************************************************
823 
824  //**ConstIterator class definition**************************************************************
827  class ConstIterator
828  {
829  public:
830  //**Type definitions*************************************************************************
831  using IteratorCategory = std::random_access_iterator_tag;
836 
837  // STL iterator requirements
843  //*******************************************************************************************
844 
845  //**Constructor******************************************************************************
852  explicit inline ConstIterator( Operand dm, size_t index, OP op )
853  : dm_ ( dm ) // Dense matrix of the reduction expression
854  , index_( index ) // Index to the current matrix row
855  , op_ ( op ) // The reduction operation
856  {}
857  //*******************************************************************************************
858 
859  //**Addition assignment operator*************************************************************
865  inline BLAZE_DEVICE_CALLABLE ConstIterator& operator+=( size_t inc ) {
866  index_ += inc;
867  return *this;
868  }
869  //*******************************************************************************************
870 
871  //**Subtraction assignment operator**********************************************************
877  inline BLAZE_DEVICE_CALLABLE ConstIterator& operator-=( size_t dec ) {
878  index_ -= dec;
879  return *this;
880  }
881  //*******************************************************************************************
882 
883  //**Prefix increment operator****************************************************************
888  inline BLAZE_DEVICE_CALLABLE ConstIterator& operator++() {
889  ++index_;
890  return *this;
891  }
892  //*******************************************************************************************
893 
894  //**Postfix increment operator***************************************************************
899  inline BLAZE_DEVICE_CALLABLE const ConstIterator operator++( int ) {
900  return ConstIterator( index_++ );
901  }
902  //*******************************************************************************************
903 
904  //**Prefix decrement operator****************************************************************
909  inline BLAZE_DEVICE_CALLABLE ConstIterator& operator--() {
910  --index_;
911  return *this;
912  }
913  //*******************************************************************************************
914 
915  //**Postfix decrement operator***************************************************************
920  inline BLAZE_DEVICE_CALLABLE const ConstIterator operator--( int ) {
921  return ConstIterator( index_-- );
922  }
923  //*******************************************************************************************
924 
925  //**Element access operator******************************************************************
930  inline ReturnType operator*() const {
931  return reduce( row( dm_, index_, unchecked ), op_ );
932  }
933  //*******************************************************************************************
934 
935  //**Equality operator************************************************************************
941  inline bool operator==( const ConstIterator& rhs ) const {
942  return index_ == rhs.index_;
943  }
944  //*******************************************************************************************
945 
946  //**Inequality operator**********************************************************************
952  inline bool operator!=( const ConstIterator& rhs ) const {
953  return index_ != rhs.index_;
954  }
955  //*******************************************************************************************
956 
957  //**Less-than operator***********************************************************************
963  inline bool operator<( const ConstIterator& rhs ) const {
964  return index_ < rhs.index_;
965  }
966  //*******************************************************************************************
967 
968  //**Greater-than operator********************************************************************
974  inline bool operator>( const ConstIterator& rhs ) const {
975  return index_ > rhs.index_;
976  }
977  //*******************************************************************************************
978 
979  //**Less-or-equal-than operator**************************************************************
985  inline bool operator<=( const ConstIterator& rhs ) const {
986  return index_ <= rhs.index_;
987  }
988  //*******************************************************************************************
989 
990  //**Greater-or-equal-than operator***********************************************************
996  inline bool operator>=( const ConstIterator& rhs ) const {
997  return index_ >= rhs.index_;
998  }
999  //*******************************************************************************************
1000 
1001  //**Subtraction operator*********************************************************************
1007  inline DifferenceType operator-( const ConstIterator& rhs ) const {
1008  return index_ - rhs.index_;
1009  }
1010  //*******************************************************************************************
1011 
1012  //**Addition operator************************************************************************
1019  friend inline const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
1020  return ConstIterator( it.index_ + inc );
1021  }
1022  //*******************************************************************************************
1023 
1024  //**Addition operator************************************************************************
1031  friend inline const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
1032  return ConstIterator( it.index_ + inc );
1033  }
1034  //*******************************************************************************************
1035 
1036  //**Subtraction operator*********************************************************************
1043  friend inline const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
1044  return ConstIterator( it.index_ - dec );
1045  }
1046  //*******************************************************************************************
1047 
1048  private:
1049  //**Member variables*************************************************************************
1051  size_t index_;
1052  OP op_;
1053  //*******************************************************************************************
1054  };
1055  //**********************************************************************************************
1056 
1057  //**Compilation flags***************************************************************************
1059  static constexpr bool simdEnabled = false;
1060 
1062  static constexpr bool smpAssignable = MT::smpAssignable;
1063  //**********************************************************************************************
1064 
1065  //**Constructor*********************************************************************************
1071  explicit inline DMatReduceExpr( const MT& dm, OP op ) noexcept
1072  : dm_( dm ) // Dense matrix of the reduction expression
1073  , op_( op ) // The reduction operation
1074  {}
1075  //**********************************************************************************************
1076 
1077  //**Subscript operator**************************************************************************
1083  inline ReturnType operator[]( size_t index ) const {
1084  BLAZE_INTERNAL_ASSERT( index < dm_.rows(), "Invalid vector access index" );
1085  return reduce( row( dm_, index, unchecked ), op_ );
1086  }
1087  //**********************************************************************************************
1088 
1089  //**At function*********************************************************************************
1096  inline ReturnType at( size_t index ) const {
1097  if( index >= dm_.rows() ) {
1098  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
1099  }
1100  return (*this)[index];
1101  }
1102  //**********************************************************************************************
1103 
1104  //**Begin function******************************************************************************
1109  inline ConstIterator begin() const {
1110  return ConstIterator( dm_, 0UL, op_ );
1111  }
1112  //**********************************************************************************************
1113 
1114  //**End function********************************************************************************
1119  inline ConstIterator end() const {
1120  return ConstIterator( dm_, size(), op_ );
1121  }
1122  //**********************************************************************************************
1123 
1124  //**Size function*******************************************************************************
1129  inline size_t size() const noexcept {
1130  return dm_.rows();
1131  }
1132  //**********************************************************************************************
1133 
1134  //**Operand access******************************************************************************
1139  inline Operand operand() const noexcept {
1140  return dm_;
1141  }
1142  //**********************************************************************************************
1143 
1144  //**Operation access****************************************************************************
1149  inline Operation operation() const {
1150  return op_;
1151  }
1152  //**********************************************************************************************
1153 
1154  //**********************************************************************************************
1160  template< typename T >
1161  inline bool canAlias( const T* alias ) const noexcept {
1162  return ( dm_.isAliased( alias ) );
1163  }
1164  //**********************************************************************************************
1165 
1166  //**********************************************************************************************
1172  template< typename T >
1173  inline bool isAliased( const T* alias ) const noexcept {
1174  return ( dm_.isAliased( alias ) );
1175  }
1176  //**********************************************************************************************
1177 
1178  //**********************************************************************************************
1183  inline bool isAligned() const noexcept {
1184  return false;
1185  }
1186  //**********************************************************************************************
1187 
1188  //**********************************************************************************************
1193  inline bool canSMPAssign() const noexcept {
1194  return dm_.canSMPAssign() || ( size() > SMP_DMATREDUCE_THRESHOLD );
1195  }
1196  //**********************************************************************************************
1197 
1198  private:
1199  //**Member variables****************************************************************************
1202  //**********************************************************************************************
1203 
1204  //**Assignment to vectors***********************************************************************
1218  template< typename VT1 > // Type of the target vector
1219  friend inline auto assign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1221  {
1223 
1224  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1225 
1226  const RT tmp( serial( rhs.dm_ ) ); // Evaluation of the dense matrix operand
1227  assign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1228  }
1230  //**********************************************************************************************
1231 
1232  //**Addition assignment to vectors**************************************************************
1246  template< typename VT1 > // Type of the target vector
1247  friend inline auto addAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1249  {
1251 
1252  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1253 
1254  const RT tmp( serial( rhs.dm_ ) ); // Evaluation of the dense matrix operand
1255  addAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1256  }
1258  //**********************************************************************************************
1259 
1260  //**Subtraction assignment to vectors***********************************************************
1275  template< typename VT1 > // Type of the target vector
1276  friend inline auto subAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1277  -> EnableIf_t< UseAssign_v<VT1> >
1278  {
1280 
1281  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1282 
1283  const RT tmp( serial( rhs.dm_ ) ); // Evaluation of the dense matrix operand
1284  subAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1285  }
1287  //**********************************************************************************************
1288 
1289  //**Multiplication assignment to vectors********************************************************
1304  template< typename VT1 > // Type of the target vector
1305  friend inline auto multAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1306  -> EnableIf_t< UseAssign_v<VT1> >
1307  {
1309 
1310  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1311 
1312  const RT tmp( serial( rhs.dm_ ) ); // Evaluation of the dense matrix operand
1313  multAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1314  }
1316  //**********************************************************************************************
1317 
1318  //**Division assignment to vectors**************************************************************
1332  template< typename VT1 > // Type of the target vector
1333  friend inline auto divAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1334  -> EnableIf_t< UseAssign_v<VT1> >
1335  {
1337 
1338  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1339 
1340  const RT tmp( serial( rhs.dm_ ) ); // Evaluation of the dense matrix operand
1341  divAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1342  }
1344  //**********************************************************************************************
1345 
1346  //**SMP assignment to vectors*******************************************************************
1360  template< typename VT1 > // Type of the target vector
1361  friend inline auto smpAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1362  -> EnableIf_t< UseSMPAssign_v<VT1> >
1363  {
1365 
1366  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1367 
1368  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
1369  smpAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1370  }
1372  //**********************************************************************************************
1373 
1374  //**SMP addition assignment to vectors**********************************************************
1389  template< typename VT1 > // Type of the target vector
1390  friend inline auto smpAddAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1391  -> EnableIf_t< UseSMPAssign_v<VT1> >
1392  {
1394 
1395  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1396 
1397  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
1398  smpAddAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1399  }
1401  //**********************************************************************************************
1402 
1403  //**SMP subtraction assignment to vectors*******************************************************
1418  template< typename VT1 > // Type of the target vector
1419  friend inline auto smpSubAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1420  -> EnableIf_t< UseSMPAssign_v<VT1> >
1421  {
1423 
1424  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1425 
1426  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
1427  smpSubAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1428  }
1430  //**********************************************************************************************
1431 
1432  //**SMP multiplication assignment to vectors****************************************************
1447  template< typename VT1 > // Type of the target vector
1448  friend inline auto smpMultAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1449  -> EnableIf_t< UseSMPAssign_v<VT1> >
1450  {
1452 
1453  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1454 
1455  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
1456  smpMultAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1457  }
1459  //**********************************************************************************************
1460 
1461  //**SMP division assignment to vectors**********************************************************
1476  template< typename VT1 > // Type of the target vector
1477  friend inline auto smpDivAssign( Vector<VT1,false>& lhs, const DMatReduceExpr& rhs )
1478  -> EnableIf_t< UseSMPAssign_v<VT1> >
1479  {
1481 
1482  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1483 
1484  const RT tmp( rhs.dm_ ); // Evaluation of the dense matrix operand
1485  smpDivAssign( ~lhs, reduce<rowwise>( tmp, rhs.op_ ) );
1486  }
1488  //**********************************************************************************************
1489 
1490  //**Compile time checks*************************************************************************
1495  //**********************************************************************************************
1496 };
1497 //*************************************************************************************************
1498 
1499 
1500 
1501 
1502 //=================================================================================================
1503 //
1504 // CLASS DEFINITION
1505 //
1506 //=================================================================================================
1507 
1508 //*************************************************************************************************
1513 template< typename MT // Type of the dense matrix
1514  , typename OP > // Type of the reduction operation
1515 struct DMatReduceExprHelper
1516 {
1517  //**Type definitions****************************************************************************
1519  using CT = RemoveReference_t< CompositeType_t<MT> >;
1520 
1522  using ET = ElementType_t<CT>;
1523  //**********************************************************************************************
1524 
1525  //**********************************************************************************************
1526  static constexpr bool value =
1527  ( CT::simdEnabled &&
1528  If_t< HasSIMDEnabled_v<OP>, GetSIMDEnabled<OP,ET,ET>, HasLoad<OP> >::value );
1529  //**********************************************************************************************
1530 };
1532 //*************************************************************************************************
1533 
1534 
1535 
1536 
1537 //=================================================================================================
1538 //
1539 // GLOBAL FUNCTIONS
1540 //
1541 //=================================================================================================
1542 
1543 //*************************************************************************************************
1556 template< typename MT // Type of the dense matrix
1557  , typename OP > // Type of the reduction operation
1558 inline auto dmatreduce( const DenseMatrix<MT,false>& dm, OP op )
1559  -> DisableIf_t< DMatReduceExprHelper<MT,OP>::value, ElementType_t<MT> >
1560 {
1561  using CT = CompositeType_t<MT>;
1562  using ET = ElementType_t<MT>;
1563 
1564  const size_t M( (~dm).rows() );
1565  const size_t N( (~dm).columns() );
1566 
1567  if( M == 0UL || N == 0UL ) return ET{};
1568  if( M == 1UL && N == 1UL ) return (~dm)(0UL,0UL);
1569 
1570  CT tmp( ~dm );
1571 
1572  BLAZE_INTERNAL_ASSERT( tmp.rows() == M, "Invalid number of rows" );
1573  BLAZE_INTERNAL_ASSERT( tmp.columns() == N, "Invalid number of columns" );
1574 
1575  ET redux0{};
1576 
1577  {
1578  redux0 = tmp(0UL,0UL);
1579 
1580  for( size_t j=1UL; j<N; ++j ) {
1581  redux0 = op( redux0, tmp(0UL,j) );
1582  }
1583  }
1584 
1585  size_t i( 1UL );
1586 
1587  for( ; (i+2UL) <= M; i+=2UL )
1588  {
1589  ET redux1( tmp(i ,0UL) );
1590  ET redux2( tmp(i+1UL,0UL) );
1591 
1592  for( size_t j=1UL; j<N; ++j ) {
1593  redux1 = op( redux1, tmp(i ,j) );
1594  redux2 = op( redux2, tmp(i+1UL,j) );
1595  }
1596 
1597  redux1 = op( redux1, redux2 );
1598  redux0 = op( redux0, redux1 );
1599  }
1600 
1601  if( i < M )
1602  {
1603  ET redux1( tmp(i,0UL) );
1604 
1605  for( size_t j=1UL; j<N; ++j ) {
1606  redux1 = op( redux1, tmp(i,j) );
1607  }
1608 
1609  redux0 = op( redux0, redux1 );
1610  }
1611 
1612  return redux0;
1613 }
1615 //*************************************************************************************************
1616 
1617 
1618 //*************************************************************************************************
1631 template< typename MT // Type of the dense matrix
1632  , typename OP > // Type of the reduction operation
1633 inline auto dmatreduce( const DenseMatrix<MT,false>& dm, OP op )
1634  -> EnableIf_t< DMatReduceExprHelper<MT,OP>::value, ElementType_t<MT> >
1635 {
1636  using CT = CompositeType_t<MT>;
1637  using ET = ElementType_t<MT>;
1638 
1639  const size_t M( (~dm).rows() );
1640  const size_t N( (~dm).columns() );
1641 
1642  if( M == 0UL || N == 0UL ) return ET{};
1643 
1644  CT tmp( ~dm );
1645 
1646  BLAZE_INTERNAL_ASSERT( tmp.rows() == M, "Invalid number of rows" );
1647  BLAZE_INTERNAL_ASSERT( tmp.columns() == N, "Invalid number of columns" );
1648 
1649  constexpr size_t SIMDSIZE = SIMDTrait<ET>::size;
1650 
1651  alignas( AlignmentOf_v<ET> ) ET array1[SIMDSIZE];
1652  alignas( AlignmentOf_v<ET> ) ET array2[SIMDSIZE];
1653  alignas( AlignmentOf_v<ET> ) ET array3[SIMDSIZE];
1654  alignas( AlignmentOf_v<ET> ) ET array4[SIMDSIZE];
1655 
1656  ET redux{};
1657 
1658  if( N >= SIMDSIZE )
1659  {
1660  const size_t jpos( N & size_t(-SIMDSIZE) );
1661  BLAZE_INTERNAL_ASSERT( ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1662 
1663  SIMDTrait_t<ET> xmm1;
1664 
1665  {
1666  xmm1 = tmp.load(0UL,0UL);
1667  size_t j( SIMDSIZE );
1668 
1669  for( ; j<jpos; j+=SIMDSIZE ) {
1670  xmm1 = op( xmm1, tmp.load(0UL,j) );
1671  }
1672 
1673  if( jpos < N )
1674  {
1675  storea( array1, xmm1 );
1676 
1677  for( ; j<N; ++j ) {
1678  array1[0UL] = op( array1[0UL], tmp(0UL,j) );
1679  }
1680 
1681  xmm1 = loada( array1 );
1682  }
1683  }
1684 
1685  size_t i( 1UL );
1686 
1687  for( ; (i+4UL) <= M; i+=4UL )
1688  {
1689  xmm1 = op( xmm1, tmp.load(i,0UL) );
1690  SIMDTrait_t<ET> xmm2( tmp.load(i+1UL,0UL) );
1691  SIMDTrait_t<ET> xmm3( tmp.load(i+2UL,0UL) );
1692  SIMDTrait_t<ET> xmm4( tmp.load(i+3UL,0UL) );
1693  size_t j( SIMDSIZE );
1694 
1695  for( ; j<jpos; j+=SIMDSIZE ) {
1696  xmm1 = op( xmm1, tmp.load(i ,j) );
1697  xmm2 = op( xmm2, tmp.load(i+1UL,j) );
1698  xmm3 = op( xmm3, tmp.load(i+2UL,j) );
1699  xmm4 = op( xmm4, tmp.load(i+3UL,j) );
1700  }
1701 
1702  if( jpos < N )
1703  {
1704  storea( array1, xmm1 );
1705  storea( array2, xmm2 );
1706  storea( array3, xmm3 );
1707  storea( array4, xmm4 );
1708 
1709  for( ; j<N; ++j ) {
1710  array1[0UL] = op( array1[0UL], tmp(i ,j) );
1711  array2[0UL] = op( array2[0UL], tmp(i+1UL,j) );
1712  array3[0UL] = op( array3[0UL], tmp(i+2UL,j) );
1713  array4[0UL] = op( array4[0UL], tmp(i+3UL,j) );
1714  }
1715 
1716  xmm1 = loada( array1 );
1717  xmm2 = loada( array2 );
1718  xmm3 = loada( array3 );
1719  xmm4 = loada( array4 );
1720  }
1721 
1722  xmm1 = op( xmm1, xmm2 );
1723  xmm3 = op( xmm3, xmm4 );
1724  xmm1 = op( xmm1, xmm3 );
1725  }
1726 
1727  if( i+2UL <= M )
1728  {
1729  xmm1 = op( xmm1, tmp.load(i,0UL) );
1730  SIMDTrait_t<ET> xmm2( tmp.load(i+1UL,0UL) );
1731  size_t j( SIMDSIZE );
1732 
1733  for( ; j<jpos; j+=SIMDSIZE ) {
1734  xmm1 = op( xmm1, tmp.load(i ,j) );
1735  xmm2 = op( xmm2, tmp.load(i+1UL,j) );
1736  }
1737 
1738  if( jpos < N )
1739  {
1740  storea( array1, xmm1 );
1741  storea( array2, xmm2 );
1742 
1743  for( ; j<N; ++j ) {
1744  array1[0UL] = op( array1[0UL], tmp(i ,j) );
1745  array2[0UL] = op( array2[0UL], tmp(i+1UL,j) );
1746  }
1747 
1748  xmm1 = loada( array1 );
1749  xmm2 = loada( array2 );
1750  }
1751 
1752  xmm1 = op( xmm1, xmm2 );
1753 
1754  i += 2UL;
1755  }
1756 
1757  if( i < M )
1758  {
1759  xmm1 = op( xmm1, tmp.load(i,0UL) );
1760  size_t j( SIMDSIZE );
1761 
1762  for( ; j<jpos; j+=SIMDSIZE ) {
1763  xmm1 = op( xmm1, tmp.load(i,j) );
1764  }
1765 
1766  if( jpos < N )
1767  {
1768  storea( array1, xmm1 );
1769 
1770  for( ; j<N; ++j ) {
1771  array1[0] = op( array1[0], tmp(i,j) );
1772  }
1773 
1774  xmm1 = loada( array1 );
1775  }
1776  }
1777 
1778  redux = reduce( xmm1, op );
1779  }
1780  else
1781  {
1782  {
1783  redux = tmp(0UL,0UL);
1784  for( size_t j=1UL; j<N; ++j ) {
1785  redux = op( redux, tmp(0UL,j) );
1786  }
1787  }
1788  for( size_t i=1UL; i<M; ++i ) {
1789  for( size_t j=0UL; j<N; ++j ) {
1790  redux = op( redux, tmp(i,j) );
1791  }
1792  }
1793  }
1794 
1795  return redux;
1796 }
1798 //*************************************************************************************************
1799 
1800 
1801 //*************************************************************************************************
1813 template< typename MT > // Type of the dense matrix
1814 inline auto dmatreduce( const DenseMatrix<MT,false>& dm, Add /*op*/ )
1815  -> EnableIf_t< DMatReduceExprHelper<MT,Add>::value, ElementType_t<MT> >
1816 {
1817  using CT = CompositeType_t<MT>;
1818  using ET = ElementType_t<MT>;
1819 
1820  const size_t M( (~dm).rows() );
1821  const size_t N( (~dm).columns() );
1822 
1823  if( M == 0UL || N == 0UL ) return ET{};
1824 
1825  CT tmp( ~dm );
1826 
1827  BLAZE_INTERNAL_ASSERT( tmp.rows() == M, "Invalid number of rows" );
1828  BLAZE_INTERNAL_ASSERT( tmp.columns() == N, "Invalid number of columns" );
1829 
1830  constexpr bool remainder( !usePadding || !IsPadded_v< RemoveReference_t<CT> > );
1831  constexpr size_t SIMDSIZE = SIMDTrait<ET>::size;
1832 
1833  ET redux{};
1834 
1835  if( !remainder || N >= SIMDSIZE )
1836  {
1837  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
1838  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1839 
1840  SIMDTrait_t<ET> xmm1;
1841  size_t i( 0UL );
1842 
1843  for( ; (i+4UL) <= M; i+=4UL )
1844  {
1845  xmm1 += tmp.load(i,0UL);
1846  SIMDTrait_t<ET> xmm2( tmp.load(i+1UL,0UL) );
1847  SIMDTrait_t<ET> xmm3( tmp.load(i+2UL,0UL) );
1848  SIMDTrait_t<ET> xmm4( tmp.load(i+3UL,0UL) );
1849  size_t j( SIMDSIZE );
1850 
1851  for( ; j<jpos; j+=SIMDSIZE ) {
1852  xmm1 += tmp.load(i ,j);
1853  xmm2 += tmp.load(i+1UL,j);
1854  xmm3 += tmp.load(i+2UL,j);
1855  xmm4 += tmp.load(i+3UL,j);
1856  }
1857  for( ; remainder && j<N; ++j ) {
1858  redux += tmp(i ,j);
1859  redux += tmp(i+1UL,j);
1860  redux += tmp(i+2UL,j);
1861  redux += tmp(i+3UL,j);
1862  }
1863 
1864  xmm1 += xmm2;
1865  xmm3 += xmm4;
1866  xmm1 += xmm3;
1867  }
1868 
1869  if( i+2UL <= M )
1870  {
1871  xmm1 += tmp.load(i,0UL);
1872  SIMDTrait_t<ET> xmm2( tmp.load(i+1UL,0UL) );
1873  size_t j( SIMDSIZE );
1874 
1875  for( ; j<jpos; j+=SIMDSIZE ) {
1876  xmm1 += tmp.load(i ,j);
1877  xmm2 += tmp.load(i+1UL,j);
1878  }
1879  for( ; remainder && j<N; ++j ) {
1880  redux += tmp(i ,j);
1881  redux += tmp(i+1UL,j);
1882  }
1883 
1884  xmm1 += xmm2;
1885 
1886  i += 2UL;
1887  }
1888 
1889  if( i < M )
1890  {
1891  xmm1 += tmp.load(i,0UL);
1892  size_t j( SIMDSIZE );
1893 
1894  for( ; j<jpos; j+=SIMDSIZE ) {
1895  xmm1 += tmp.load(i,j);
1896  }
1897  for( ; remainder && j<N; ++j ) {
1898  redux += tmp(i,j);
1899  }
1900  }
1901 
1902  redux += sum( xmm1 );
1903  }
1904  else
1905  {
1906  for( size_t i=0UL; i<M; ++i ) {
1907  for( size_t j=0UL; j<N; ++j ) {
1908  redux += tmp(i,j);
1909  }
1910  }
1911  }
1912 
1913  return redux;
1914 
1915 }
1917 //*************************************************************************************************
1918 
1919 
1920 //*************************************************************************************************
1931 template< typename MT > // Type of the dense matrix
1932 inline auto dmatreduce( const DenseMatrix<MT,false>& dm, Min /*op*/ )
1933  -> EnableIf_t< IsUniform_v<MT>, ElementType_t<MT> >
1934 {
1935  return (~dm)(0UL,0UL);
1936 }
1938 //*************************************************************************************************
1939 
1940 
1941 //*************************************************************************************************
1952 template< typename MT > // Type of the dense matrix
1953 inline auto dmatreduce( const DenseMatrix<MT,false>& dm, Max /*op*/ )
1954  -> EnableIf_t< IsUniform_v<MT>, ElementType_t<MT> >
1955 {
1956  return (~dm)(0UL,0UL);
1957 }
1959 //*************************************************************************************************
1960 
1961 
1962 //*************************************************************************************************
1975 template< typename MT // Type of the dense matrix
1976  , typename OP > // Type of the reduction operation
1977 inline ElementType_t<MT> dmatreduce( const DenseMatrix<MT,true>& dm, OP op )
1978 {
1979  return dmatreduce( trans( ~dm ), op );
1980 }
1982 //*************************************************************************************************
1983 
1984 
1985 //*************************************************************************************************
2014 template< typename MT // Type of the dense matrix
2015  , bool SO // Storage order
2016  , typename OP > // Type of the reduction operation
2017 inline decltype(auto) reduce( const DenseMatrix<MT,SO>& dm, OP op )
2018 {
2020 
2021  return dmatreduce( ~dm, op );
2022 }
2023 //*************************************************************************************************
2024 
2025 
2026 //*************************************************************************************************
2035 template< size_t RF // Reduction flag
2036  , typename MT // Type of the dense matrix
2037  , typename OP > // Type of the reduction operation
2038 inline const DMatReduceExpr<MT,OP,RF> reduce_backend( const DenseMatrix<MT,false>& dm, OP op )
2039 {
2040  using ReturnType = const DMatReduceExpr<MT,OP,RF>;
2041  return ReturnType( ~dm, op );
2042 }
2044 //*************************************************************************************************
2045 
2046 
2047 //*************************************************************************************************
2056 template< size_t RF // Reduction flag
2057  , typename MT // Type of the dense matrix
2058  , typename OP > // Type of the reduction operation
2059 inline decltype(auto) reduce_backend( const DenseMatrix<MT,true>& dm, OP op )
2060 {
2061  return trans( reduce<1UL-RF>( trans( ~dm ), op ) );
2062 }
2064 //*************************************************************************************************
2065 
2066 
2067 //*************************************************************************************************
2113 template< size_t RF // Reduction flag
2114  , typename MT // Type of the dense matrix
2115  , bool SO // Storage order
2116  , typename OP > // Type of the reduction operation
2117 inline decltype(auto) reduce( const DenseMatrix<MT,SO>& dm, OP op )
2118 {
2120 
2121  BLAZE_STATIC_ASSERT_MSG( RF < 2UL, "Invalid reduction flag" );
2122 
2123  return reduce_backend<RF>( ~dm, op );
2124 }
2125 //*************************************************************************************************
2126 
2127 
2128 //*************************************************************************************************
2145 template< typename MT // Type of the dense matrix
2146  , bool SO > // Storage order
2147 inline decltype(auto) sum( const DenseMatrix<MT,SO>& dm )
2148 {
2150 
2151  return reduce( ~dm, Add() );
2152 }
2153 //*************************************************************************************************
2154 
2155 
2156 //*************************************************************************************************
2189 template< size_t RF // Reduction flag
2190  , typename MT // Type of the dense matrix
2191  , bool SO > // Storage order
2192 inline decltype(auto) sum( const DenseMatrix<MT,SO>& dm )
2193 {
2195 
2196  return reduce<RF>( ~dm, Add() );
2197 }
2198 //*************************************************************************************************
2199 
2200 
2201 //*************************************************************************************************
2218 template< typename MT // Type of the dense matrix
2219  , bool SO > // Storage order
2220 inline decltype(auto) prod( const DenseMatrix<MT,SO>& dm )
2221 {
2223 
2224  return reduce( ~dm, Mult() );
2225 }
2226 //*************************************************************************************************
2227 
2228 
2229 //*************************************************************************************************
2262 template< size_t RF // Reduction flag
2263  , typename MT // Type of the dense matrix
2264  , bool SO > // Storage order
2265 inline decltype(auto) prod( const DenseMatrix<MT,SO>& dm )
2266 {
2268 
2269  return reduce<RF>( ~dm, Mult() );
2270 }
2271 //*************************************************************************************************
2272 
2273 
2274 //*************************************************************************************************
2292 template< typename MT // Type of the dense matrix
2293  , bool SO > // Storage order
2294 inline decltype(auto) min( const DenseMatrix<MT,SO>& dm )
2295 {
2297 
2298  return reduce( ~dm, Min() );
2299 }
2300 //*************************************************************************************************
2301 
2302 
2303 //*************************************************************************************************
2333 template< size_t RF // Reduction flag
2334  , typename MT // Type of the dense matrix
2335  , bool SO > // Storage order
2336 inline decltype(auto) min( const DenseMatrix<MT,SO>& dm )
2337 {
2339 
2340  return reduce<RF>( ~dm, Min() );
2341 }
2342 //*************************************************************************************************
2343 
2344 
2345 //*************************************************************************************************
2363 template< typename MT // Type of the dense matrix
2364  , bool SO > // Storage order
2365 inline decltype(auto) max( const DenseMatrix<MT,SO>& dm )
2366 {
2368 
2369  return reduce( ~dm, Max() );
2370 }
2371 //*************************************************************************************************
2372 
2373 
2374 //*************************************************************************************************
2404 template< size_t RF // Reduction flag
2405  , typename MT // Type of the dense matrix
2406  , bool SO > // Storage order
2407 inline decltype(auto) max( const DenseMatrix<MT,SO>& dm )
2408 {
2410 
2411  return reduce<RF>( ~dm, Max() );
2412 }
2413 //*************************************************************************************************
2414 
2415 } // namespace blaze
2416 
2417 #endif
ElementType_t< MT > ET
Element type of the dense matrix expression.
Definition: DMatReduceExpr.h:134
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Header file for the blaze::checked and blaze::unchecked instances.
bool operator>(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DMatReduceExpr.h:974
ConstIterator(Operand dm, size_t index, OP op)
Constructor for the ConstIterator class.
Definition: DMatReduceExpr.h:852
Header file for the HasLoad type trait.
DMatReduceExpr(const MT &dm, OP op) noexcept
Constructor for the DMatReduceExpr class.
Definition: DMatReduceExpr.h:182
Header file for basic type definitions.
ElementType * PointerType
Pointer return type.
Definition: DMatReduceExpr.h:833
Header file for the Add functor.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatReduceExpr.h:1183
Header file for the MatReduceExpr base class.
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
SIMDTrait_t< ElementType > SIMDType
Resulting SIMD element type.
Definition: DMatReduceExpr.h:811
Header file for the serial shim.
Base class for all matrix reduction expression templates.The MatReduceExpr class serves as a tag for ...
Definition: MatReduceExpr.h:67
ResultType_t< MT > RT
Result type of the dense matrix expression.
Definition: DMatReduceExpr.h:133
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatReduceExpr.h:264
Header file for the IsSame and IsStrictlySame type traits.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
BLAZE_DEVICE_CALLABLE const ConstIterator operator++(int)
Post-increment operator.
Definition: DMatReduceExpr.h:899
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatReduceExpr.h:159
Expression object for row-wise row-major dense matrix reduction operations.This specialization of the...
Definition: DMatReduceExpr.h:765
BLAZE_DEVICE_CALLABLE ConstIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DMatReduceExpr.h:877
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_t alias declaration provid...
Definition: SIMDTrait.h:315
decltype(auto) prod(const DenseMatrix< MT, SO > &dm)
Reduces the given dense matrix by means of multiplication.
Definition: DMatReduceExpr.h:2220
Header file for the DenseVector base class.
Generic wrapper for the addition operator.
Definition: Add.h:83
PointerType pointer
Pointer return type.
Definition: DMatReduceExpr.h:840
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: DMatReduceExpr.h:1096
Header file for the Computation base class.
ResultType_t< MT > RT
Result type of the dense matrix expression.
Definition: DMatReduceExpr.h:771
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatReduceExpr.h:284
#define BLAZE_STATIC_ASSERT_MSG(expr, msg)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:123
OP Operation
Data type of the custom unary operation.
Definition: DMatReduceExpr.h:165
BLAZE_DEVICE_CALLABLE const ConstIterator operator--(int)
Post-decrement operator.
Definition: DMatReduceExpr.h:920
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DMatReduceExpr.h:810
Header file for the reduce trait.
friend const ConstIterator operator-(const ConstIterator &it, size_t dec)
Subtraction between a ConstIterator and an integral value.
Definition: DMatReduceExpr.h:1043
DMatReduceExpr(const MT &dm, OP op) noexcept
Constructor for the DMatReduceExpr class.
Definition: DMatReduceExpr.h:1071
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Expression object for column-wise row-major dense matrix reduction operations.This specialization of ...
Definition: DMatReduceExpr.h:127
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:220
size_t index_
Index to the current matrix row.
Definition: DMatReduceExpr.h:1051
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatReduceExpr.h:812
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DMatReduceExpr.h:1007
Constraint on the transpose flag of vector types.
bool operator<(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DMatReduceExpr.h:963
Base template for row-major dense matrix partial reduction operations.The DMatReduceExpr class repres...
Definition: DMatReduceExpr.h:105
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatReduceExpr.h:1173
Constraint on the data type.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: DMatReduceExpr.h:194
decltype(auto) reduce(const DenseMatrix< MT, SO > &dm, OP op)
Performs a custom reduction operation on the given dense matrix.
Definition: DMatReduceExpr.h:2017
Header file for the DisableIf class template.
Header file for the IsUniform type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
Compile time assertion.
ConstIterator begin() const
Returns an iterator to the first non-zero element of the dense vector.
Definition: DMatReduceExpr.h:1109
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: DMatReduceExpr.h:1083
decltype(auto) operator *(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9091
BLAZE_DEVICE_CALLABLE ConstIterator & operator--()
Pre-decrement operator.
Definition: DMatReduceExpr.h:909
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DMatReduceExpr.h:941
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatReduceExpr.h:155
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
decltype(auto) sum(const DenseMatrix< MT, SO > &dm)
Reduces the given dense matrix by means of addition.
Definition: DMatReduceExpr.h:2147
Header file for the Mult functor.
Header file for the DenseMatrix base class.
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: DMatReduceExpr.h:1129
Header file for all SIMD functionality.
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
Operation op_
The reduction operation.
Definition: DMatReduceExpr.h:1201
Operation operation() const
Returns a copy of the reduction operation.
Definition: DMatReduceExpr.h:1149
bool operator>=(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DMatReduceExpr.h:996
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
ReduceTrait_t< RT, OP, rowwise > ResultType
Result type for expression template evaluations.
Definition: DMatReduceExpr.h:808
bool operator<=(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DMatReduceExpr.h:985
Constraint on the data type.
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
Constraint on the data type.
ReferenceType reference
Reference return type.
Definition: DMatReduceExpr.h:841
Header file for the EnableIf class template.
Header file for the IsPadded type trait.
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatReduceExpr.h:274
ReduceTrait_t< RT, OP, columnwise > ResultType
Result type for expression template evaluations.
Definition: DMatReduceExpr.h:154
If_t< useAssign, const ResultType, const DMatReduceExpr & > CompositeType
Data type for composite expression templates.
Definition: DMatReduceExpr.h:815
If_t< IsExpression_v< MT >, const MT, const MT & > Operand
Composite type of the left-hand side dense matrix expression.
Definition: DMatReduceExpr.h:162
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: DMatReduceExpr.h:207
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: DMatReduceExpr.h:952
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: DMatReduceExpr.h:220
Header file for the IsSIMDEnabled type trait.
constexpr size_t columnwise
Reduction flag for column-wise reduction operations.
Definition: ReductionFlag.h:90
BLAZE_DEVICE_CALLABLE ConstIterator & operator++()
Pre-increment operator.
Definition: DMatReduceExpr.h:888
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
typename ReduceTrait< T, OP, RF... >::Type ReduceTrait_t
Auxiliary alias declaration for the ReduceTrait class template.The ReduceTrait_t alias declaration pr...
Definition: ReduceTrait.h:173
Operand dm_
Dense matrix of the reduction expression.
Definition: DMatReduceExpr.h:1050
constexpr bool IsPadded_v
Auxiliary variable template for the IsPadded type trait.The IsPadded_v variable template provides a c...
Definition: IsPadded.h:134
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
Generic wrapper for the max() function.
Definition: Max.h:80
ElementType_t< MT > ET
Element type of the dense matrix expression.
Definition: DMatReduceExpr.h:772
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
Operand dm_
Dense matrix of the reduction expression.
Definition: DMatReduceExpr.h:291
friend const ConstIterator operator+(size_t inc, const ConstIterator &it)
Addition between an integral value and a ConstIterator.
Definition: DMatReduceExpr.h:1031
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
Operand dm_
Dense matrix of the reduction expression.
Definition: DMatReduceExpr.h:1200
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DMatReduceExpr.h:831
Header file for all forward declarations for expression class templates.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatReduceExpr.h:1161
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DMatReduceExpr.h:156
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Operation op_
The reduction operation.
Definition: DMatReduceExpr.h:292
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Operand operand() const noexcept
Returns the dense matrix operand.
Definition: DMatReduceExpr.h:1139
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
Header file for the HasMember type traits.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
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.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
If_t< IsExpression_v< MT >, const MT, const MT & > Operand
Composite type of the left-hand side dense matrix expression.
Definition: DMatReduceExpr.h:818
ValueType value_type
Type of the underlying elements.
Definition: DMatReduceExpr.h:839
Generic wrapper for the min() function.
Definition: Min.h:80
CompositeType_t< MT > CT
Composite type of the dense matrix expression.
Definition: DMatReduceExpr.h:135
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatReduceExpr.h:809
Header file for the Min functor.
IteratorCategory iterator_category
The iterator category.
Definition: DMatReduceExpr.h:838
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatReduceExpr.h:252
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type,...
Definition: DenseVector.h:61
OP op_
The reduction operation.
Definition: DMatReduceExpr.h:1052
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatReduceExpr.h:1193
Macro for CUDA compatibility.
constexpr size_t rowwise
Reduction flag for row-wise reduction operations.
Definition: ReductionFlag.h:70
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:198
friend const ConstIterator operator+(const ConstIterator &it, size_t inc)
Addition between a ConstIterator and an integral value.
Definition: DMatReduceExpr.h:1019
Generic wrapper for the multiplication operator.
Definition: Mult.h:80
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatReduceExpr.h:158
ElementType ValueType
Type of the underlying elements.
Definition: DMatReduceExpr.h:832
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:146
ElementType & ReferenceType
Reference return type.
Definition: DMatReduceExpr.h:834
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
Header file for the Max functor.
Operation operation() const
Returns a copy of the reduction operation.
Definition: DMatReduceExpr.h:240
SIMDTrait_t< ElementType > SIMDType
Resulting SIMD element type.
Definition: DMatReduceExpr.h:157
#define BLAZE_DEVICE_CALLABLE
Conditional macro that sets host and device attributes when compiled with CUDA.
Definition: HostDevice.h:94
BLAZE_DEVICE_CALLABLE ConstIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DMatReduceExpr.h:865
ConstIterator end() const
Returns an iterator just past the last non-zero element of the dense vector.
Definition: DMatReduceExpr.h:1119
Operand operand() const noexcept
Returns the dense matrix operand.
Definition: DMatReduceExpr.h:230
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:191
OP Operation
Data type of the custom unary operation.
Definition: DMatReduceExpr.h:821
Header file for the reduction flags.
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
decltype(auto) map(const DenseMatrix< MT1, SO > &lhs, const DenseMatrix< MT2, SO > &rhs, OP op)
Evaluates the given binary operation on each single element of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1121