20 return "spread-equally-over-all-ranks";
22 return "spread-equally-over-all-threads";
30 _stepsToWaitForNextLoadBalancingDecision(0) {
45 _statistics.getGlobalNumberOfTrees() > 1
58 logDebug(
"updateState()",
"switch to state " <<
::toString(
_state) <<
" as more than one local subpartition is already hosted, i.e. we assume rank has already spread out locally" );
64 logDebug(
"updateState()",
"switch to state " <<
::toString(
_state) <<
" as rank is degenerated with only one thread, i.e. rank-local distribution makes no sense" );
74 if (_stepsToWaitForNextLoadBalancingDecision>0) {
77 "shall wait for another " << _stepsToWaitForNextLoadBalancingDecision <<
" step(s) before we rebalance"
85 const int MinOriginalTreeSizeToTriggerMPISpreadOut = std::max(
99 else if ( _statistics.getLocalNumberOfInnerUnrefinedCells() < MinOriginalTreeSizeToTriggerMPISpreadOut ) {
102 "have to postpone any decision, as local no of inner unrefined cells of " << _statistics.getLocalNumberOfInnerUnrefinedCells() <<
" is smaller than " << MinOriginalTreeSizeToTriggerMPISpreadOut <<
" (which would occupy all ranks)" );
106 return Action::SpreadEquallyOverAllRanks;
112 const int MinOriginalTreeSizeToTriggerThreadSpreadOut = std::max(
113 _configuration->getMinTreeSize(
_state) * ThreadsToKeepBusy,
117 if ( _statistics.getLocalNumberOfInnerUnrefinedCells() < MinOriginalTreeSizeToTriggerThreadSpreadOut ) {
118 logInfo(
"getAction()",
"have to postpone any decision, as local no of inner unrefined cells of " << _statistics.getLocalNumberOfInnerUnrefinedCells() <<
" is smaller than " << MinOriginalTreeSizeToTriggerThreadSpreadOut <<
" (which would occupy all threads)" );
122 return Action::SpreadEquallyOverAllThreads;
138 int numberOfSplits = std::max(1,maxLocalTrees);
142 int estimatedCellsPerTree = maxSizeOfLocalRank / (numberOfSplits+1);
144 const int MinTreeSize = _configuration->getMinTreeSize(
_state);
145 if ( estimatedCellsPerTree<MinTreeSize ) {
146 const int adoptedSplits = std::max(1, maxSizeOfLocalRank / MinTreeSize - 1 );
148 "getNumberOfSplitsOnLocalRank(...)",
149 "coded wanted to split " << numberOfSplits <<
150 " times, but this would yield around " << estimatedCellsPerTree <<
151 " cells per tree, whereas the number of cells per tree should be at least " << MinTreeSize <<
152 ". Split only " << adoptedSplits <<
" times"
154 numberOfSplits = adoptedSplits;
159 maxAdditionalSplitsDueToMemory>=numberOfSplits
162 "getNumberOfSplitsOnLocalRank(...)",
163 "assume enough memory is available, so split " << numberOfSplits <<
164 " times (current mem footprint=" << worstCaseEstimateForSizeOfSpacetree <<
" MByte, free memory=" <<
166 ", max-local-trees-per-rank=" << _configuration->getMaxLocalTreesPerRank(
_state) <<
", no-of-threads=" <<
170 else if ( _configuration->makeSplitDependOnMemory(
_state) ) {
171 int adoptedSplitCount = std::max(1,maxAdditionalSplitsDueToMemory);
173 "getNumberOfSplitsOnLocalRank(...)",
174 "not sure if additional trees fit on node. Optimal number of splits is " << numberOfSplits <<
175 ". With current mem footprint of " << worstCaseEstimateForSizeOfSpacetree <<
" MByte and free memory of " <<
178 numberOfSplits = adoptedSplitCount;
181 return numberOfSplits;
186 auto action = getAction();
191 if ( action!=Action::None ) {
197 case Action::SpreadEquallyOverAllRanks:
199 int cellsPerRank = std::max(
205 int thisRanksCells = cellsPerRank;
209 triggerSplit(thisRanksCells, targetRank);
213 case Action::SpreadEquallyOverAllThreads:
215 int heaviestSpacetree = getIdOfHeaviestLocalSpacetree();
216 if (heaviestSpacetree!=NoHeaviestTreeAvailable and not _blacklist.isBlacklisted(heaviestSpacetree) ) {
219 int numberOfSplits = getNumberOfSplitsOnLocalRank();
220 int cellsPerCore = std::max( {1, numberOfLocalUnrefinedCellsOfHeaviestSpacetree/(numberOfSplits+1),_configuration->getMinTreeSize(
_state)} );
223 "updateLoadBalancing()",
224 "split " << cellsPerCore <<
" or " << (cellsPerCore+1) <<
" cells " << numberOfSplits <<
225 " times from tree " << heaviestSpacetree <<
" on local rank (hosts " << numberOfLocalUnrefinedCellsOfHeaviestSpacetree <<
228 for (
int i=0; i<numberOfSplits; i++) {
229 int thisCellsPerCore = cellsPerCore;
230 if (i<numberOfLocalUnrefinedCellsOfHeaviestSpacetree % (numberOfSplits+1)) {
237 logInfo(
"updateLoadBalancing()",
"local tree is not yet available for further splits (heaviest-spacetree=" << heaviestSpacetree <<
")" );
248 _statistics.updateGlobalView();
249 _costMetrics->updateGlobalView();
252 if ( _statistics.hasConsistentViewOfWorld() ) {
253 _stepsToWaitForNextLoadBalancingDecision = std::max( _stepsToWaitForNextLoadBalancingDecision-1, 0 );
256 logInfo(
"finishStep()",
"statistics have no consistent view of world, so postpone load balancing decisions" );
257 _stepsToWaitForNextLoadBalancingDecision = std::max(_stepsToWaitForNextLoadBalancingDecision,1);
260 updateLoadBalancing();
263 _statistics.notifyOfStateChange(
_state );
275 logInfo(
"triggerSplit()",
"wanted to split local rank " << sourceTree <<
" but failed" );
278 _blacklist.triggeredSplit( sourceTree );
279 _statistics.incLocalNumberOfSplits();
281 _stepsToWaitForNextLoadBalancingDecision = 3;
#define assertionEquals(lhs, rhs)
#define logDebug(methodName, logMacroMessageStream)
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
bool split(int treeId, const peano4::SplitInstruction &instruction, int targetRank)
Split a local tree.
static SpacetreeSet & getInstance()
std::set< int > getLocalSpacetrees() const
int getNumberOfRanks() const
static Rank & getInstance()
This operation returns the singleton instance.
static Core & getInstance()
int getNumberOfThreads() const
Returns the number of threads that is used.
std::string toString(Filter filter)
int getMemoryUsage(MemoryUsageFormat format)
Method for getting the application's memory footprint.
int getFreeMemory(MemoryUsageFormat format)