Commit 6c912fb2 authored by DUFOYER Benjamin's avatar DUFOYER Benjamin

Fix bug : building BlockTree with BlockLinearTree

parent d07a6169
......@@ -17,8 +17,11 @@ protected:
int block_size;
int nb_block;
const inria::mpi_config& mpi_conf;
std::vector<node_t>* linear_tree;
std::vector<std::pair<unsigned long long int,unsigned long long int>> particle_repartition;
bool unknow_particle_repartition = true:;
public:
......@@ -34,7 +37,12 @@ public:
* @param in_box_center Box Center of particle container
* @param in_box_width Box Width of particle container
*/
FGroupLinearTree(){}
FGroupLinearTree(const inria::mpi_config& conf):
mpi_conf(conf),
particle_repartition(conf.comm.size())
{
linear_tree = new std::vector<node_t>[1];
}
/**
* This function create a blocked linear tree from the current distributed
......@@ -58,21 +66,20 @@ public:
* @author benjamin.dufoyer@inria.fr
* @param in_linear_tree linear tree
* @param in_block_size blocksize needed
* @param conf [description]
*/
void create_global_blocked_linear_tree(
std::vector<node_t>* in_linear_tree,
int in_block_size,
const inria::mpi_config& conf
int in_block_size
){
this->create(in_linear_tree,in_block_size);
this->redistribute_block(conf);
this->redistribute_block();
}
void create(
std::vector<node_t>* in_linear_tree,
int in_block_size
){
this->block_size = in_block_size;
this->linear_tree = in_linear_tree;
this->nb_block = (int)in_linear_tree->size()/in_block_size;
......@@ -97,12 +104,11 @@ public:
* block size. For N proc, N-1 proc have the same number of leaf,
* the rest is for the proc N
* @author benjamin.dufoyer@inria.fr
* @param conf mpi configuration to work with the other process
*/
void redistribute_block(const inria::mpi_config& conf){
void redistribute_block(){
dstr_grp_tree_builder::parrallel_build_block(
conf,
this->mpi_conf,
this->linear_tree,
this->block_size);
//Update nb_block
......@@ -198,42 +204,64 @@ public:
* This function fill the particle_repartition with a call of the function
* from FDistributedGroupTreeBuilder
* @author benjamin.dufoyer@inria.fr
* @param conf [description]
* @param particle_container [description]
*/
template<class particle_t>
void set_particle_repartition(const inria::mpi_config& conf,
std::vector<particle_t> particle_container)
void set_particle_repartition(
std::vector<particle_t> particle_container)
{
this->particle_repartition.resize(conf.comm.size());
dstr_grp_tree_builder::know_particle_division(
conf,
this->mpi_conf,
particle_container,
particle_repartition);
}
std::vector<std::pair<unsigned long long int,unsigned long long int>>*
get_particle_repartition(){
get_particle_repartition()
// TO get the particle repartition, you will compute it before
FAssert(!unknow_particle_repartition);
return &this->particle_repartition;
}
std::pair<unsigned long long int,unsigned long long int> get_particle_repartition_at(unsigned i){
// TO get the particle repartition, you will compute it before
FAssert(!unknow_particle_repartition);
FAssert(i < this->particle_repartition.size());
return this->particle_repartition.data()[i];
}
/**
* This function call a couple of function who add the LET part of the
* groupTree
* return the max morton index of the left proc
* it's needed for the distributed construction of the groupTree
* you will compute the repartition before calling this function
* @author benjamin.dufoyer@inria.fr
* @param tree local group tree
* @return Morton Index
*/
unsigned long long int get_left_limit(){
FAssert(!unknow_particle_repartition);
int my_rank = this->mpi_conf.comm.rank();
if(my_rank != 0){
left_limit = this->particle_repartition[my_rank-1].second;
}
return left_limit;
}
/**
* This function compute the leaf needed to build the LET part of the Group
* Tree.
* After she send block needed by other proc and she recev block needed
* @author benjamin.dufoyer@inria.fr
* @param tree local group tree
* [Optionial]
* @param dim Dimension of coordinate of particle
*/
template<class GroupTreeClass>
void create_let_group_tree(
GroupTreeClass& tree,
const inria::mpi_config& conf,
int dim = 3){
int dim = 3
){
FAssert(particle_repartition.size() != 0 );
FAssert(dim > 0);
// Compute min and max global morton index
const MortonIndex global_min_m_idx = this->particle_repartition.front().first;
......@@ -263,18 +291,24 @@ public:
// concat result
std::vector<size_t> needed_leaf = dstr_grp_tree_builder::concat_M2L_P2P(leaf_P2P,leaf_M2L);
// Creation of interaction matrice
std::vector<size_t> global_matrix_interaction = dstr_grp_tree_builder::get_matrix_interaction(
needed_leaf,
particle_repartition,
conf);
this->mpi_conf);
// Send and get leaf
// Auto is used to get the block more easly
// it's a vector<vector<block_t>>
// block_t is a struct define on FDistributedGroupTreeBuilder.hpp
auto let_block = dstr_grp_tree_builder::send_get_symbolic_leaf(
needed_leaf,
global_matrix_interaction,
tree,
conf);
this->mpi_conf);
// Add the block recev to the local group tree
dstr_grp_tree_builder::add_let_block_to_tree(
tree,
let_block,
......@@ -282,6 +316,7 @@ public:
}
};
#endif //_FGROUP_LINEAR_TREE_HPP_
......@@ -896,13 +896,15 @@ public:
class Particle_Container
>
void create_tree(Group_Linear_tree* in_lin_tree,
Particle_Container* particles){
Particle_Container* particles,
MortonIndex inLeftLimite = -1){
MortonIndex in_left_limit = in_lin_tree->get_left_limit();
// Creation of the leaf level and groups of particle
create_leaf_level(in_lin_tree,particles);
auto current_block_indexes = create_leaf_level(in_lin_tree,particles);
// Creation of every level of the tree
for(int level = this->_treeHeight-2 ; level >= 0 ; --level){
create_block_nodes_at_level(level);
}
create_block_nodes_level(
current_block_indexes,
in_left_limit);
}
/** This function dealloc the tree by deleting each block */
......@@ -914,7 +916,6 @@ public:
}
}
delete[] _cellBlocksPerLevel;
for (ParticleGroupClass* block: _particleBlocks){
delete block;
}
......@@ -1153,7 +1154,7 @@ template<
class Blocked_Linear_tree,
class Particle_Container
>
void create_leaf_level(Blocked_Linear_tree* in_lin_tree,
MortonIndex* create_leaf_level(Blocked_Linear_tree* in_lin_tree,
Particle_Container* particles)
{
const int idxLevel = this->_treeHeight-1;
......@@ -1264,107 +1265,94 @@ void create_leaf_level(Blocked_Linear_tree* in_lin_tree,
_particleBlocks.push_back(new_particle_block);
size_of_block = 0;
}
return current_block_indexes;
}
/**
* create_level create every level
* It's juste a factorisation from the Beregenger constructor
* @author benjamin.dufoyer@inria.fr
* @param level to construct
* @param in_left_limit left limit of block of the current proc
* @param currentBlockIndexes block repartition at leaf level
* to construct
* @param inLeftLimite left limit of block of the current proc
* this parameter is not used with the blocked_linear_tree, he is here
* to have compatibility with old constructor
*/
void create_block_nodes_at_level(int idxLevel,
MortonIndex in_left_limit = -1){
// Modify in_left_limit
in_left_limit = (in_left_limit == -1 ? in_left_limit : (in_left_limit>>3));
// Initialiser iterator to manage child block
CellGroupConstIterator iter_child_cell =
_cellBlocksPerLevel[idxLevel+1].begin();
const CellGroupConstIterator iter_child_end_cells =
_cellBlocksPerLevel[idxLevel+1].end();
void create_block_nodes_level(MortonIndex* currentBlockIndexes,
MortonIndex inLeftLimite = -1
){
// Cronstruct every level
for(int idxLevel = _treeHeight-2; idxLevel > 0 ; --idxLevel){
inLeftLimite = (inLeftLimite == -1 ? inLeftLimite : (inLeftLimite>>3));
CellGroupConstIterator iterChildCells = _cellBlocksPerLevel[idxLevel+1].begin();
const CellGroupConstIterator iterChildEndCells = _cellBlocksPerLevel[idxLevel+1].end();
// Skip blocks that do not respect limit
while(iter_child_cell != iter_child_end_cells
&& ((*iter_child_cell )->getEndingIndex()>>3) <= in_left_limit){
++iter_child_cell ;
while(iterChildCells != iterChildEndCells
&& ((*iterChildCells)->getEndingIndex()>>3) <= inLeftLimite){
++iterChildCells;
}
// If lower level is empty or all blocks skiped stop here
if(iter_child_cell == iter_child_end_cells){
return;
if(iterChildCells == iterChildEndCells){
break;
}
// Initialise current cell index
MortonIndex current_cell_index =
(*iter_child_cell )->getStartingIndex();
if((current_cell_index>>3) <= in_left_limit)
current_cell_index = ((in_left_limit+1)<<3);
int size_of_block = 0;
MortonIndex* current_block_indexes = new MortonIndex[_nbElementsPerBlock];
MortonIndex currentCellIndex = (*iterChildCells)->getStartingIndex();
if((currentCellIndex>>3) <= inLeftLimite) currentCellIndex = ((inLeftLimite+1)<<3);
int sizeOfBlock = 0;
// We need to proceed each group in sub level
while(iter_child_cell != iter_child_end_cells){
while(iterChildCells != iterChildEndCells){
// Count until end of sub group is reached or we have enough cells
while(size_of_block < _nbElementsPerBlock && iter_child_cell != iter_child_end_cells ){
if(( size_of_block == 0 ||
current_block_indexes[size_of_block-1] != (current_cell_index>>3)) &&
(*iter_child_cell )->exists(current_cell_index))
{
current_block_indexes[size_of_block] = (current_cell_index>>3);
size_of_block += 1;
current_cell_index = (((current_cell_index>>3)+1)<<3);
while(sizeOfBlock < _nbElementsPerBlock && iterChildCells != iterChildEndCells ){
if((sizeOfBlock == 0 || currentBlockIndexes[sizeOfBlock-1] != (currentCellIndex>>3))
&& (*iterChildCells)->exists(currentCellIndex)){
currentBlockIndexes[sizeOfBlock] = (currentCellIndex>>3);
sizeOfBlock += 1;
currentCellIndex = (((currentCellIndex>>3)+1)<<3);
}
else
{
current_cell_index += 1;
else{
currentCellIndex += 1;
}
// If we are at the end of the sub group, move to next
while(iter_child_cell != iter_child_end_cells && (*iter_child_cell )->getEndingIndex() <= current_cell_index){
++iter_child_cell ;
while(iterChildCells != iterChildEndCells && (*iterChildCells)->getEndingIndex() <= currentCellIndex){
++iterChildCells;
// Update morton index
if(iter_child_cell != iter_child_end_cells
&& current_cell_index < (*iter_child_cell )->getStartingIndex())
{
current_cell_index = (*iter_child_cell )->getStartingIndex();
if(iterChildCells != iterChildEndCells && currentCellIndex < (*iterChildCells)->getStartingIndex()){
currentCellIndex = (*iterChildCells)->getStartingIndex();
}
}
}
// If group is full
if(size_of_block == _nbElementsPerBlock || (size_of_block && iter_child_cell == iter_child_end_cells)){
// Create a block
CellGroupClass*const newBlock = new CellGroupClass(current_block_indexes[0],
current_block_indexes[size_of_block-1]+1,
size_of_block);
// Init cells of the block
for(int cellIdInBlock = 0; cellIdInBlock != size_of_block ; ++cellIdInBlock){
newBlock->newCell(current_block_indexes[cellIdInBlock], cellIdInBlock);
if(sizeOfBlock == _nbElementsPerBlock || (sizeOfBlock && iterChildCells == iterChildEndCells)){
// Create a group
CellGroupClass*const newBlock = new CellGroupClass(currentBlockIndexes[0],
currentBlockIndexes[sizeOfBlock-1]+1,
sizeOfBlock);
// Init cells
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
SymbolCellClass& symbolic = newBlock->getSymbolic(cellIdInBlock);
symbolic.setMortonIndex(current_block_indexes[cellIdInBlock]);
symbolic.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(current_block_indexes[cellIdInBlock]);
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock]);
symbolic.setCoordinate(coord);
symbolic.setLevel(idxLevel);
}
// stock the block
// Keep the block
_cellBlocksPerLevel[idxLevel].push_back(newBlock);
// reinitialise variables
size_of_block = 0;
sizeOfBlock = 0;
}
}
}
}
/**
* Add block putted in parameter into the local group tree
......
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