Commit c6d15e05 authored by Benjamin Dufoyer's avatar Benjamin Dufoyer

Modif parrallel_build_block to support pointer usage and adding the BlockedLinearTree

parent 3ba0a399
#ifndef _FBLOCKED_LINEAR_TREE_HPP_
#define _FBLOCKED_LINEAR_TREE_HPP_
#include <vector>
#include "../../Utils/FLog.hpp"
#include "FDistributedGroupTreeBuilder.hpp"
template<class node_t>
class FBlockedLinearTree {
protected:
const int block_size;
int nb_leaf;
int nb_block;
std::vector<node_t>* linear_tree;
public:
////////////////////////////////////////////////
// constructor
////////////////////////////////////////////////
/**
* FBlockedLinearTree This constructer create a blocked linear tree
* from a linear tree. This linear tree will be balanced BEFORE calling
* this constructer
* @author benjamin.dufoyer@inria.fr
* @param in_linear_tree current linear_tree
* @param in_block_size block_size needed
*/
FBlockedLinearTree(const int in_block_size ,std::vector<node_t>* in_linear_tree):
block_size(in_block_size),
nb_leaf((int)in_linear_tree->size())
{
if(nb_leaf%block_size == 0)
this->nb_block = nb_leaf/block_size;
else
this->nb_block = nb_leaf/block_size+1;
std::swap(in_linear_tree,linear_tree);
}
////////////////////////////////////////////////
// destructor
////////////////////////////////////////////////
~FBlockedLinearTree(){
delete linear_tree;
}
////////////////////////////////////////////////
// Function
////////////////////////////////////////////////
/**
* redistribute_block redistribute leaf of the linear_tree with the good
* 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){
dstr_grp_tree_builder::parrallel_build_block(conf,
this->linear_tree,
this->block_size);
//Update nb_leaf and nb_block
this->nb_leaf = (int)this->linear_tree->size();
if(nb_leaf%block_size == 0)
this->nb_block = nb_leaf/block_size;
else
this->nb_block = nb_leaf/block_size+1;
}
int get_nb_leaf() const{
return this->nb_leaf;
}
int get_nb_block() const{
return this->nb_block;
}
int get_block_size() const{
return this->block_size;
}
/**
* get_block_size_at return the block size of the number of the block
* placed in parametter,
* [INFO] first block is 0
* [INFO] last block is this->nb_block-1
* @author benjamin.dufoyer@inria.fr
* @param num_block number of the block
* @return size of the block
*/
int get_block_size_at(int num_block) {
int size;
if(num_block < this->nb_block){
if(num_block == this->nb_block-1){
size = this->nb_leaf - ((this->nb_block-1)*this->block_size);
} else {
size = this->block_size;
}
} else {
FLOG(FLog::Controller << "[ERROR][FBlockedLinearTree] Trying to access to undefined block, returning block_size " << "\n");
size = this->block_size;
}
return size;
}
/**
* get_leaf_at return the leaf at the position placed in parameter
* @author benjamin.dufoyer@inria.fr
* @param position position of the leaf
* @return the leaf
*/
node_t get_leaf_at(int position){
node_t leaf;
if(position < this->nb_leaf && position >= 0) {
leaf = this->linear_tree->at(position);
} else {
FLOG(FLog::Controller << "[ERROR][FBlockedLinearTree] Trying to access to undefined leaf " << "\n");
leaf = this->linear_tree->first();
}
return leaf;
}
int get_leaf_level(){
return this->linear_tree->front().level;
}
int get_first_morton_index(){
return this->linear_tree->front().morton_index;
}
int get_last_morton_index(){
return linear_tree->back().morton_index;
}
void print_info_tree(){
std::cout << " nb_leaf : " << nb_leaf << std::endl;
std::cout << " nb_block : " << nb_block << std::endl;
std::cout << " block_size : " << block_size << std::endl;
for(int i = 0 ; i < nb_leaf ; i++){
std::cout << linear_tree->at(i) << std::endl;
}
}
};
#endif //_FBLOCKED_LINEAR_TREE_HPP_
......@@ -9,6 +9,8 @@
#include "FGroupTree.hpp"
#include <cmath>
namespace dstr_grp_tree_builder{
/**
* fill_new_linear_tree this function fill the new linear tree with the value of the current linear tree who are conserved.
* @author benjamin.dufoyer@inria.fr
......@@ -40,7 +42,6 @@ void fill_new_linear_tree(
}
}
/**
* redistribute_leafs redistribute the leaf on proc according to the groupsize
* on a distributed linear tree
......@@ -50,8 +51,8 @@ void fill_new_linear_tree(
* @param group_size size of the group of leaf
*/
template<class node_t>
void parrallel_build_block(const inria::mpi_config& conf, std::vector<node_t>& linear_tree, const int& group_size){
int nb_local_leaf = (int)linear_tree.size();
void parrallel_build_block(const inria::mpi_config& conf, std::vector<node_t>* linear_tree, const int& group_size){
int nb_local_leaf = (int)linear_tree->size();
const int nb_proc = conf.comm.size();
int* array_global_nb_leaf = (int *)malloc(sizeof(int) * nb_proc); //nb leaf
const int my_rank = conf.comm.rank();
......@@ -153,7 +154,7 @@ void parrallel_build_block(const inria::mpi_config& conf, std::vector<node_t>& l
// in a second time we post every send message
// We declare the new linear_tree who have the new number of cell
std::vector<node_t> new_linear_tree(array_global_nb_leaf[my_rank]);
std::vector<node_t>* new_linear_tree = new std::vector<node_t>(array_global_nb_leaf[my_rank]);
//Posting receiv message
//For every interaction
......@@ -166,11 +167,11 @@ void parrallel_build_block(const inria::mpi_config& conf, std::vector<node_t>& l
// Compute the pointer to write result
unsigned start = 0;
if(my_rank < interaction_recev.at(i).process_rank){
start = (unsigned)new_linear_tree.size() - interaction_recev.at(i).nb_leaf;
start = (unsigned)new_linear_tree->size() - interaction_recev.at(i).nb_leaf;
}
// Sending request
tab_mpi_status[i] =
conf.comm.irecv(&new_linear_tree.at(start),
conf.comm.irecv(&new_linear_tree->at(start),
size_recev,
MPI_CHAR,
interaction_recev.at(i).process_rank,1);
......@@ -182,10 +183,10 @@ void parrallel_build_block(const inria::mpi_config& conf, std::vector<node_t>& l
// Compute the pointer to send cell
unsigned start = 0;
if(my_rank < interaction_send.at(i).process_rank){
start = (unsigned)linear_tree.size() - interaction_send.at(i).nb_leaf;
start = (unsigned)linear_tree->size() - interaction_send.at(i).nb_leaf;
}
//sending leaf
conf.comm.isend(&linear_tree.at(start),
conf.comm.isend(&linear_tree->at(start),
size_send,
MPI_CHAR,
interaction_send.at(i).process_rank,1);
......@@ -195,16 +196,16 @@ void parrallel_build_block(const inria::mpi_config& conf, std::vector<node_t>& l
// The function need to know how many cell the current process send on
// the right and on the left because the MPI request write on the same
// pointer
fill_new_linear_tree(&linear_tree,&new_linear_tree,nb_leaf_recev_left,nb_leaf_recev_right,nb_leaf_send_left,nb_leaf_send_right);
fill_new_linear_tree(linear_tree,new_linear_tree,nb_leaf_recev_left,nb_leaf_recev_right,nb_leaf_send_left,nb_leaf_send_right);
// waiting for the end of MPI request
inria::mpi::request::waitall(interaction_recev.size(),tab_mpi_status);
// swaping linear_tree pointer
linear_tree.swap(new_linear_tree);
std::swap(*linear_tree,*new_linear_tree);
}
}
#endif /*_FDISTRIBUTED_GROUPTREE_BUILDER_HPP_*/
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