Commit 33aad35f authored by BRAMAS Berenger's avatar BRAMAS Berenger
Browse files

add a partition system and update test

parent dd9742df
......@@ -10,7 +10,7 @@
#include "../Utils/FHUtils.hpp"
#include <functional>
#include <memory>
template <class FReal, class LeafClass, class CellClass >
......@@ -92,6 +92,71 @@ public:
}
}
explicit FDiv2Bissection(const int inDim, const int inHeight,
const int partitions[], const int nbPartitions)
: dim(inDim), height(inHeight),
nbCells(0), cells(nullptr),
nbLeaves(0), leaves(nullptr),
totalNbBlocks(0){
FAssertLF(FMath::pow2(height) <= inDim);
FAssertLF(FMath::pow2(height-1) == nbPartitions);
int currentNbPartitions = nbPartitions;
std::unique_ptr<int[]> offsetUnknowns(new int[currentNbPartitions+1]);
offsetUnknowns[0] = 0;
for(int idxPartition = 1 ; idxPartition <= currentNbPartitions ; ++idxPartition){
offsetUnknowns[idxPartition] = offsetUnknowns[idxPartition-1] + partitions[idxPartition-1];
}
FAssertLF(offsetUnknowns[nbPartitions] == dim);
nbLeaves = FMath::pow2(height);
leaves = new LeafNode[nbLeaves];
totalNbBlocks += nbLeaves;
{
for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){
const int rowLeafNumber = ((idxLeaf/4)*2) + (idxLeaf&1?1:0);
const int colLeafNumber = ((idxLeaf/4)*2) + (idxLeaf&2?1:0);
leaves[idxLeaf].infos.row = offsetUnknowns[rowLeafNumber];
leaves[idxLeaf].infos.col = offsetUnknowns[colLeafNumber];
leaves[idxLeaf].infos.nbRows = offsetUnknowns[rowLeafNumber+1] - offsetUnknowns[rowLeafNumber];
leaves[idxLeaf].infos.nbCols = offsetUnknowns[colLeafNumber+1] - offsetUnknowns[colLeafNumber];
leaves[idxLeaf].infos.level = height-1;
}
}
cells = new CellNode*[height-1];
FSetToZeros(cells, height-1);
nbCells = new int[height-1];
FSetToZeros(nbCells, height-1);
for(int idxLevel = height-2 ; idxLevel >= 1 ; --idxLevel){
const int nbCellsAtLevel = FMath::pow2(idxLevel);
cells[idxLevel] = new CellNode[nbCellsAtLevel];
nbCells[idxLevel] = nbCellsAtLevel;
totalNbBlocks += nbCellsAtLevel;
const int nbCellsInDirection = nbCells[idxLevel];
FAssertLF(nbCellsInDirection == currentNbPartitions/2);
currentNbPartitions = nbCellsInDirection;
for(int idxPartition = 1 ; idxPartition <= currentNbPartitions ; ++idxPartition){
offsetUnknowns[idxPartition] = offsetUnknowns[idxPartition*2];
}
FAssertLF(offsetUnknowns[currentNbPartitions] == dim);
for(int idxCell = 0 ; idxCell < nbCellsAtLevel ; ++idxCell){
const int rowCellNumber = (idxCell&1? idxCell-1 : idxCell+1);
const int colCellNumner = idxCell;
cells[idxLevel][idxCell].infos.row = offsetUnknowns[rowCellNumber];
cells[idxLevel][idxCell].infos.col = offsetUnknowns[colCellNumner];
cells[idxLevel][idxCell].infos.nbRows = offsetUnknowns[rowCellNumber+1] - offsetUnknowns[rowCellNumber];
cells[idxLevel][idxCell].infos.nbCols = offsetUnknowns[colCellNumner+1] - offsetUnknowns[colCellNumner];
cells[idxLevel][idxCell].infos.level = idxLevel;
}
}
}
~FDiv2Bissection(){
for(int idxLevel = 0 ; idxLevel < height-1 ; ++idxLevel){
delete[] cells[idxLevel];
......
......@@ -46,6 +46,11 @@ public:
}
FSvgRect(const char inDirname[], const char inFilename[], const int inDim,
const int inSvgSize = 2048, const int inMargin = 50)
: FSvgRect((std::string(inDirname)+std::string(inFilename)).c_str(), inDim, inSvgSize, inMargin) {
}
~FSvgRect(){
fprintf(fsvg, "</svg>");
fclose(fsvg);
......
......@@ -9,10 +9,12 @@
#include "Utils/FParameters.hpp"
#include "Utils/FParameterNames.hpp"
#include <memory>
int main(int argc, char** argv){
static const FParameterNames SvgOutParam = {
{"-fout", "--out"} ,
"Svg output filename."
{"-fout", "--out", "-out"} ,
"Svg output directory."
};
static const FParameterNames DimParam = {
{"-N", "-nb", "-dim"} ,
......@@ -29,20 +31,42 @@ int main(int argc, char** argv){
const int dim = FParameters::getValue(argc, argv, DimParam.options, 100);
const int height = FParameters::getValue(argc, argv, HeightParam.options, 4);
const char* outputfile = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/example.svg");
const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/");
std::cout << "Config : dim = " << dim << "\n";
std::cout << "Config : height = " << height << "\n";
std::cout << "Config : outputfile = " << outputfile << "\n";
std::cout << "Config : outputdir = " << outputdir << "\n";
typedef double FReal;
typedef FDenseMatrix<FReal> LeafClass;
typedef FDenseMatrix<FReal> CellClass;
typedef FDiv2Bissection<FReal, LeafClass, CellClass> GridClass;
GridClass bissection(dim, height);
{
FSvgRect output(outputfile, dim);
GridClass bissection(dim, height);
FSvgRect output(outputdir, "classic", dim);
bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){
output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level);
});
}
{
const int nbPartitions = FMath::pow2(height-1);
std::unique_ptr<int[]> partitions(new int[nbPartitions]);
{
int nbValuesLeft = dim;
for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){
partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition))));
nbValuesLeft -= partitions[idxPartition];
}
partitions[nbPartitions-1] = nbValuesLeft;
}
GridClass bissection(dim, height, partitions.get(), nbPartitions);
FSvgRect output(outputdir, "partitioned", dim);
bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){
output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level);
......
......@@ -72,6 +72,35 @@ int main(int argc, char** argv){
std::cout << "Test Dense, Error = " << testDense << "\n";
}
{
typedef FDenseMatrix<FReal> LeafClass;
typedef FDenseMatrix<FReal> CellClass;
typedef FDiv2Bissection<FReal, LeafClass, CellClass> GridClass;
const int nbPartitions = FMath::pow2(height-1);
std::unique_ptr<int[]> partitions(new int[nbPartitions]);
{
int nbValuesLeft = dim;
for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){
partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition))));
nbValuesLeft -= partitions[idxPartition];
}
partitions[nbPartitions-1] = nbValuesLeft;
}
GridClass grid(dim, height, partitions.get(), nbPartitions);
grid.fillBlocks(matrix);
std::unique_ptr<FReal[]> resDense(new FReal[dim]);
FSetToZeros(resDense.get(), dim);
grid.gemv(resDense.get(), vec.get());
FMath::FAccurater<FReal> testDense(resTest.get(), resDense.get(), dim);
std::cout << "Test Dense with partitions, Error = " << testDense << "\n";
}
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment