35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
125 template<
typename MT1
127 class SMatDMatMultExpr :
public DenseMatrix< SMatDMatMultExpr<MT1,MT2>, false >
128 ,
private MatMatMultExpr
129 ,
private Computation
157 template<
typename T1,
typename T2,
typename T3 >
158 struct IsEvaluationRequired {
159 enum :
bool { value = ( evaluateLeft || evaluateRight ) };
169 template<
typename T1,
typename T2,
typename T3 >
170 struct UseVectorizedKernel {
172 !IsDiagonal<T3>::value &&
173 T1::simdEnabled && T3::simdEnabled &&
174 IsRowMajorMatrix<T1>::value &&
175 AreSIMDCombinable< ElementType_<T1>
177 , ElementType_<T3> >::value &&
178 HasSIMDAdd< ElementType_<T2>, ElementType_<T3> >::value &&
179 HasSIMDMult< ElementType_<T2>, ElementType_<T3> >::value };
190 template<
typename T1,
typename T2,
typename T3 >
191 struct UseOptimizedKernel {
193 !UseVectorizedKernel<T1,T2,T3>::value &&
194 !IsDiagonal<T3>::value &&
195 !IsResizable< ElementType_<T1> >::value &&
196 !IsResizable<ET1>::value };
206 template<
typename T1,
typename T2,
typename T3 >
207 struct UseDefaultKernel {
208 enum :
bool { value = !UseVectorizedKernel<T1,T2,T3>::value &&
209 !UseOptimizedKernel<T1,T2,T3>::value };
246 enum :
bool { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
247 !evaluateRight && MT2::smpAssignable };
302 :(
lhs_.columns() ) ) );
306 const size_t n(
end - begin );
324 inline ReturnType
at(
size_t i,
size_t j )
const {
325 if( i >=
lhs_.rows() ) {
328 if( j >=
rhs_.columns() ) {
340 inline size_t rows() const noexcept {
351 return rhs_.columns();
381 template<
typename T >
382 inline bool canAlias(
const T* alias )
const noexcept {
383 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
393 template<
typename T >
394 inline bool isAliased(
const T* alias )
const noexcept {
395 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
405 return rhs_.isAligned();
415 return (
rows() *
columns() >= SMP_SMATDMATMULT_THRESHOLD );
438 template<
typename MT
447 LT A(
serial( rhs.lhs_ ) );
448 RT B(
serial( rhs.rhs_ ) );
457 SMatDMatMultExpr::selectAssignKernel( ~lhs, A, B );
476 template<
typename MT3
480 selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
488 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
490 const size_t jtmp(
min( jj+block, B.columns() ) );
492 for(
size_t i=0UL; i<A.rows(); ++i )
494 ConstIterator element( A.begin(i) );
495 const ConstIterator
end( A.end(i) );
497 for( ; element!=
end; ++element )
499 const size_t i1( element->index() );
503 C(i,i1) = element->value() * B(i1,i1);
507 const size_t jbegin( ( IsUpper<MT5>::value )
508 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
510 const size_t jend( ( IsLower<MT5>::value )
511 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i1 : i1+1UL ) ) )
514 if( IsTriangular<MT5>::value && jbegin >= jend )
519 for(
size_t j=jbegin; j<jend; ++j ) {
521 C(i,j) = element->value() * B(i1,j);
523 C(i,j) += element->value() * B(i1,j);
547 template<
typename MT3
550 static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
551 selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
555 const size_t block( IsRowMajorMatrix<MT3>::value ? B.columns() : 64UL );
559 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
561 const size_t jtmp(
min( jj+block, B.columns() ) );
563 for(
size_t i=0UL; i<A.rows(); ++i )
565 const ConstIterator
end( A.end(i) );
566 ConstIterator element( A.begin(i) );
568 const size_t nonzeros( A.nonZeros(i) );
569 const size_t kpos( nonzeros &
size_t(-4) );
572 for(
size_t k=0UL; k<kpos; k+=4UL )
574 const size_t i1( element->index() );
575 const ET1 v1( element->value() );
577 const size_t i2( element->index() );
578 const ET1 v2( element->value() );
580 const size_t i3( element->index() );
581 const ET1 v3( element->value() );
583 const size_t i4( element->index() );
584 const ET1 v4( element->value() );
589 const size_t jbegin( ( IsUpper<MT5>::value )
590 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
592 const size_t jend( ( IsLower<MT5>::value )
593 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i4 : i4+1UL ) ) )
596 if( IsTriangular<MT5>::value && jbegin >= jend )
601 const size_t jnum( jend - jbegin );
602 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
605 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
606 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
607 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
608 C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
609 C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
611 for(
size_t j=jpos; j<jend; ++j ) {
612 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
616 for( ; element!=
end; ++element )
618 const size_t i1( element->index() );
619 const ET1 v1( element->value() );
621 const size_t jbegin( ( IsUpper<MT5>::value )
622 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
624 const size_t jend( ( IsLower<MT5>::value )
625 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i1 : i1+1UL ) ) )
628 if( IsTriangular<MT5>::value && jbegin >= jend )
633 const size_t jnum( jend - jbegin );
634 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
637 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
638 C(i,j ) += v1 * B(i1,j );
639 C(i,j+1UL) += v1 * B(i1,j+1UL);
640 C(i,j+2UL) += v1 * B(i1,j+2UL);
641 C(i,j+3UL) += v1 * B(i1,j+3UL);
643 for(
size_t j=jpos; j<jend; ++j ) {
644 C(i,j) += v1 * B(i1,j);
667 template<
typename MT3
670 static inline EnableIf_< UseVectorizedKernel<MT3,MT4,MT5> >
671 selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
675 const bool remainder( !IsPadded<MT3>::value || !IsPadded<MT5>::value );
679 for(
size_t i=0UL; i<A.rows(); ++i )
681 const ConstIterator
end( A.end(i) );
682 ConstIterator element( A.begin(i) );
684 const size_t nonzeros( A.nonZeros(i) );
685 const size_t kpos( nonzeros &
size_t(-4) );
688 for(
size_t k=0UL; k<kpos; k+=4UL )
690 const size_t i1( element->index() );
691 const ET1 v1( element->value() );
693 const size_t i2( element->index() );
694 const ET1 v2( element->value() );
696 const size_t i3( element->index() );
697 const ET1 v3( element->value() );
699 const size_t i4( element->index() );
700 const ET1 v4( element->value() );
705 const SIMDType xmm1(
set( v1 ) );
706 const SIMDType xmm2(
set( v2 ) );
707 const SIMDType xmm3(
set( v3 ) );
708 const SIMDType xmm4(
set( v4 ) );
710 const size_t jbegin( ( IsUpper<MT5>::value )
711 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-SIMDSIZE) )
713 const size_t jend( ( IsLower<MT5>::value )
714 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
718 const size_t jpos( remainder ? ( jend &
size_t(-SIMDSIZE) ) : jend );
719 BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos,
"Invalid end calculation" );
723 for( ; j<jpos; j+=SIMDSIZE ) {
724 C.store( i, j, C.load(i,j) + xmm1 * B.load(i1,j) + xmm2 * B.load(i2,j) + xmm3 * B.load(i3,j) + xmm4 * B.load(i4,j) );
726 for( ; remainder && j<jend; ++j ) {
727 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
731 for( ; element!=
end; ++element )
733 const size_t i1( element->index() );
734 const ET1 v1( element->value() );
736 const SIMDType xmm1(
set( v1 ) );
738 const size_t jbegin( ( IsUpper<MT5>::value )
739 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-SIMDSIZE) )
741 const size_t jend( ( IsLower<MT5>::value )
742 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
746 const size_t jpos( remainder ? ( jend &
size_t(-SIMDSIZE) ) : jend );
747 BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos,
"Invalid end calculation" );
751 for( ; j<jpos; j+=SIMDSIZE ) {
752 C.store( i, j, C.load(i,j) + xmm1 * B.load(i1,j) );
754 for( ; remainder && j<jend; ++j ) {
755 C(i,j) += v1 * B(i1,j);
776 template<
typename MT
778 friend inline void assign( SparseMatrix<MT,SO>& lhs,
const SMatDMatMultExpr& rhs )
782 typedef IfTrue_< SO, OppositeType, ResultType > TmpType;
794 const TmpType tmp(
serial( rhs ) );
813 template<
typename MT
815 friend inline void addAssign( DenseMatrix<MT,SO>& lhs,
const SMatDMatMultExpr& rhs )
822 LT A(
serial( rhs.lhs_ ) );
823 RT B(
serial( rhs.rhs_ ) );
832 SMatDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
851 template<
typename MT3
854 static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
855 selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
859 const size_t block( Or< IsRowMajorMatrix<MT3>, IsDiagonal<MT5> >::value ? B.columns() : 64UL );
861 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
863 const size_t jtmp(
min( jj+block, B.columns() ) );
865 for(
size_t i=0UL; i<A.rows(); ++i )
867 const ConstIterator
end( A.end(i) );
868 ConstIterator element( A.begin(i) );
870 for( ; element!=
end; ++element )
872 const size_t i1( element->index() );
874 if( IsDiagonal<MT5>::value )
876 C(i,i1) += element->value() * B(i1,i1);
880 const size_t jbegin( ( IsUpper<MT5>::value )
881 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
883 const size_t jend( ( IsLower<MT5>::value )
884 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i1 : i1+1UL ) ) )
887 if( IsTriangular<MT5>::value && jbegin >= jend )
892 const size_t jnum( jend - jbegin );
893 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
896 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
897 C(i,j ) += element->value() * B(i1,j );
898 C(i,j+1UL) += element->value() * B(i1,j+1UL);
899 C(i,j+2UL) += element->value() * B(i1,j+2UL);
900 C(i,j+3UL) += element->value() * B(i1,j+3UL);
902 for(
size_t j=jpos; j<jend; ++j ) {
903 C(i,j) += element->value() * B(i1,j);
927 template<
typename MT3
930 static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
931 selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
935 const size_t block( IsRowMajorMatrix<MT3>::value ? B.columns() : 64UL );
937 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
939 const size_t jtmp(
min( jj+block, B.columns() ) );
941 for(
size_t i=0UL; i<A.rows(); ++i )
943 const ConstIterator
end( A.end(i) );
944 ConstIterator element( A.begin(i) );
946 const size_t nonzeros( A.nonZeros(i) );
947 const size_t kpos( nonzeros &
size_t(-4) );
950 for(
size_t k=0UL; k<kpos; k+=4UL )
952 const size_t i1( element->index() );
953 const ET1 v1( element->value() );
955 const size_t i2( element->index() );
956 const ET1 v2( element->value() );
958 const size_t i3( element->index() );
959 const ET1 v3( element->value() );
961 const size_t i4( element->index() );
962 const ET1 v4( element->value() );
967 const size_t jbegin( ( IsUpper<MT5>::value )
968 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
970 const size_t jend( ( IsLower<MT5>::value )
971 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i4 : i4+1UL ) ) )
974 if( IsTriangular<MT5>::value && jbegin >= jend )
979 const size_t jnum( jend - jbegin );
980 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
983 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
984 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
985 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
986 C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
987 C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
989 for(
size_t j=jpos; j<jend; ++j ) {
990 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
994 for( ; element!=
end; ++element )
996 const size_t i1( element->index() );
997 const ET1 v1( element->value() );
999 const size_t jbegin( ( IsUpper<MT5>::value )
1000 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
1002 const size_t jend( ( IsLower<MT5>::value )
1003 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i1 : i1+1UL ) ) )
1006 if( IsTriangular<MT5>::value && jbegin >= jend )
1011 const size_t jnum( jend - jbegin );
1012 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1015 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1016 C(i,j ) += v1 * B(i1,j );
1017 C(i,j+1UL) += v1 * B(i1,j+1UL);
1018 C(i,j+2UL) += v1 * B(i1,j+2UL);
1019 C(i,j+3UL) += v1 * B(i1,j+3UL);
1021 for(
size_t j=jpos; j<jend; ++j ) {
1022 C(i,j) += v1 * B(i1,j);
1045 template<
typename MT3
1048 static inline EnableIf_< UseVectorizedKernel<MT3,MT4,MT5> >
1049 selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1053 const bool remainder( !IsPadded<MT3>::value || !IsPadded<MT5>::value );
1055 for(
size_t i=0UL; i<A.rows(); ++i )
1057 const ConstIterator
end( A.end(i) );
1058 ConstIterator element( A.begin(i) );
1060 const size_t nonzeros( A.nonZeros(i) );
1061 const size_t kpos( nonzeros &
size_t(-4) );
1064 for(
size_t k=0UL; k<kpos; k+=4UL )
1066 const size_t i1( element->index() );
1067 const ET1 v1( element->value() );
1069 const size_t i2( element->index() );
1070 const ET1 v2( element->value() );
1072 const size_t i3( element->index() );
1073 const ET1 v3( element->value() );
1075 const size_t i4( element->index() );
1076 const ET1 v4( element->value() );
1081 const SIMDType xmm1(
set( v1 ) );
1082 const SIMDType xmm2(
set( v2 ) );
1083 const SIMDType xmm3(
set( v3 ) );
1084 const SIMDType xmm4(
set( v4 ) );
1086 const size_t jbegin( ( IsUpper<MT5>::value )
1087 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-SIMDSIZE) )
1089 const size_t jend( ( IsLower<MT5>::value )
1090 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
1094 const size_t jpos( remainder ? ( jend &
size_t(-SIMDSIZE) ) : jend );
1095 BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos,
"Invalid end calculation" );
1099 for( ; j<jpos; j+=SIMDSIZE ) {
1100 C.store( i, j, C.load(i,j) + xmm1 * B.load(i1,j) + xmm2 * B.load(i2,j) + xmm3 * B.load(i3,j) + xmm4 * B.load(i4,j) );
1102 for( ; remainder && j<jend; ++j ) {
1103 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1107 for( ; element!=
end; ++element )
1109 const size_t i1( element->index() );
1110 const ET1 v1( element->value() );
1112 const SIMDType xmm1(
set( v1 ) );
1114 const size_t jbegin( ( IsUpper<MT5>::value )
1115 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-SIMDSIZE) )
1117 const size_t jend( ( IsLower<MT5>::value )
1118 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1122 const size_t jpos( remainder ? ( jend &
size_t(-SIMDSIZE) ) : jend );
1123 BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos,
"Invalid end calculation" );
1127 for( ; j<jpos; j+=SIMDSIZE ) {
1128 C.store( i, j, C.load(i,j) + xmm1 * B.load(i1,j) );
1130 for( ; remainder && j<jend; ++j ) {
1131 C(i,j) += v1 * B(i1,j);
1156 template<
typename MT
1158 friend inline void subAssign( DenseMatrix<MT,SO>& lhs,
const SMatDMatMultExpr& rhs )
1165 LT A(
serial( rhs.lhs_ ) );
1166 RT B(
serial( rhs.rhs_ ) );
1175 SMatDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1194 template<
typename MT3
1197 static inline EnableIf_< UseDefaultKernel<MT3,MT4,MT5> >
1198 selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1202 const size_t block( Or< IsRowMajorMatrix<MT3>, IsDiagonal<MT5> >::value ? B.columns() : 64UL );
1204 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
1206 const size_t jtmp(
min( jj+block, B.columns() ) );
1208 for(
size_t i=0UL; i<A.rows(); ++i )
1210 const ConstIterator
end( A.end(i) );
1211 ConstIterator element( A.begin(i) );
1213 for( ; element!=
end; ++element )
1215 const size_t i1( element->index() );
1217 if( IsDiagonal<MT5>::value )
1219 C(i,i1) -= element->value() * B(i1,i1);
1223 const size_t jbegin( ( IsUpper<MT5>::value )
1224 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
1226 const size_t jend( ( IsLower<MT5>::value )
1227 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i1 : i1+1UL ) ) )
1230 if( IsTriangular<MT5>::value && jbegin >= jend )
1235 const size_t jnum( jend - jbegin );
1236 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1239 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1240 C(i,j ) -= element->value() * B(i1,j );
1241 C(i,j+1UL) -= element->value() * B(i1,j+1UL);
1242 C(i,j+2UL) -= element->value() * B(i1,j+2UL);
1243 C(i,j+3UL) -= element->value() * B(i1,j+3UL);
1245 for(
size_t j=jpos; j<jend; ++j ) {
1246 C(i,j) -= element->value() * B(i1,j);
1270 template<
typename MT3
1273 static inline EnableIf_< UseOptimizedKernel<MT3,MT4,MT5> >
1274 selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1278 const size_t block( IsRowMajorMatrix<MT3>::value ? B.columns() : 64UL );
1280 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
1282 const size_t jtmp(
min( jj+block, B.columns() ) );
1284 for(
size_t i=0UL; i<A.rows(); ++i )
1286 const ConstIterator
end( A.end(i) );
1287 ConstIterator element( A.begin(i) );
1289 const size_t nonzeros( A.nonZeros(i) );
1290 const size_t kpos( nonzeros &
size_t(-4) );
1293 for(
size_t k=0UL; k<kpos; k+=4UL )
1295 const size_t i1( element->index() );
1296 const ET1 v1( element->value() );
1298 const size_t i2( element->index() );
1299 const ET1 v2( element->value() );
1301 const size_t i3( element->index() );
1302 const ET1 v3( element->value() );
1304 const size_t i4( element->index() );
1305 const ET1 v4( element->value() );
1310 const size_t jbegin( ( IsUpper<MT5>::value )
1311 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
1313 const size_t jend( ( IsLower<MT5>::value )
1314 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i4 : i4+1UL ) ) )
1317 if( IsTriangular<MT5>::value && jbegin >= jend )
1322 const size_t jnum( jend - jbegin );
1323 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1326 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1327 C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1328 C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1329 C(i,j+2UL) -= v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1330 C(i,j+3UL) -= v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1332 for(
size_t j=jpos; j<jend; ++j ) {
1333 C(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1337 for( ; element!=
end; ++element )
1339 const size_t i1( element->index() );
1340 const ET1 v1( element->value() );
1342 const size_t jbegin( ( IsUpper<MT5>::value )
1343 ?(
max( jj, ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) ) )
1345 const size_t jend( ( IsLower<MT5>::value )
1346 ?(
min( jtmp, ( IsStrictlyLower<MT5>::value ? i1 : i1+1UL ) ) )
1349 if( IsTriangular<MT5>::value && jbegin >= jend )
1354 const size_t jnum( jend - jbegin );
1355 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1358 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1359 C(i,j ) -= v1 * B(i1,j );
1360 C(i,j+1UL) -= v1 * B(i1,j+1UL);
1361 C(i,j+2UL) -= v1 * B(i1,j+2UL);
1362 C(i,j+3UL) -= v1 * B(i1,j+3UL);
1364 for(
size_t j=jpos; j<jend; ++j ) {
1365 C(i,j) -= v1 * B(i1,j);
1388 template<
typename MT3
1391 static inline EnableIf_< UseVectorizedKernel<MT3,MT4,MT5> >
1392 selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1396 const bool remainder( !IsPadded<MT3>::value || !IsPadded<MT5>::value );
1398 for(
size_t i=0UL; i<A.rows(); ++i )
1400 const ConstIterator
end( A.end(i) );
1401 ConstIterator element( A.begin(i) );
1403 const size_t nonzeros( A.nonZeros(i) );
1404 const size_t kpos( nonzeros &
size_t(-4) );
1407 for(
size_t k=0UL; k<kpos; k+=4UL )
1409 const size_t i1( element->index() );
1410 const ET1 v1( element->value() );
1412 const size_t i2( element->index() );
1413 const ET1 v2( element->value() );
1415 const size_t i3( element->index() );
1416 const ET1 v3( element->value() );
1418 const size_t i4( element->index() );
1419 const ET1 v4( element->value() );
1424 const SIMDType xmm1(
set( v1 ) );
1425 const SIMDType xmm2(
set( v2 ) );
1426 const SIMDType xmm3(
set( v3 ) );
1427 const SIMDType xmm4(
set( v4 ) );
1429 const size_t jbegin( ( IsUpper<MT5>::value )
1430 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-SIMDSIZE) )
1432 const size_t jend( ( IsLower<MT5>::value )
1433 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
1437 const size_t jpos( remainder ? ( jend &
size_t(-SIMDSIZE) ) : jend );
1438 BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos,
"Invalid end calculation" );
1442 for( ; j<jpos; j+=SIMDSIZE ) {
1443 C.store( i, j, C.load(i,j) - xmm1 * B.load(i1,j) - xmm2 * B.load(i2,j) - xmm3 * B.load(i3,j) - xmm4 * B.load(i4,j) );
1445 for( ; remainder && j<jend; ++j ) {
1446 C(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1450 for( ; element!=
end; ++element )
1452 const size_t i1( element->index() );
1453 const ET1 v1( element->value() );
1455 const SIMDType xmm1(
set( v1 ) );
1457 const size_t jbegin( ( IsUpper<MT5>::value )
1458 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-SIMDSIZE) )
1460 const size_t jend( ( IsLower<MT5>::value )
1461 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1465 const size_t jpos( remainder ? ( jend &
size_t(-SIMDSIZE) ) : jend );
1466 BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos,
"Invalid end calculation" );
1470 for( ; j<jpos; j+=SIMDSIZE ) {
1471 C.store( i, j, C.load(i,j) - xmm1 * B.load(i1,j) );
1473 for( ; remainder && j<jend; ++j ) {
1474 C(i,j) -= v1 * B(i1,j);
1509 template<
typename MT
1511 friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1549 template<
typename MT
1551 friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1556 typedef IfTrue_< SO, OppositeType, ResultType > TmpType;
1568 const TmpType tmp( rhs );
1590 template<
typename MT
1592 friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1635 template<
typename MT
1637 friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1722 template<
typename T1
1724 inline const SMatDMatMultExpr<T1,T2>
1748 template<
typename MT1,
typename MT2 >
1765 template<
typename MT1,
typename MT2 >
1782 template<
typename MT1,
typename MT2 >
1800 template<
typename MT1,
typename MT2 >
1802 :
public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1818 template<
typename MT1,
typename MT2 >
1820 :
public BoolConstant< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1836 template<
typename MT1,
typename MT2 >
1838 :
public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1839 , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1855 template<
typename MT1,
typename MT2 >
1857 :
public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1873 template<
typename MT1,
typename MT2 >
1875 :
public BoolConstant< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1891 template<
typename MT1,
typename MT2 >
1893 :
public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1894 , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1910 template<
typename MT1,
typename MT2,
typename VT >
1915 using Type = If_< And< IsSparseMatrix<MT1>, IsRowMajorMatrix<MT1>
1916 , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2>
1917 , IsDenseVector<VT>, IsColumnVector<VT> >
1918 , SMatDVecMultExprTrait_< MT1, DMatDVecMultExprTrait_<MT2,VT> >
1928 template<
typename MT1,
typename MT2,
typename VT >
1933 using Type = If_< And< IsSparseMatrix<MT1>, IsRowMajorMatrix<MT1>
1934 , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2>
1935 , IsSparseVector<VT>, IsColumnVector<VT> >
1936 , SMatDVecMultExprTrait_< MT1, DMatSVecMultExprTrait_<MT2,VT> >
1946 template<
typename VT,
typename MT1,
typename MT2 >
1951 using Type = If_< And< IsDenseVector<VT>, IsRowVector<VT>
1952 , IsSparseMatrix<MT1>, IsRowMajorMatrix<MT1>
1953 , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2> >
1954 , TDVecDMatMultExprTrait_< TDVecSMatMultExprTrait_<VT,MT1>, MT2 >
1964 template<
typename VT,
typename MT1,
typename MT2 >
1969 using Type = If_< And< IsSparseVector<VT>, IsRowVector<VT>
1970 , IsSparseMatrix<MT1>, IsRowMajorMatrix<MT1>
1971 , IsDenseMatrix<MT2>, IsRowMajorMatrix<MT2> >
1972 , TSVecDMatMultExprTrait_< TSVecSMatMultExprTrait_<VT,MT1>, MT2 >
1982 template<
typename MT1,
typename MT2,
bool AF >
1987 using Type = MultExprTrait_< SubmatrixExprTrait_<const MT1,AF>
1988 , SubmatrixExprTrait_<const MT2,AF> >;
1997 template<
typename MT1,
typename MT2 >
2002 using Type = MultExprTrait_< RowExprTrait_<const MT1>, MT2 >;
2011 template<
typename MT1,
typename MT2 >
2016 using Type = MultExprTrait_< MT1, ColumnExprTrait_<const MT2> >;
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatDMatMultExpr.h:421
Header file for the SMatDVecMultExprTrait class template.
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7800
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:87
Header file for basic type definitions.
CompositeType_< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:138
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseMatrix type trait.
Header file for the serial shim.
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatDMatMultExpr.h:404
#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
Header file for the ColumnExprTrait class template.
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:133
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatDMatMultExpr.h:232
If_< IsExpression< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:226
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:162
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
Header file for the IsRowVector type trait.
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:162
Header file for the TDVecSMatMultExprTrait class template.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:245
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Expression object for sparse matrix-dense matrix multiplications.The SMatDMatMultExpr class represent...
Definition: Forward.h:90
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
If_< IsExpression< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:229
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatDMatMultExpr.h:220
System settings for performance optimizations.
Header file for the TSVecSMatMultExprTrait class template.
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:126
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
SIMDTrait_< ElementType > SIMDType
Resulting SIMD element type.
Definition: SMatDMatMultExpr.h:221
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
SubvectorExprTrait_< VT, unaligned > subvector(Vector< VT, TF > &vector, size_t index, size_t size)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:152
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatDMatMultExpr.h:394
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
SMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatDMatMultExpr class.
Definition: SMatDMatMultExpr.h:261
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:83
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatDMatMultExpr.h:276
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatDMatMultExpr.h:382
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Header file for the Or class template.
ElementType_< RT2 > ET2
Element type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:136
#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
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
Header file for the Columns type trait.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for all SIMD functionality.
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatDMatMultExpr.h:217
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatDMatMultExpr.h:218
Header file for the DMatDVecMultExprTrait class template.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatDMatMultExpr.h:360
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:60
Header file for the IsTriangular type trait.
ResultType_< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:134
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:254
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatDMatMultExpr.h:219
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:109
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:126
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatDMatMultExpr.h:324
Header file for the IsSparseVector type trait.
Header file for the SubmatrixExprTrait class template.
#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
Header file for the HasSIMDMult type trait.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatDMatMultExpr.h:222
Header file for run time assertion macros.
Utility type for generic codes.
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: SMatDMatMultExpr.h:370
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:160
Header file for the reset shim.
SMatDMatMultExpr< MT1, MT2 > This
Type of this SMatDMatMultExpr instance.
Definition: SMatDMatMultExpr.h:216
Constraints on the storage order of matrix types.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatDMatMultExpr.h:422
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatDMatMultExpr.h:235
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
Header file for the IsDenseVector type trait.
ElementType_< RT1 > ET1
Element type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:135
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
Header file for the AreSIMDCombinable type trait.
Header file for the IsRowMajorMatrix type trait.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatDMatMultExpr.h:340
Header file for the IsComputation type trait class.
Header file for the TDVecDMatMultExprTrait class template.
Compile time logical or evaluation.The Or class template performs at compile time a logical or ('&&')...
Definition: Or.h:101
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
Header file for the IntegralConstant class template.
Header file for the TSVecDMatMultExprTrait class template.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:137
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatDMatMultExpr.h:223
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
Header file for the IsUpper type trait.
Header file for the DMatSVecMultExprTrait class template.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatDMatMultExpr.h:414
Header file for the IsColumnVector type trait.
Constraint on the data type.
Header file for the IsResizable type trait.
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, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatDMatMultExpr.h:350
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.