diff --git a/Addons/HMat/Src/Blocks/FDenseBlock.hpp b/Addons/HMat/Src/Blocks/FDenseBlock.hpp index 2afaa94f7bc41370c80f67c2723d59822c1deca9..7bf42da75484f3cc143b5e3697a8318227fb239b 100644 --- a/Addons/HMat/Src/Blocks/FDenseBlock.hpp +++ b/Addons/HMat/Src/Blocks/FDenseBlock.hpp @@ -55,6 +55,17 @@ public: } }; + void resize(const int inNbRow, const int inNbCol){ + if(inNbRow != nbRows || + inNbCol != nbCols){ + clear(); + nbRows = inNbRow; + nbCols = inNbCol; + block = new FReal[nbRows*nbCols]; + } + memset(block, 0, sizeof(FReal)*nbRows*nbCols); + } + // dtor ~FDenseBlock(){ // Free memory @@ -69,6 +80,26 @@ public: block = 0; } + int getNbRows() const{ + return nbRows; + } + + int getNbCols() const{ + return nbCols; + } + + FReal getValue(const int idxRow, const int idxCol) const{ + return block[idxCol*nbRows+idxRow]; + } + + FReal& getValue(const int idxRow, const int idxCol) { + return block[idxCol*nbRows+idxRow]; + } + + void setValue(const int idxRow, const int idxCol, const FReal& val) { + block[idxCol*nbRows+idxRow] = val; + } + void gemv(FReal res[], const FReal vec[], const FReal scale = FReal(1.)) const { FBlas::gemva(nbRows, nbCols, scale, const_cast<FReal*>(block), const_cast<FReal*>(vec), res); } diff --git a/Addons/HMat/Src/Containers/FBlockPMapping.hpp b/Addons/HMat/Src/Containers/FBlockPMapping.hpp index cfdc94d3186d639ddae45ee6c7e2d8053d8c28f1..9f99da3bf989fe51b679a98863d963833ff8890e 100644 --- a/Addons/HMat/Src/Containers/FBlockPMapping.hpp +++ b/Addons/HMat/Src/Containers/FBlockPMapping.hpp @@ -29,31 +29,31 @@ #include <memory> -template <class FReal, class RowBlockClass, class ColBlockClass, class CoreCellClass > +template <class FReal, class CellClass > class FBlockPMapping { protected: - struct CellNode { + struct CellCNode { FBlockDescriptor infos; - CoreCellClass cell; + CellClass cell; }; - struct RowNode { + struct RowUNode { FBlockDescriptor infos; - RowBlockClass cell; + CellClass cell; }; - struct ColNode { + struct ColVNode { FBlockDescriptor infos; - ColBlockClass cell; + CellClass cell; }; const int dim; const int nbPartitions; const int nbCells; - CellNode* cells; - RowNode* rowBlocks; - ColNode* colBlocks; + CellCNode* cBlocks; + RowUNode* uRowBlocks; + ColVNode* vColBlocks; FBlockPMapping(const FBlockPMapping&) = delete; FBlockPMapping& operator=(const FBlockPMapping&) = delete; @@ -63,7 +63,7 @@ public: : dim(inDim), nbPartitions(inNbPartitions), nbCells(inNbPartitions*inNbPartitions), - cells(nullptr){ + cBlocks(nullptr){ FAssertLF(nbPartitions <= inDim); FAssertLF(1 <= nbPartitions); @@ -73,41 +73,41 @@ public: partitionsOffset[idxPart] = partitionsOffset[idxPart-1] + partitions[idxPart-1]; } - cells = new CellNode[nbCells]; + cBlocks = new CellCNode[nbCells]; for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - cells[idxPartCol*nbPartitions + idxPartRow].infos.row = partitionsOffset[idxPartRow]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.col = partitionsOffset[idxPartCol]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.nbRows = partitions[idxPartRow]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.nbCols = partitions[idxPartCol]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.level = 0; + cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.row = partitionsOffset[idxPartRow]; + cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.col = partitionsOffset[idxPartCol]; + cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.nbRows = partitions[idxPartRow]; + cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.nbCols = partitions[idxPartCol]; + cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.level = 0; } } - rowBlocks = new RowNode[nbPartitions]; + uRowBlocks = new RowUNode[nbPartitions]; for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - rowBlocks[idxPartRow].infos.row = partitionsOffset[idxPartRow]; - rowBlocks[idxPartRow].infos.col = 0; - rowBlocks[idxPartRow].infos.nbRows = partitions[idxPartRow]; - rowBlocks[idxPartRow].infos.nbCols = dim; - rowBlocks[idxPartRow].infos.level = 0; + uRowBlocks[idxPartRow].infos.row = partitionsOffset[idxPartRow]; + uRowBlocks[idxPartRow].infos.col = 0; + uRowBlocks[idxPartRow].infos.nbRows = partitions[idxPartRow]; + uRowBlocks[idxPartRow].infos.nbCols = dim; + uRowBlocks[idxPartRow].infos.level = 0; } - colBlocks = new ColNode[nbPartitions]; + vColBlocks = new ColVNode[nbPartitions]; for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - colBlocks[idxPartCol].infos.row = 0; - colBlocks[idxPartCol].infos.col = partitionsOffset[idxPartCol]; - colBlocks[idxPartCol].infos.nbRows = dim; - colBlocks[idxPartCol].infos.nbCols = partitions[idxPartCol]; - colBlocks[idxPartCol].infos.level = 0; + vColBlocks[idxPartCol].infos.row = 0; + vColBlocks[idxPartCol].infos.col = partitionsOffset[idxPartCol]; + vColBlocks[idxPartCol].infos.nbRows = dim; + vColBlocks[idxPartCol].infos.nbCols = partitions[idxPartCol]; + vColBlocks[idxPartCol].infos.level = 0; } } ~FBlockPMapping(){ - delete[] cells; - delete[] rowBlocks; - delete[] colBlocks; + delete[] cBlocks; + delete[] uRowBlocks; + delete[] vColBlocks; } int getNbBlocks() const { @@ -116,74 +116,74 @@ public: // Iterate blocks - CoreCellClass& getCell(const int idxRowPart, const int idxColPart){ - return cells[idxColPart*nbPartitions + idxRowPart].cell; + CellClass& getCBlock(const int idxRowPart, const int idxColPart){ + return cBlocks[idxColPart*nbPartitions + idxRowPart].cell; } - const CoreCellClass& getCell(const int idxRowPart, const int idxColPart) const { - return cells[idxColPart*nbPartitions + idxRowPart].cell; + const CellClass& getCBlock(const int idxRowPart, const int idxColPart) const { + return cBlocks[idxColPart*nbPartitions + idxRowPart].cell; } - const FBlockDescriptor& getCellInfo(const int idxRowPart, const int idxColPart) const { - return cells[idxColPart*nbPartitions + idxRowPart].infos; + const FBlockDescriptor& getCBlockInfo(const int idxRowPart, const int idxColPart) const { + return cBlocks[idxColPart*nbPartitions + idxRowPart].infos; } - void forAllBlocksDescriptor(std::function<void(const FBlockDescriptor&)> callback){ + void forAllCBlocksDescriptor(std::function<void(const FBlockDescriptor&)> callback){ for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - callback(cells[idxCell].infos); + callback(cBlocks[idxCell].infos); } } - void forAllCellBlocks(std::function<void(const FBlockDescriptor&, - RowBlockClass&, CoreCellClass&, ColBlockClass&)> callback){ + void forAllBlocks(std::function<void(const FBlockDescriptor&, + CellClass&, CellClass&, CellClass&)> callback){ for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - callback(cells[idxPartCol*nbPartitions + idxPartRow].infos, - cells[idxPartCol*nbPartitions + idxPartRow].cell, - rowBlocks[idxPartRow].cell, - colBlocks[idxPartCol].cell); + callback(cBlocks[idxPartCol*nbPartitions + idxPartRow].infos, + cBlocks[idxPartCol*nbPartitions + idxPartRow].cell, + uRowBlocks[idxPartRow].cell, + vColBlocks[idxPartCol].cell); } } } // Iterate row blocks - RowBlockClass& getRowCell(const int idxRowPart){ - return rowBlocks[idxRowPart].cell; + CellClass& getUBlock(const int idxRowPart){ + return uRowBlocks[idxRowPart].cell; } - const RowBlockClass& getRowCell(const int idxRowPart) const { - return rowBlocks[idxRowPart].cell; + const CellClass& getUBlock(const int idxRowPart) const { + return uRowBlocks[idxRowPart].cell; } - const FBlockDescriptor& getRowCellInfo(const int idxRowPart) const { - return rowBlocks[idxRowPart].infos; + const FBlockDescriptor& getUBlockInfo(const int idxRowPart) const { + return uRowBlocks[idxRowPart].infos; } // Iterate col blocks - ColBlockClass& getColCell(const int idxColPart){ - return colBlocks[idxColPart].cell; + CellClass& getVBlock(const int idxColPart){ + return vColBlocks[idxColPart].cell; } - const ColBlockClass& getColCell(const int idxColPart) const { - return colBlocks[idxColPart].cell; + const CellClass& getVBlock(const int idxColPart) const { + return vColBlocks[idxColPart].cell; } - const FBlockDescriptor& getColCellInfo(const int idxColPart) const { - return colBlocks[idxColPart].infos; + const FBlockDescriptor& getVBlockInfo(const int idxColPart) const { + return vColBlocks[idxColPart].infos; } // Operations void gemv(FReal res[], const FReal vec[]) const { for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ -// &res[cells[idxPartCol*nbPartitions + idxPartRow].infos.row], -// &vec[cells[idxPartCol*nbPartitions + idxPartRow].infos.col]) -// cells[idxPartCol*nbPartitions + idxPartRow].cell, -// rowBlocks[idxPartRow].cell, -// colBlocks[idxPartCol].cell; +// &res[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.row], +// &vec[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.col]) +// cBlocks[idxPartCol*nbPartitions + idxPartRow].cell, +// uRowBlocks[idxPartRow].cell, +// vColBlocks[idxPartCol].cell; } } } @@ -191,11 +191,11 @@ public: void gemm(FReal res[], const FReal mat[], const int nbRhs) const { for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ -// &res[cells[idxPartCol*nbPartitions + idxPartRow].infos.row], -// &vec[cells[idxPartCol*nbPartitions + idxPartRow].infos.col]) -// cells[idxPartCol*nbPartitions + idxPartRow].cell, -// rowBlocks[idxPartRow].cell, -// colBlocks[idxPartCol].cell; +// &res[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.row], +// &vec[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.col]) +// cBlocks[idxPartCol*nbPartitions + idxPartRow].cell, +// uRowBlocks[idxPartRow].cell, +// vColBlocks[idxPartCol].cell; // nbRhs, dim } } diff --git a/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp b/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp index 2b43578eeaba05d5dd366a9869b57a54b193b89b..7ae84e23630303b6fc45251eb8054853990d9b2a 100644 --- a/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp +++ b/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp @@ -81,7 +81,7 @@ int main(int argc, char** argv){ { typedef FDenseBlock<FReal> CellClass; - typedef FBlockPMapping<FReal, CellClass, CellClass, CellClass> GridClass; + typedef FBlockPMapping<FReal, CellClass> GridClass; std::unique_ptr<int[]> partitions(new int[nbPartitions]); { @@ -96,20 +96,64 @@ int main(int argc, char** argv){ GridClass grid(dim, partitions.get(), nbPartitions); // We iterate on the blocks + // V blocks cover all the rows, but only some columns (based on the clustering) for(int idxColBlock = 0 ; idxColBlock < nbPartitions ; ++idxColBlock){ - const MatrixClass::BlockDescriptor colBlock = matrix.getBlock(grid.getColCellInfo(idxColBlock)); - - // Store the result in grid.getColCell(idxColBlock) + const MatrixClass::BlockDescriptor colBlock = matrix.getBlock(grid.getVBlockInfo(idxColBlock)); + int rj = -1; + /// TODO HERE + /// Compute rj, and the resulting Vj blocks, + /// use the colBlock (some or all of its values) + + /// TODO END + // Store the result in grid.getVBlock(idxColBlock) + CellClass& Vj = grid.getVBlock(idxColBlock); + Vj.resize(rj, colBlock.getNbCols()); + for(int idxRow = 0 ; idxRow < Vj.getNbRows() ; ++idxRow){ + for(int idxCol = 0 ; idxCol < Vj.getNbCols() ; ++idxCol){ + /// TODO HERE + /// Fill Vj with the result + Vj.setValue(idxRow, idxCol, -1); + /// TODO END + } + } } + // U blocks cover all the columns, but only some rows (based on the clustering) for(int idxRowBlock = 0 ; idxRowBlock < nbPartitions ; ++idxRowBlock){ - const MatrixClass::BlockDescriptor rowBlock = matrix.getBlock(grid.getRowCellInfo(idxRowBlock)); - - // Store the result in grid.getRowCell(idxRowBlock) + const MatrixClass::BlockDescriptor rowBlock = matrix.getBlock(grid.getUBlockInfo(idxRowBlock)); + int ri = -1; + /// TODO HERE + /// Compute ri, and the resulting Ui blocks + /// use the rowBlock (some or all of its values) + + /// TODO END + // Store the result in grid.getUBlock(idxRowBlock) + CellClass& Ui = grid.getUBlock(idxRowBlock); + Ui.resize(rowBlock.getNbRows(), ri); + for(int idxRow = 0 ; idxRow < Ui.getNbRows() ; ++idxRow){ + for(int idxCol = 0 ; idxCol < Ui.getNbCols() ; ++idxCol){ + /// TODO HERE + /// Fill Vj with the result + Ui.setValue(idxRow, idxCol, -1); + /// TODO END + } + } } // Build the core part for(int idxColBlock = 0 ; idxColBlock < nbPartitions ; ++idxColBlock){ for(int idxRowBlock = 0 ; idxRowBlock < nbPartitions ; ++idxRowBlock){ - // Store the result in grid.getCell(idxRowBlock, idxColBlock) + const CellClass& Ui = grid.getUBlock(idxRowBlock); + const CellClass& Vj = grid.getVBlock(idxColBlock); + // Store the result in grid.getCBlock(idxRowBlock, idxColBlock) + CellClass& Cij = grid.getCBlock(idxRowBlock, idxColBlock); + Cij.resize(Vj.getNbRows(), Ui.getNbCols()); + for(int idxRow = 0 ; idxRow < Cij.getNbRows() ; ++idxRow){ + for(int idxCol = 0 ; idxCol < Cij.getNbCols() ; ++idxCol){ + /// TODO HERE + /// Fill Vj with the result + Cij.setValue(idxRow, idxCol, -1); + /// TODO END + } + } } }