Mentions légales du service

Skip to content
Snippets Groups Projects
Commit e98870ea authored by BRAMAS Berenger's avatar BRAMAS Berenger
Browse files

update hmat

parent 575e00ef
Branches
No related tags found
No related merge requests found
......@@ -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);
}
......
......@@ -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
}
}
......
......@@ -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
}
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment