Peano
Loading...
Searching...
No Matches
SpreadOut.cpp
Go to the documentation of this file.
2
6
7
8tarch::logging::Log toolbox::loadbalancing::strategies::SpreadOut::_log("toolbox::loadbalancing::strategies::SpreadOut"
9);
10
11
13 AbstractLoadBalancing(configuration, costMetrics),
14 _previousNumberOfCells(-1),
15 _numberOfStableGridIterations(0) {
16 assertion(configuration != nullptr);
17 assertion(costMetrics != nullptr);
20}
21
22
24
25
27 int result = 0;
28
29 if (_state == State::InterRankDistribution and _statistics.hasConsistentViewOfWorld()) {
30 const int MaxTreesPerRank = std::min(
31 _configuration->getMaxLocalTreesPerRank(_state), tarch::multicore::Core::getInstance().getNumberOfThreads()
32 );
33 const int MaxTotalTrees = MaxTreesPerRank * tarch::mpi::Rank::getInstance().getNumberOfRanks();
34
35 const int MinMeshSizeToAccommodateMaxTotalTrees = _configuration->getMinTreeSize(_state) <= 1
36 ? MaxTotalTrees
37 : _configuration->getMinTreeSize(_state) * MaxTotalTrees;
38
39 // Mesh is stable, so we should just split up as aggressively as possible,
40 // even if we cannot keep all cores busy.
41 if (_numberOfStableGridIterations > 3) {
42 // min tree but at least give each rank something
43 const int MinTreeSize = std::max(_configuration->getMinTreeSize(_state), 1);
44
45 result = _statistics.getLocalNumberOfInnerUnrefinedCells() / MinTreeSize
47 logInfo(
48 "getNumberOfTreesPerRank()",
49 "mesh is stable, so create "
50 << result << " trees even though we might end up with fewer cells per tree than the lower bound "
51 << _configuration->getMinTreeSize(_state) << " or might not be able to use all cores"
52 );
53 } else if (_statistics.getLocalNumberOfInnerUnrefinedCells() >= MinMeshSizeToAccommodateMaxTotalTrees) {
54 result = MaxTotalTrees / tarch::mpi::Rank::getInstance().getNumberOfRanks();
55 logInfo(
56 "getNumberOfTreesPerRank()",
57 "mesh has "
58 << _statistics.getLocalNumberOfInnerUnrefinedCells() << " cells already, so create " << result
59 << " trees per rank (min tree size=" << _configuration->getMinTreeSize(_state)
60 << ", max-trees-per-rank=" << _configuration->getMaxLocalTreesPerRank(_state) << ")"
61 );
62 }
63 }
64
65 return result;
66}
67
68
70 if (_statistics.hasConsistentViewOfWorld() and _previousNumberOfCells == _statistics.getGlobalNumberOfInnerUnrefinedCells()) {
71 _numberOfStableGridIterations++;
72 } else {
73 _numberOfStableGridIterations = 0;
74 }
75
76 if (not tarch::mpi::Rank::getInstance().isGlobalMaster() and _state == State::InterRankDistribution) {
78 }
79
80 const int numberOfTreesPerRank = getNumberOfTreesPerRank();
81
82 if (numberOfTreesPerRank > 0) {
84
85 int cellsPerTree = std::max(
86 static_cast<int>(std::round(_statistics.getGlobalNumberOfInnerUnrefinedCells() / ranks / numberOfTreesPerRank)), 1
87 );
88
89 logInfo(
90 "updateLoadBalancing()",
91 "try to create "
92 << numberOfTreesPerRank << " trees per rank with internal state" << toString() << " to produce " << ranks << "x"
93 << numberOfTreesPerRank << " trees with approx " << cellsPerTree << " cells per tree"
94 );
95
96 int totalSplits = cellsPerTree;
97 for (int targetRank = 0; targetRank < ranks; targetRank++)
98 for (int treeNumber = targetRank == 0 ? 1 : 0; treeNumber < numberOfTreesPerRank; treeNumber++) {
99 int thisTreesCells = cellsPerTree;
100 if (static_cast<int>(_statistics.getGlobalNumberOfInnerUnrefinedCells()) % (ranks * numberOfTreesPerRank) >= totalSplits) {
101 thisTreesCells++;
102 }
103
104 triggerSplit(thisTreesCells, targetRank);
105
106 totalSplits++;
107 }
108
110 } else if (not _statistics.hasConsistentViewOfWorld()) {
111 _previousNumberOfCells = -1;
112 } else {
113 _previousNumberOfCells = _statistics.getGlobalNumberOfInnerUnrefinedCells();
114 }
115}
116
117
119 _statistics.updateGlobalView();
120 _costMetrics->updateGlobalView();
121 _blacklist.update();
122
123 _statistics.notifyOfStateChange(_state);
124
125 updateLoadBalancing();
127}
128
129
130void toolbox::loadbalancing::strategies::SpreadOut::triggerSplit(int numberOfCells, int targetRank) {
131 logInfo(
132 "triggerSplit(int,int,int)",
133 "trigger split from tree 0 into new tree on rank " << targetRank << " with " << numberOfCells << " cell(s)"
134 );
135
136 assertionEquals(peano4::parallel::SpacetreeSet::getInstance().getLocalSpacetrees().size(), 1);
137 assertion(tarch::mpi::Rank::getInstance().isGlobalMaster());
138
139 const int sourceTree = 0;
141 sourceTree, peano4::SplitInstruction{numberOfCells, _configuration->getMode(_state)}, targetRank
142 );
143 if (not success) {
144 logInfo("triggerSplit()", "wanted to split local rank " << sourceTree << " but failed");
145 }
146
147 _blacklist.triggeredSplit(sourceTree);
148 _statistics.incLocalNumberOfSplits();
149}
#define assertionEquals(lhs, rhs)
#define assertion(expr)
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
bool split(int treeId, const peano4::SplitInstruction &instruction, int targetRank)
Split a local tree.
static SpacetreeSet & getInstance()
Log Device.
Definition Log.h:516
int getNumberOfRanks() const
Definition Rank.cpp:552
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
static Core & getInstance()
Definition Core.cpp:56
int getNumberOfThreads() const
Returns the number of threads that is used.
Definition Core.cpp:67
Abstract interface to tweak the behaviour of the recursive subdivision.
void notifyOfStateChange(State state)
void triggerSplit(int numberOfCells, int targetRank)
virtual void finishStep() override
Finish the step.
SpreadOut(Configuration *configuration=new DefaultConfiguration(), CostMetrics *costMetrics=new toolbox::loadbalancing::metrics::CellCount())
Definition SpreadOut.cpp:12
int getNumberOfTreesPerRank() const
Return 0 if the load balancing should not split (yet) and otherwise return number of splits required.
Definition SpreadOut.cpp:26
std::string toString(Filter filter)
Definition convert.cpp:170
void dumpStatistics()
Dump the stats of the lb to the terminal (info device).
@ Stagnation
You usually don't get this state when we query the configuration, i.e.
@ InterRankDistribution
Code has not yet spread out over all ranks but would like to do so now.
Instruction to split.
Definition grid.h:34