LAMA
|
00001 00034 #ifndef LAMA_CRTP_MATRIX_HPP_ 00035 #define LAMA_CRTP_MATRIX_HPP_ 00036 00037 // for dll_import 00038 #include <lama/config.hpp> 00039 00040 // base classes 00041 #include <lama/matrix/Matrix.hpp> 00042 00043 // others 00044 #include <lama/DenseVector.hpp> 00045 #include <lama/Scalar.hpp> 00046 00047 // tracing 00048 #include <lama/tracing.hpp> 00049 00050 // assert 00051 #include <lama/exception/LAMAAssert.hpp> 00052 00053 namespace lama 00054 { 00055 00069 template<class Derived, typename ValueType> 00070 class CRTPMatrix : public Matrix 00071 { 00072 public: 00073 00076 CRTPMatrix() : Matrix() 00077 { 00078 } 00079 00082 CRTPMatrix( const IndexType numRows, const IndexType numColumns ) 00083 00084 : Matrix( numRows, numColumns ) 00085 { 00086 } 00087 00090 CRTPMatrix( DistributionPtr rowDistribution, DistributionPtr colDistribution ) 00091 00092 : Matrix( rowDistribution, colDistribution ) 00093 { 00094 } 00095 00096 void matrixTimesVector ( Vector& result, 00097 const Scalar alpha, const Vector& x, 00098 const Scalar beta, const Vector& y ) const 00099 { 00100 LAMA_REGION( "MatrixTimesVector" ); 00101 00102 LAMA_LOG_INFO( logger, result << " = " 00103 << alpha << " * " << *this << " * " << x 00104 << " + " << beta << " * " << y ); 00105 00106 if ( &result == &y ) 00107 { 00108 LAMA_LOG_DEBUG( logger, "alias: result = y is well handled" ); 00109 } 00110 else if ( &result == &x ) 00111 { 00112 LAMA_THROWEXCEPTION( "alias: result = x is not handled, use temporary" ); 00113 } 00114 else 00115 { 00116 // we inherit the row distribution of this matrix to result 00117 00118 result.resize( getDistributionPtr() ); 00119 00120 // no more to check: result.size() == mNumRows, getDistirubtion() == result.getDistribution() 00121 } 00122 00123 LAMA_ASSERT_EQUAL( x.getDistribution(), getColDistribution() ); 00124 LAMA_ASSERT_EQUAL( y.getDistribution(), getDistribution() ); 00125 00126 const DenseVector<ValueType>* denseX = dynamic_cast<const DenseVector<ValueType>* > ( &x ); 00127 const DenseVector<ValueType>* denseY = dynamic_cast<const DenseVector<ValueType>* > ( &y ); 00128 DenseVector<ValueType>* denseResult = dynamic_cast<DenseVector<ValueType>* > ( &result ); 00129 00130 LAMA_ASSERT( denseX, x << ": must be DenseVector<" << Scalar::getType<ValueType>() << ">" ); 00131 00132 // Note: in case of beta == 0, we might skip this test 00133 00134 LAMA_ASSERT( denseY, y << ": must be DenseVector<" << Scalar::getType<ValueType>() << ">" ); 00135 00136 LAMA_ASSERT( denseResult, result << ": must be DenseVector<" << Scalar::getType<ValueType>() << ">" ); 00137 00138 static_cast<const Derived*>(this)->matrixTimesVectorImpl( *denseResult, alpha.getValue<ValueType>(), *denseX, 00139 beta.getValue<ValueType>(), *denseY ); 00140 } 00141 00142 protected: 00143 #ifndef LAMA_LOG_LEVEL_OFF 00144 using Matrix::logger; 00145 #endif 00146 }; 00147 00148 } 00149 00150 #endif // LAMA_CRTP_MATRIX_HPP_