From 6767fc83d8e889f92bc91f973d8907beda2b3c5b Mon Sep 17 00:00:00 2001 From: Libor Bakajsa <bakajsa.libor@seznam.cz> Date: Mon, 17 Nov 2014 20:40:31 +0100 Subject: [PATCH] COO format --- .../matrices/tnlCOOMatrix_impl.h | 338 ++++++++++++++++++ src/matrices/tnlCOOMatrix.h | 113 ++++++ 2 files changed, 451 insertions(+) create mode 100644 src/implementation/matrices/tnlCOOMatrix_impl.h create mode 100644 src/matrices/tnlCOOMatrix.h diff --git a/src/implementation/matrices/tnlCOOMatrix_impl.h b/src/implementation/matrices/tnlCOOMatrix_impl.h new file mode 100644 index 0000000000..a9cbdc15e4 --- /dev/null +++ b/src/implementation/matrices/tnlCOOMatrix_impl.h @@ -0,0 +1,338 @@ +#ifndef TNLCOOMATRIX_IMPL_H_ +#define TNLCOOMATRIX_IMPL_H_ + +#include <matrices/tnlCOOMatrix.h> +#include <core/vectors/tnlVector.h> +#include <core/vectors/tnlSharedVector.h> +#include <core/mfuncs.h> + +template< typename Real, + typename Device, + typename Index > +tnlCOOMatrix< Real, Device, Index >::tnlCOOMatrix() +:cudaWarpSize( 32 ), + numberOfUsedValues( 0 ) +{ +}; + +template< typename Real, + typename Device, + typename Index > +tnlString tnlCOOMatrix< Real, Device, Index >::getType() +{ + return tnlString("tnlCOOMatrix< ") + + tnlString(::getType< Real>()) + + tnlString(", ") + + Device::getDeviceType() + + tnlString(" >"); +} + +template< typename Real, + typename Device, + typename Index > +tnlString tnlCOOMatrix< Real, Device, Index >::getTypeVirtual() const +{ + return this->getType(); +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::setDimensions(const IndexType rows, const IndexType columns) +{ + if (!tnlSparseMatrix< Real, Device, Index >::setDimensions(rows, columns) || + !this->rowIndexes.setSize( this->values.getSize() ) ) + return false; + return true; +} + +template< typename Real, + typename Device, + typename Index > +void tnlCOOMatrix< Real, Device, Index >::setNumberOfUsedValues() +{ + for(IndexType i = 0; i < this->values.getSize(); i++) + { + if(this->values[ i ] == 0.0) + { + numberOfUsedValues = i; + break; + } + } +} + +template< typename Real, + typename Device, + typename Index > +Index tnlCOOMatrix< Real, Device, Index >::getNumberOfUsedValues() const +{ + return this->numberOfUsedValues; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::setRowLengths(const RowLengthsVector& rowLengths) +{ + IndexType size = 0; + for(IndexType row = 0; row < this->getRows(); row++) + size += rowLengths.getElement(row); + if( !this->rowIndexes.setSize(size) || + !this->columnIndexes.setSize(size) || + !this->values.setSize(size) ) + return false; + return true; +} + +template< typename Real, + typename Device, + typename Index > +void tnlCOOMatrix< Real, Device, Index >::getRowLengths(tnlVector< IndexType, DeviceType, IndexType >& rowLengthsVector) const +{ + for(IndexType row = 0; row < this->getRows(); row++) + rowLengthsVector.setElement(row, this->getRowLength(row)); +} + +template< typename Real, + typename Device, + typename Index > +Index tnlCOOMatrix< Real, Device, Index >::getRowLength( const IndexType row ) const +{ + IndexType rowLength = 0; + for(IndexType elementPtr = 0; elementPtr < this->values.getSize(); elementPtr++) + if(rowIndexes.getElement(elementPtr) == row) + rowLength++; + return rowLength; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::setElement( const IndexType row, + const IndexType column, + const RealType& value) +{ + return this->addElement( row, column, value, 1.0); +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::addElement( const IndexType row, + const IndexType column, + const RealType& value, + const RealType& thisElementMultiplicator ) +{ + tnlAssert( row >= 0 && row < this->rows && + column >= 0 && column < this->columns, + cerr << " row = " << row + << " column = " << column + << " this->rows = " << this->rows + << " this->columns = " << this->columns ); + + IndexType endPtr = this->getNumberOfUsedValues(); + for(IndexType elementPtr = 0; elementPtr < endPtr; elementPtr++) + { + if(this->rowIndexes[ elementPtr ] == row && this->columnIndexes[ elementPtr ] == column) + { + this->values.setElement( elementPtr, thisElementMultiplicator * this->values.getElement( elementPtr ) + value ); + return true; + } + } + if(endPtr < this->values.getSize()) + { + this->values.setElement( endPtr, thisElementMultiplicator * this->values.getElement( endPtr ) + value ); + this->rowIndexes.setElement( endPtr, row ); + this->columnIndexes.setElement( endPtr, column ); + this->numberOfUsedValues++; + return true; + } + return false; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::setRow(const IndexType row, + const IndexType* columns, + const RealType* values, + const IndexType numberOfElements) +{ + IndexType rowPtr = getNumberOfUsedValues(); + IndexType end = rowPtr + numberOfElements; + for(IndexType i = 0; i < numberOfElements; i++) + { + this->rowIndexes.setElement(rowPtr, row); + this->columnIndexes.setElement(rowPtr, columns[i]); + this->values.setElement(rowPtr, values[i]); + rowPtr++; + } + numberOfUsedValues += numberOfElements; + return true; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::addRow(const IndexType row, + const IndexType* columns, + const RealType* values, + const IndexType numberOfElements, + const RealType& thisElementMultiplicator ) +{ + // ma secist dva radky? popr. jak? + return false; +} + +template< typename Real, + typename Device, + typename Index > +Real tnlCOOMatrix< Real, Device, Index >::getElement(const IndexType row, + const IndexType column) const +{ + for (IndexType elementPtr = 0; elementPtr < this->getNumberOfUsedValues(); elementPtr++) + { + if (this->rowIndexes[elementPtr] == row && this->columnIndexes[elementPtr] == column) + return this->values.getElement(elementPtr); + } + return 0.0; +} + +template< typename Real, + typename Device, + typename Index > +void tnlCOOMatrix< Real, Device, Index >::getRow(const IndexType row, + IndexType* columns, + RealType* values) const +{ + IndexType i = 0; + for (IndexType elementPtr; elementPtr < this->getNumberOfUsedValues(); elementPtr++) + { + if (this->rowIndexes[elementPtr] == row) + { + columns[i] = this->columnIndexes.getElement(elementPtr); + values[i] = this->values.getElement(elementPtr); + i++; + } + } +} + +template< typename Real, + typename Device, + typename Index > +template< typename InVector, + typename OutVector > +void tnlCOOMatrix< Real, Device, Index >::vectorProduct(const InVector& inVector, + OutVector& outVector) const +{ + DeviceDependentCode::vectorProduct( *this, inVector, outVector ); +} + +template< typename Real, + typename Device, + typename Index > +template< typename InVector, + typename OutVector > +void tnlCOOMatrix< Real, Device, Index >::vectorProductHost(const InVector& inVector, + OutVector& outVector) const +{ + for(IndexType i = 0; i < this->values.getSize(); i++) + outVector[ this->rowIndexes.getElement(i) ] = this->values.getElement(i)*inVector[ this->columnIndexes.getElement(i) ]; +} + +template <> +class tnlCOOMatrixDeviceDependentCode< tnlHost > +{ + public: + typedef tnlHost Device; + + template< typename Real, + typename Index, + typename InVector, + typename OutVector > + static void vectorProduct( const tnlCOOMatrix< Real, Device, Index >& matrix, + const InVector& inVector, + OutVector& outVector) + { + matrix.vectorProductHost( inVector, outVector ); + } +}; + +template< typename Real, + typename Device, + typename Index > +template< typename Vector > +typename Vector::RealType tnlCOOMatrix< Real, Device, Index >::rowVectorProduct(const IndexType row, + const Vector& inVector) const +{ + RealType result = 0.0; + for(IndexType elementPtr = 0; elementPtr < this->values.getSize(); elementPtr++) + if(this->rowIndexes.getElement(elementPtr) == row) + { + result += this->values.getElement(elementPtr) * inVector[this->columnIndexes.getElement(elementPtr)]; + } + return result; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::save(tnlFile& file) const +{ + if (!tnlSparseMatrix< Real, Device, Index >::save(file) || + !this->rowIndexes.save(file)) + return false; + return true; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::load(tnlFile& file) +{ + if (!tnlSparseMatrix< Real, Device, Index >::load(file) || + !this->rowIndexes.load(file)) + return false; + return true; +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::save(const tnlString& fileName) const +{ + return tnlObject::save(fileName); +} + +template< typename Real, + typename Device, + typename Index > +bool tnlCOOMatrix< Real, Device, Index >::load(const tnlString& fileName) +{ + return tnlObject::load(fileName); +} + +template< typename Real, + typename Device, + typename Index > +void tnlCOOMatrix< Real, Device, Index >::print(ostream& str) const +{ + //zatim jsem to napsal takhle, kdyztak to pozdeji zmenim + for(IndexType elementPtr = 0; elementPtr < this->getNumberOfUsedValues(); elementPtr++) + { + str << "Row: " << this->rowIndexes.getElement(elementPtr) << "\t"; + str << "Col: " << this->columnIndexes.getElement(elementPtr) << " -> "; + str << this->values.getElement(elementPtr) << "\n"; + } +} + +template< typename Real, + typename Device, + typename Index > +void tnlCOOMatrix< Real, Device, Index >::reset() +{ + tnlSparseMatrix< Real, Device, Index >::reset(); + this->rowIndexes.reset(); +} + +#endif diff --git a/src/matrices/tnlCOOMatrix.h b/src/matrices/tnlCOOMatrix.h new file mode 100644 index 0000000000..c2426c50c2 --- /dev/null +++ b/src/matrices/tnlCOOMatrix.h @@ -0,0 +1,113 @@ +/* u addElement by nejspis melo byt realokovani pole jinak se asi prvek, ktery + * na danem miste nebyl pridat neda, leda by se puvodne naalokovalo pole o neco vetsi + */ +#ifndef TNLCOOMATRIX_H_ +#define TNLCOOMATRIX_H_ + +#include <matrices/tnlSparseMatrix.h> +#include <core/vectors/tnlVector.h> + +template< typename Device > +class tnlCOOMatrixDeviceDependentCode; + +template< typename Real, typename Device = tnlHost, typename Index = int > +class tnlCOOMatrix : public tnlSparseMatrix < Real, Device, Index > +{ +public: + + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef typename tnlSparseMatrix< RealType, DeviceType, IndexType >:: RowLengthsVector RowLengthsVector; + typedef tnlCOOMatrix< Real, Device, Index > ThisType; + typedef tnlCOOMatrix< Real, tnlHost, Index > HostType; + typedef tnlCOOMatrix< Real, tnlCuda, Index > CudaType; + + tnlCOOMatrix(); + + static tnlString getType(); + + tnlString getTypeVirtual() const; + + bool setDimensions(const IndexType rows, + const IndexType columns); + + void setNumberOfUsedValues(); + + IndexType getNumberOfUsedValues() const; + + bool setRowLengths(const RowLengthsVector& rowLengths); + + void getRowLengths(tnlVector< IndexType, DeviceType, IndexType >& rowLengths) const; + + IndexType getRowLength( const IndexType row ) const; + + bool setElement(const IndexType row, + const IndexType column, + const RealType& value); + + bool addElement(const IndexType row, + const IndexType column, + const RealType& value, + const RealType& thisElementMultiplicator = 1.0); + + bool setRow(const IndexType row, + const IndexType* columns, + const RealType* values, + const IndexType numberOfElements); + + bool addRow(const IndexType row, + const IndexType* columns, + const RealType* values, + const IndexType numberOfElements, + const RealType& thisElementMultiplicator = 1.0); + + Real getElement(const IndexType row, + const IndexType column) const; + + void getRow(const IndexType row, + IndexType* columns, + RealType* values) const; + + template< typename InVector, + typename OutVector > + void vectorProduct(const InVector& inVector, + OutVector& outVector) const; + + template< typename InVector, + typename OutVector > + void vectorProductHost(const InVector& inVector, + OutVector& outVector) const; + + template< typename Vector > + typename Vector::RealType rowVectorProduct(const IndexType row, + const Vector& inVector) const; + + bool save(tnlFile& file) const; + + bool load(tnlFile& file); + + bool save(const tnlString& fileName) const; + + bool load(const tnlString& fileName); + + // nejsem si jisty jestli dela to co ma + void print(ostream& str) const; + + void reset(); + + typedef tnlCOOMatrixDeviceDependentCode< DeviceType > DeviceDependentCode; + friend class tnlCOOMatrixDeviceDependentCode< DeviceType >; + +private: + + tnlVector< Index, Device, Index > rowIndexes; + + IndexType numberOfUsedValues; + + int cudaWarpSize; +}; + +#include <implementation/matrices/tnlCOOMatrix_impl.h> + +#endif -- GitLab