Mise à jour terminée. Pour connaître les apports de la version 13.8.4 par rapport à notre ancienne version vous pouvez lire les "Release Notes" suivantes :
https://about.gitlab.com/releases/2021/02/11/security-release-gitlab-13-8-4-released/
https://about.gitlab.com/releases/2021/02/05/gitlab-13-8-3-released/

Commit 33a88b36 authored by BLANCHARD Pierre's avatar BLANCHARD Pierre
parents e3262e2e f60f896f
......@@ -18,15 +18,16 @@ OPTION( SCALFMM_ADDON_HMAT "Set to ON to build ScalFMM HMat interface" OFF )
# if ask to build addon
if(SCALFMM_ADDON_HMAT)
list(APPEND FUSE_LIST "SCOTCH")
if(NOT ENV{SCOTCH_LIB})
set(SCOTCH_NOT_FOUND $ENV{SCOTCH_LIB})
if(NOT SCOTCH_NOT_FOUND)
MESSAGE(STATUS " SCOTCH not found " )
else()
OPTION( SCALFMM_USE_SCOTCH "Set to ON to use scotch" ON )
if (SCALFMM_USE_SCOTCH)
include_directories($ENV{SCOTCH_INC})
SET(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};-L$ENV{SCOTCH_LIB};-lscotch;-lscotcherr")
endif()
endif
endif()
# first build lib scalfmmhmat
set(LIBRARY_OUTPUT_PATH ../lib/${CMAKE_BUILD_TYPE})
......
......@@ -222,7 +222,9 @@ public:
}
int getRank() const{
return rank;
}
};
#endif // FSVDBLOCK_HPP
......
......@@ -118,7 +118,7 @@ public:
free(croot);
}
void fillClusterTree(FClusterTree<FReal>* ctree){
void fillClusterTree(FClusterTree<FReal>* ctree) const {
int* permsOrigToNew = new int[dim];
int* permsNewToOrig = new int[dim];
......
......@@ -29,6 +29,19 @@ protected:
std::pair<int, int>* gclusters;
public:
static FReal GetDefaultRadius(const int inDim, const FReal inDistMat[]){
FReal avg = 0;
FReal min = std::numeric_limits<FReal>::max();
const FReal dimSquare = FReal(inDim*inDim);
for(int idxCol = 0 ; idxCol < inDim ; ++idxCol){
for(int idxRow = 0 ; idxRow < inDim ; ++idxRow){
avg += (inDistMat[idxCol*inDim + idxRow]/dimSquare);
min = (min < inDistMat[idxCol*inDim + idxRow]? min:inDistMat[idxCol*inDim + idxRow]);
}
}
return (avg+min) / FReal(2);
}
FGraphThreshold(const int inDim, const FReal inDistMat[], const FReal inTreshold)
: dim(inDim), treshold(inTreshold),
permutations(new int[dim]),
......@@ -62,85 +75,118 @@ public:
nbValuesUnderThreshold += (inDistMat[idxColReal*dim+ idxRowReal] < treshold && idxRowReal != idxColReal? 1 : 0);
}
}
FAssertLF(nbValuesUnderThreshold != 0);
// Base value for all array indexings
const SCOTCH_Num baseval = 0;
// Number of vertices in graph
const SCOTCH_Num vertnbr = sizeInterval;
// Number of arcs in graph. Since edges are represented by both of their ends,
// the number of edge data in the graph is twice the number of graph edges.
const SCOTCH_Num edgenbr = nbValuesUnderThreshold;// it is already symmetric
// Array of start indices in edgetab of vertex adjacency sub-arrays
SCOTCH_Num* verttab = new SCOTCH_Num[vertnbr+1];
SCOTCH_Num* vendtab = &verttab[1];
// edgetab[verttab[i]] to edgetab[vendtab[i] − 1]
SCOTCH_Num* edgetab = new SCOTCH_Num[edgenbr];
// Optional array, of size vertnbr, holding the integer load associated with every vertex.
SCOTCH_Num* velotab = nullptr;
// Optional array, of a size equal at least to (max i (vendtab[i]) − baseval), holding the integer load associated with every arc.
SCOTCH_Num* edlotab = nullptr;
SCOTCH_Num* vlbltab = nullptr;
verttab[0] = 0;
for(int idxCol = 0 ; idxCol < sizeInterval ; ++idxCol){
const int idxColReal = permutations[idxCol+currentCluster.first];
verttab[idxCol+1] = verttab[idxCol];
for(int idxRow = 0 ; idxRow < sizeInterval ; ++idxRow){
const int idxRowReal = permutations[idxRow+currentCluster.first];
if(inDistMat[idxColReal*dim+ idxRowReal] < treshold
&& idxColReal != idxRowReal){
edgetab[verttab[idxCol+1]] = idxRow;
verttab[idxCol+1] += 1;
if(nbValuesUnderThreshold != 0){
// Base value for all array indexings
const SCOTCH_Num baseval = 0;
// Number of vertices in graph
const SCOTCH_Num vertnbr = sizeInterval;
// Number of arcs in graph. Since edges are represented by both of their ends,
// the number of edge data in the graph is twice the number of graph edges.
const SCOTCH_Num edgenbr = nbValuesUnderThreshold;// it is already symmetric
// Array of start indices in edgetab of vertex adjacency sub-arrays
SCOTCH_Num* verttab = new SCOTCH_Num[vertnbr+1];
SCOTCH_Num* vendtab = &verttab[1];
// edgetab[verttab[i]] to edgetab[vendtab[i] − 1]
SCOTCH_Num* edgetab = new SCOTCH_Num[edgenbr];
// Optional array, of size vertnbr, holding the integer load associated with every vertex.
SCOTCH_Num* velotab = nullptr;
// Optional array, of a size equal at least to (max i (vendtab[i]) − baseval), holding the integer load associated with every arc.
SCOTCH_Num* edlotab = nullptr;
SCOTCH_Num* vlbltab = nullptr;
verttab[0] = 0;
for(int idxCol = 0 ; idxCol < sizeInterval ; ++idxCol){
const int idxColReal = permutations[idxCol+currentCluster.first];
verttab[idxCol+1] = verttab[idxCol];
for(int idxRow = 0 ; idxRow < sizeInterval ; ++idxRow){
const int idxRowReal = permutations[idxRow+currentCluster.first];
if(inDistMat[idxColReal*dim+ idxRowReal] < treshold
&& idxColReal != idxRowReal){
edgetab[verttab[idxCol+1]] = idxRow;
verttab[idxCol+1] += 1;
}
}
}
}
FAssertLF(verttab[vertnbr] == edgenbr);
SCOTCH_Graph grafdat;
FAssertLF(SCOTCH_graphInit(&grafdat) == 0);
FAssertLF(SCOTCH_graphBuild(&grafdat, baseval, vertnbr, verttab, vendtab,
velotab, vlbltab, edgenbr, edgetab, edlotab) == 0);
FAssertLF(SCOTCH_graphCheck(&grafdat) == 0);
SCOTCH_Strat straptr;
FAssertLF(SCOTCH_stratInit(&straptr) == 0);
//const SCOTCH_Num pwgtmax = std::numeric_limits<SCOTCH_Num>::max(); //maximum cluster vertex weight
//const double densmin = 0; // the minimum edge density
//const double bbalval = 0.2;// bipartition imbalance ratio
//SCOTCH_stratGraphClusterBuild (&straptr, SCOTCH_STRATDEFAULT, pwgtmax, densmin, bbalval);
const int partnbr = 2;
SCOTCH_Num* parttab = new SCOTCH_Num[vertnbr];
FAssertLF(SCOTCH_graphPart(&grafdat, partnbr, &straptr, parttab) == 0);
{
int idxLeft = 0;
int idxRight = sizeInterval-1;
while(idxLeft <= idxRight){
if(parttab[idxLeft] == 0){
idxLeft += 1;
FAssertLF(verttab[vertnbr] == edgenbr);
SCOTCH_Graph grafdat;
FAssertLF(SCOTCH_graphInit(&grafdat) == 0);
FAssertLF(SCOTCH_graphBuild(&grafdat, baseval, vertnbr, verttab, vendtab,
velotab, vlbltab, edgenbr, edgetab, edlotab) == 0);
FAssertLF(SCOTCH_graphCheck(&grafdat) == 0);
SCOTCH_Strat straptr;
FAssertLF(SCOTCH_stratInit(&straptr) == 0);
//const SCOTCH_Num pwgtmax = std::numeric_limits<SCOTCH_Num>::max(); //maximum cluster vertex weight
//const double densmin = 0; // the minimum edge density
//const double bbalval = 0.2;// bipartition imbalance ratio
//SCOTCH_stratGraphClusterBuild (&straptr, SCOTCH_STRATDEFAULT, pwgtmax, densmin, bbalval);
const int partnbr = 2;
SCOTCH_Num* parttab = new SCOTCH_Num[vertnbr];
FAssertLF(SCOTCH_graphPart(&grafdat, partnbr, &straptr, parttab) == 0);
{
int idxLeft = 0;
int idxRight = sizeInterval-1;
while(idxLeft <= idxRight){
if(parttab[idxLeft] == 0){
idxLeft += 1;
}
else if(parttab[idxRight] == 1){
idxRight -= 1;
}
else{
const int unk = parttab[idxLeft];
parttab[idxLeft] = parttab[idxRight];
parttab[idxRight] = unk;
const int unkPerm = permutations[idxLeft+currentCluster.first];
permutations[idxLeft+currentCluster.first] = permutations[idxRight+currentCluster.first];
permutations[idxRight+currentCluster.first] = unkPerm;
idxLeft += 1;
idxRight -= 1;
}
}
else if(parttab[idxRight] == 1){
idxRight -= 1;
// idxLeft is on the first 1
if(idxLeft == 1){
gclusters[idxCluster].first = permutations[currentCluster.first];
countToUnknowns += 1;
FAssertLF(countToUnknowns <= dim);
}
else{
const int unk = parttab[idxLeft];
parttab[idxLeft] = parttab[idxRight];
parttab[idxRight] = unk;
const int unkPerm = permutations[idxLeft+currentCluster.first];
permutations[idxLeft+currentCluster.first] = permutations[idxRight+currentCluster.first];
permutations[idxRight+currentCluster.first] = unkPerm;
idxLeft += 1;
idxRight -= 1;
else if(idxLeft > 1){
FAssertLF(idxChildCluster >= 0);
gclusters[idxCluster].first = (-idxChildCluster)-1;
idxChildCluster -= 1;
intervals.push(std::pair<int,int>(currentCluster.first, currentCluster.first+idxLeft));
}
if(idxRight == sizeInterval-2){
gclusters[idxCluster].second = permutations[sizeInterval-1+currentCluster.first];
countToUnknowns += 1;
FAssertLF(countToUnknowns <= dim);
}
else if(idxRight < sizeInterval-2){
FAssertLF(idxChildCluster >= 0);
gclusters[idxCluster].second = (-idxChildCluster)-1;
idxChildCluster -= 1;
intervals.push(std::pair<int,int>(currentCluster.first+idxLeft, currentCluster.first+sizeInterval));
}
}
SCOTCH_stratExit(&straptr);
SCOTCH_graphExit(&grafdat);
delete[] parttab;
delete[] verttab;
delete[] edgetab;
}
else{
int idxLeft = sizeInterval/2;
int idxRight = idxLeft-1;
// idxLeft is on the first 1
if(idxLeft == 1){
gclusters[idxCluster].first = permutations[currentCluster.first];
......@@ -164,16 +210,8 @@ public:
idxChildCluster -= 1;
intervals.push(std::pair<int,int>(currentCluster.first+idxLeft, currentCluster.first+sizeInterval));
}
fflush(stdout);
}
SCOTCH_stratExit(&straptr);
SCOTCH_graphExit(&grafdat);
delete[] parttab;
delete[] verttab;
delete[] edgetab;
idxCluster -= 1;
}
FAssertLF(idxCluster == -1);
......@@ -186,7 +224,7 @@ public:
delete[] gclusters;
}
void fillClusterTree(FClusterTree<FReal>* ctree){
void fillClusterTree(FClusterTree<FReal>* ctree) const {
int* permsOrigToNew = new int[dim];
int* permsNewToOrig = new int[dim];
......
#ifndef FMAXDISTCUT_HPP
#define FMAXDISTCUT_HPP
// @SCALFMM_PRIVATE
#include "./Utils/FGlobal.hpp"
#include "./Utils/FAssert.hpp"
#include "./Utils/FMath.hpp"
#include "./Containers/FBoolArray.hpp"
#include "FClusterTree.hpp"
#include <stack>
#include <vector>
#include <functional>
#include <queue>
#include <limits>
#include <memory>
template <class FReal>
class FMaxDistCut {
protected:
const int dim;
int* permutations;
std::pair<int, int>* gclusters;
public:
FMaxDistCut(const int inDim, const FReal inDistMat[])
: dim(inDim),
permutations(new int[dim]),
gclusters (new std::pair<int, int>[dim-1]){
for(int idx = 0 ; idx < dim ; ++idx){
permutations[idx] = idx;
}
std::queue<std::pair<int, int>> intervals;
intervals.push(std::pair<int,int>(0, dim));
int idxCluster = dim-2;
int idxChildCluster = dim-3;
int countToUnknowns = 0;
while(intervals.size()){
FAssertLF(idxCluster >= 0);
const std::pair<int,int> currentCluster = intervals.front();
intervals.pop();
const int sizeInterval = currentCluster.second-currentCluster.first;
FAssertLF(sizeInterval != 1);
int firstIdxMax = permutations[0 + currentCluster.first];
int secondIdxMax = permutations[1 + currentCluster.first];
for(int idxCol = 0 ; idxCol < sizeInterval ; ++idxCol){
const int idxColReal = permutations[idxCol+currentCluster.first];
for(int idxRow = idxCol+1 ; idxRow < sizeInterval ; ++idxRow){
const int idxRowReal = permutations[idxRow+currentCluster.first];
if(inDistMat[idxColReal*dim+ idxRowReal]
> inDistMat[firstIdxMax*dim + secondIdxMax]){
firstIdxMax = idxColReal;
secondIdxMax = idxRowReal;
}
}
}
{
int idxLeft = 0;
int idxRight = sizeInterval-1;
while(idxLeft <= idxRight){
const int idxLeftReal = permutations[idxLeft + currentCluster.first];
const int idxRightReal = permutations[idxRight + currentCluster.first];
if(inDistMat[idxLeftReal*dim+ firstIdxMax]
< inDistMat[idxLeftReal*dim + secondIdxMax]){
idxLeft += 1;
}
else if(inDistMat[idxRightReal*dim+ firstIdxMax]
>= inDistMat[idxRightReal*dim + secondIdxMax]){
idxRight -= 1;
}
else{
const int unkPerm = permutations[idxLeft+currentCluster.first];
permutations[idxLeft+currentCluster.first] = permutations[idxRight+currentCluster.first];
permutations[idxRight+currentCluster.first] = unkPerm;
idxLeft += 1;
idxRight -= 1;
}
}
// idxLeft is on the first 1
if(idxLeft == 1){
gclusters[idxCluster].first = permutations[currentCluster.first];
countToUnknowns += 1;
FAssertLF(countToUnknowns <= dim);
}
else if(idxLeft > 1){
FAssertLF(idxChildCluster >= 0);
gclusters[idxCluster].first = (-idxChildCluster)-1;
idxChildCluster -= 1;
intervals.push(std::pair<int,int>(currentCluster.first, currentCluster.first+idxLeft));
}
if(idxRight == sizeInterval-2){
gclusters[idxCluster].second = permutations[sizeInterval-1+currentCluster.first];
countToUnknowns += 1;
FAssertLF(countToUnknowns <= dim);
}
else if(idxRight < sizeInterval-2){
FAssertLF(idxChildCluster >= 0);
gclusters[idxCluster].second = (-idxChildCluster)-1;
idxChildCluster -= 1;
intervals.push(std::pair<int,int>(currentCluster.first+idxLeft, currentCluster.first+sizeInterval));
}
}
idxCluster -= 1;
}
FAssertLF(idxCluster == -1);
FAssertLF(idxChildCluster == -1);
FAssertLF(countToUnknowns == dim);
}
~FMaxDistCut(){
delete[] permutations;
delete[] gclusters;
}
void fillClusterTree(FClusterTree<FReal>* ctree) const {
int* permsOrigToNew = new int[dim];
int* permsNewToOrig = new int[dim];
{
std::stack<int> depthFirst;
depthFirst.push(gclusters[dim-2].second);
depthFirst.push(gclusters[dim-2].first);
int idxPerm = 0;
while(depthFirst.size()){
const int current = depthFirst.top();
depthFirst.pop();
if(0 <= current){
permsOrigToNew[current] = idxPerm;
permsNewToOrig[idxPerm] = current;
FAssertLF(permsNewToOrig[idxPerm] == permutations[idxPerm]);
idxPerm += 1;
}
else{
depthFirst.push(gclusters[-1-current].second);
depthFirst.push(gclusters[-1-current].first);
}
}
}
typename FClusterTree<FReal>::Leaf* leaves = new typename FClusterTree<FReal>::Leaf[dim];
{
for(int idxUnk = 0 ; idxUnk < dim ; ++idxUnk){
leaves[idxUnk].id = idxUnk;
leaves[idxUnk].offset= idxUnk;
leaves[idxUnk].size = 1;
}
}
typename FClusterTree<FReal>::Node* clusters = new typename FClusterTree<FReal>::Node[dim-1];
for(int idxCluster = 0 ; idxCluster < dim-1 ; ++idxCluster){
typename FClusterTree<FReal>::Node& currentNd = clusters[idxCluster];
const std::pair<int,int>& srcNd = gclusters[idxCluster];
currentNd.id = (-idxCluster)-1;
currentNd.size = 0;
currentNd.left = srcNd.first;
if(0 <= srcNd.first){
currentNd.size += 1;
leaves[srcNd.first].parent = currentNd.id;
}
else{
currentNd.size += clusters[(-srcNd.first)-1].size;
clusters[(-srcNd.first)-1].parent = currentNd.id;
}
currentNd.right = srcNd.second;
if(0 <= srcNd.second){
currentNd.size += 1;
leaves[srcNd.second].parent = currentNd.id;
}
else{
currentNd.size += clusters[(-srcNd.second)-1].size;
clusters[(-srcNd.second)-1].parent = currentNd.id;
}
currentNd.score = 0;
}
clusters[dim-2].parent = 0;
ctree->setData(dim, dim-1, clusters, dim, leaves, permsOrigToNew, permsNewToOrig);
// We do not deallocate, ctree is in charge of this
}
};
#endif // FMAXDISTCUT_HPP
......@@ -63,10 +63,10 @@ public:
totalNbBlocks(0){
FAssertLF(FMath::pow2(height) <= inDim);
cells = new CellNode*[height-1];
FSetToZeros(cells, height-1);
nbCells = new int[height-1];
FSetToZeros(nbCells, height-1);
cells = new CellNode*[height];
FSetToZeros(cells, height);
nbCells = new int[height];
FSetToZeros(nbCells, height);
for(int idxLevel = 1 ; idxLevel < height-1 ; ++idxLevel){
const int nbCellsAtLevel = FMath::pow2(idxLevel);
......@@ -87,22 +87,42 @@ public:
cells[idxLevel][idxCell].infos.level = idxLevel;
}
}
nbLeaves = FMath::pow2(height-1);
{
const int idxLevel = height-1;
const int nbCellsAtLevel = nbLeaves;
cells[idxLevel] = new CellNode[nbCellsAtLevel];
nbCells[idxLevel] = nbCellsAtLevel;
totalNbBlocks += nbCellsAtLevel;
const int nbLeavesInDirection = nbLeaves;
for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){
const int rowLeafNumber = (idxLeaf^1);
const int colLeafNumber = idxLeaf;
cells[idxLevel][idxLeaf].infos.row = ((rowLeafNumber*dim)/nbLeavesInDirection);
cells[idxLevel][idxLeaf].infos.col = ((colLeafNumber*dim)/nbLeavesInDirection);
cells[idxLevel][idxLeaf].infos.nbRows = (((rowLeafNumber+1)*dim)/nbLeavesInDirection)
- cells[idxLevel][idxLeaf].infos.row;
cells[idxLevel][idxLeaf].infos.nbCols = (((colLeafNumber+1)*dim)/nbLeavesInDirection)
- cells[idxLevel][idxLeaf].infos.col;
cells[idxLevel][idxLeaf].infos.level = height-1;
}
}
nbLeaves = FMath::pow2(height);
leaves = new LeafNode[nbLeaves];
totalNbBlocks += nbLeaves;
{
const int nbLeavesInDirection = (nbLeaves/2);
const int nbLeavesInDirection = 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);
const int rowLeafNumber = idxLeaf;
const int colLeafNumber = idxLeaf;
leaves[idxLeaf].infos.row = ((rowLeafNumber*dim)/nbLeavesInDirection);
leaves[idxLeaf].infos.col = ((colLeafNumber*dim)/nbLeavesInDirection);
leaves[idxLeaf].infos.nbRows = (((rowLeafNumber+1)*dim)/nbLeavesInDirection)
- leaves[idxLeaf].infos.row;
leaves[idxLeaf].infos.nbCols = (((colLeafNumber+1)*dim)/nbLeavesInDirection)
- leaves[idxLeaf].infos.col;
leaves[idxLeaf].infos.level = height-1;
leaves[idxLeaf].infos.level = height;
}
}
}
......@@ -124,26 +144,44 @@ public:
}
FAssertLF(offsetUnknowns[nbPartitions] == dim);
nbLeaves = FMath::pow2(height);
nbLeaves = FMath::pow2(height-1);
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);
const int rowLeafNumber = idxLeaf;
const int colLeafNumber = idxLeaf;
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;
leaves[idxLeaf].infos.level = height;
}
}
cells = new CellNode*[height-1];
FSetToZeros(cells, height-1);
nbCells = new int[height-1];
FSetToZeros(nbCells, height-1);
cells = new CellNode*[height];
FSetToZeros(cells, height);
nbCells = new int[height];
FSetToZeros(nbCells, height);
{
const int idxLevel = height-1;
const int nbCellsAtL