Skip to content
Snippets Groups Projects
Commit 5c456a60 authored by Sebastian Eibl's avatar Sebastian Eibl
Browse files

made DynamicCurve balance levelwise optional

parent cb431e5e
Branches
Tags
No related merge requests found
......@@ -22,6 +22,7 @@
#pragma once
#include "NoPhantomData.h"
#include "blockforest/BlockForest.h"
#include "blockforest/HilbertCurveConstruction.h"
#include "blockforest/PhantomBlockForest.h"
......@@ -88,9 +89,14 @@ struct Node
} // namespace internal
/**
* This class implements Hilber and Morton space filling curves for load balancing.
*
* All algorithms are implemented to work levelwise. Load balancing with levels ignored is possible
* by specifying levelwise = false in the constructor.
**/
template< typename PhantomData_T >
class DynamicLevelwiseCurveBalance
class DynamicCurveBalance
{
public:
......@@ -99,8 +105,8 @@ public:
typedef uint16_t idx_t; // limits the maximum number of blocks per process to 65536
typedef internal::Node< pid_t, idx_t > Node;
DynamicLevelwiseCurveBalance( const bool hilbert = true, const bool allGather = true ) :
hilbert_( hilbert ), allGather_( allGather )
DynamicCurveBalance( const bool hilbert = true, const bool allGather = true, const bool levelwise = true ) :
hilbert_( hilbert ), allGather_( allGather ), levelwise_(levelwise)
{}
bool operator()( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
......@@ -180,12 +186,17 @@ private:
bool hilbert_;
bool allGather_;
/// All gets for levels are wrapped like
/// \code levelwise_ ? getCorrectLevel() : 0
///
/// This allows to use the same algorithm for levelwise balancing as well as for balancing without levels.
bool levelwise_;
};
template< typename PhantomData_T >
bool DynamicLevelwiseCurveBalance< PhantomData_T >::operator()( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
bool DynamicCurveBalance< PhantomData_T >::operator()( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom,
const PhantomBlockForest & phantomForest, const uint_t ) const
{
......@@ -214,7 +225,7 @@ bool DynamicLevelwiseCurveBalance< PhantomData_T >::operator()( std::vector< std
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::allGatherWeighted( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
void DynamicCurveBalance< PhantomData_T >::allGatherWeighted( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom,
const PhantomBlockForest & phantomForest ) const
{
......@@ -241,7 +252,8 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::allGatherWeighted( std::vect
recvBuffer >> allBlocks[p];
recvBuffer.reset();
std::vector< std::vector< std::pair< pid_t, idx_t > > > blocksPerLevel( phantomForest.getNumberOfLevels() ); // for every level one vector of pair(source process ID, index in 'allBlocks')
const uint_t numLevels = levelwise_ ? phantomForest.getNumberOfLevels() : uint_t(1);
std::vector< std::vector< std::pair< pid_t, idx_t > > > blocksPerLevel( numLevels ); // for every level one vector of pair(source process ID, index in 'allBlocks')
if( hilbert_ )
hilbertOrderWeighted( allBlocks, blocksPerLevel, phantomForest );
......@@ -259,7 +271,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::allGatherWeighted( std::vect
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::allGatherNoWeight( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
void DynamicCurveBalance< PhantomData_T >::allGatherNoWeight( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom,
const PhantomBlockForest & phantomForest ) const
{
......@@ -283,7 +295,8 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::allGatherNoWeight( std::vect
recvBuffer >> allBlocks[p];
recvBuffer.reset();
std::vector< std::vector< std::pair< pid_t, idx_t > > > blocksPerLevel( phantomForest.getNumberOfLevels() ); // for every level one vector of pair(source process ID, index in 'allBlocks')
const uint_t numLevels = levelwise_ ? phantomForest.getNumberOfLevels() : uint_t(1);
std::vector< std::vector< std::pair< pid_t, idx_t > > > blocksPerLevel( numLevels ); // for every level one vector of pair(source process ID, index in 'allBlocks')
if( hilbert_ )
hilbertOrderNoWeight( allBlocks, blocksPerLevel, phantomForest );
......@@ -301,7 +314,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::allGatherNoWeight( std::vect
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::masterWeighted( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
void DynamicCurveBalance< PhantomData_T >::masterWeighted( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom,
const PhantomBlockForest & phantomForest ) const
{
......@@ -352,7 +365,8 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::masterWeighted( std::vector<
WALBERLA_ASSERT( allBlocks[0].empty() );
allBlocks[0] = localBlocks;
blocksPerLevel.resize( phantomForest.getNumberOfLevels() );
const uint_t numLevels = levelwise_ ? phantomForest.getNumberOfLevels() : uint_t(1);
blocksPerLevel.resize( numLevels );
if( hilbert_ )
hilbertOrderWeighted( allBlocks, blocksPerLevel, phantomForest );
......@@ -377,7 +391,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::masterWeighted( std::vector<
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::masterNoWeight( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
void DynamicCurveBalance< PhantomData_T >::masterNoWeight( std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom,
const PhantomBlockForest & phantomForest ) const
{
......@@ -425,7 +439,8 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::masterNoWeight( std::vector<
WALBERLA_ASSERT( allBlocks[0].empty() );
allBlocks[0] = localBlocks;
blocksPerLevel.resize( phantomForest.getNumberOfLevels() );
const uint_t numLevels = levelwise_ ? phantomForest.getNumberOfLevels() : uint_t(1);
blocksPerLevel.resize( numLevels );
if( hilbert_ )
hilbertOrderNoWeight( allBlocks, blocksPerLevel, phantomForest );
......@@ -450,9 +465,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::masterNoWeight( std::vector<
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::hilbertOrderWeighted( const std::vector< std::vector< std::pair< BlockID, typename PhantomData_T::weight_t > > > & allBlocks,
void DynamicCurveBalance< PhantomData_T >::hilbertOrderWeighted( const std::vector< std::vector< std::pair< BlockID, typename PhantomData_T::weight_t > > > & allBlocks,
std::vector< std::vector< std::pair< pid_t, idx_t > > > & blocksPerLevel,
const PhantomBlockForest & phantomForest ) const
const PhantomBlockForest & phantomForest) const
{
// construct forest of octrees
......@@ -519,8 +534,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::hilbertOrderWeighted( const
else
{
auto & index = node->index_;
WALBERLA_ASSERT_LESS( blockforest.getLevelFromBlockId( allBlocks[ uint_c(index.first) ][ index.second ].first ), phantomForest.getNumberOfLevels() );
blocksPerLevel[ blockforest.getLevelFromBlockId( allBlocks[ uint_c(index.first) ][ index.second ].first ) ].push_back( index );
const uint_t level = levelwise_ ? blockforest.getLevelFromBlockId( allBlocks[ uint_c(index.first) ][ index.second ].first ) : uint_t(0);
WALBERLA_ASSERT_LESS( level, levelwise_ ? phantomForest.getNumberOfLevels() : uint_t(1) );
blocksPerLevel[ level ].push_back( index );
}
}
}
......@@ -539,9 +555,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::hilbertOrderWeighted( const
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::hilbertOrderNoWeight( const std::vector< std::vector< BlockID > > & allBlocks,
void DynamicCurveBalance< PhantomData_T >::hilbertOrderNoWeight( const std::vector< std::vector< BlockID > > & allBlocks,
std::vector< std::vector< std::pair< pid_t, idx_t > > > & blocksPerLevel,
const PhantomBlockForest & phantomForest ) const
const PhantomBlockForest & phantomForest) const
{
// construct forest of octrees
......@@ -608,8 +624,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::hilbertOrderNoWeight( const
else
{
auto & index = node->index_;
WALBERLA_ASSERT_LESS( blockforest.getLevelFromBlockId( allBlocks[ uint_c(index.first) ][ index.second ] ), phantomForest.getNumberOfLevels() );
blocksPerLevel[ blockforest.getLevelFromBlockId( allBlocks[ uint_c(index.first) ][ index.second ] ) ].push_back( index );
const uint_t level = levelwise_ ? blockforest.getLevelFromBlockId( allBlocks[ uint_c(index.first) ][ index.second ] ) : uint_t(0);
WALBERLA_ASSERT_LESS( level , levelwise_ ? phantomForest.getNumberOfLevels() : uint_t(1) );
blocksPerLevel[ level ].push_back( index );
}
}
}
......@@ -628,7 +645,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::hilbertOrderNoWeight( const
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::addBlockToForest( std::vector< shared_ptr< Node > > & forest,
void DynamicCurveBalance< PhantomData_T >::addBlockToForest( std::vector< shared_ptr< Node > > & forest,
const std::pair< pid_t, idx_t > & index, BlockID & id, const uint_t level ) const
{
std::stack< uint_t > path;
......@@ -681,9 +698,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::addBlockToForest( std::vecto
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::mortonOrderWeighted( const std::vector< std::vector< std::pair< BlockID, typename PhantomData_T::weight_t > > > & allBlocks,
void DynamicCurveBalance< PhantomData_T >::mortonOrderWeighted( const std::vector< std::vector< std::pair< BlockID, typename PhantomData_T::weight_t > > > & allBlocks,
std::vector< std::vector< std::pair< pid_t, idx_t > > > & blocksPerLevel,
const PhantomBlockForest & phantomForest ) const
const PhantomBlockForest & phantomForest) const
{
const uint_t processes = uint_c( mpi::MPIManager::instance()->numProcesses() );
......@@ -691,8 +708,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::mortonOrderWeighted( const s
{
for( uint_t i = uint_t(0); i != allBlocks[p].size(); ++i )
{
WALBERLA_ASSERT_LESS( phantomForest.getBlockForest().getLevelFromBlockId( allBlocks[p][i].first ), blocksPerLevel.size() );
blocksPerLevel[ phantomForest.getBlockForest().getLevelFromBlockId( allBlocks[p][i].first ) ].push_back( std::make_pair( pid_c(p), idx_c(i) ) );
uint_t level = levelwise_ ? phantomForest.getBlockForest().getLevelFromBlockId( allBlocks[p][i].first ) : uint_t(0);
WALBERLA_ASSERT_LESS( level, blocksPerLevel.size() );
blocksPerLevel[ level ].push_back( std::make_pair( pid_c(p), idx_c(i) ) );
}
}
......@@ -710,9 +728,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::mortonOrderWeighted( const s
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::mortonOrderNoWeight( const std::vector< std::vector< BlockID > > & allBlocks,
void DynamicCurveBalance< PhantomData_T >::mortonOrderNoWeight( const std::vector< std::vector< BlockID > > & allBlocks,
std::vector< std::vector< std::pair< pid_t, idx_t > > > & blocksPerLevel,
const PhantomBlockForest & phantomForest ) const
const PhantomBlockForest & phantomForest) const
{
const uint_t processes = uint_c( mpi::MPIManager::instance()->numProcesses() );
......@@ -720,8 +738,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::mortonOrderNoWeight( const s
{
for( uint_t i = uint_t(0); i != allBlocks[p].size(); ++i )
{
WALBERLA_ASSERT_LESS( phantomForest.getBlockForest().getLevelFromBlockId( allBlocks[p][i] ), blocksPerLevel.size() );
blocksPerLevel[ phantomForest.getBlockForest().getLevelFromBlockId( allBlocks[p][i] ) ].push_back( std::make_pair( pid_c(p), idx_c(i) ) );
uint_t level = levelwise_ ? phantomForest.getBlockForest().getLevelFromBlockId( allBlocks[p][i] ) : uint_t(0);
WALBERLA_ASSERT_LESS( level, blocksPerLevel.size() );
blocksPerLevel[ level ].push_back( std::make_pair( pid_c(p), idx_c(i) ) );
}
}
......@@ -739,7 +758,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::mortonOrderNoWeight( const s
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::balanceWeighted( const std::vector< std::vector< std::pair< BlockID, typename PhantomData_T::weight_t > > > & allBlocks,
void DynamicCurveBalance< PhantomData_T >::balanceWeighted( const std::vector< std::vector< std::pair< BlockID, typename PhantomData_T::weight_t > > > & allBlocks,
const std::vector< std::vector< std::pair< pid_t, idx_t > > > & blocksPerLevel,
std::vector< std::vector<pid_t> > & targets,
std::vector< std::set<pid_t> > & sender ) const
......@@ -790,7 +809,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::balanceWeighted( const std::
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::balanceNoWeight( const std::vector< std::vector< BlockID > > & allBlocks,
void DynamicCurveBalance< PhantomData_T >::balanceNoWeight( const std::vector< std::vector< BlockID > > & allBlocks,
const std::vector< std::vector< std::pair< pid_t, idx_t > > > & blocksPerLevel,
std::vector< std::vector<pid_t> > & targets,
std::vector< std::set<pid_t> > & sender ) const
......@@ -825,7 +844,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::balanceNoWeight( const std::
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::masterEnd( std::vector< std::vector<pid_t> > & targets,
void DynamicCurveBalance< PhantomData_T >::masterEnd( std::vector< std::vector<pid_t> > & targets,
std::vector< std::set<pid_t> > & sender,
std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom ) const
......@@ -893,7 +912,7 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::masterEnd( std::vector< std:
template< typename PhantomData_T >
void DynamicLevelwiseCurveBalance< PhantomData_T >::finalAssignment( const uint_t index, const std::vector< std::vector<pid_t> > & targets,
void DynamicCurveBalance< PhantomData_T >::finalAssignment( const uint_t index, const std::vector< std::vector<pid_t> > & targets,
const std::vector< std::set<pid_t> > & sender,
std::vector< std::pair< const PhantomBlock *, uint_t > > & targetProcess,
std::set< uint_t > & processesToRecvFrom ) const
......@@ -907,7 +926,9 @@ void DynamicLevelwiseCurveBalance< PhantomData_T >::finalAssignment( const uint_
processesToRecvFrom.insert( uint_c(*s) ) ;
}
///This class is deprecated use DynamicCurveBalance instead.
template< typename PhantomData_T >
using DynamicLevelwiseCurveBalance = DynamicCurveBalance<PhantomData_T> ;
} // namespace blockforest
} // namespace walberla
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