Peano
Loading...
Searching...
No Matches
SamplingMulticoreOrchestration.cpp
Go to the documentation of this file.
2
5
6#include <limits>
7
9 int numberOfTasksToHoldBack_,
10 FuseInstruction fusionInstruction_,
11 bool fuseTasksImmediatelyWhenSpawned_,
12 bool processPendingTasksWhileWaiting_
13):
14 numberOfTasksToHoldBack(numberOfTasksToHoldBack_),
15 fusionInstruction(fusionInstruction_),
16 fuseTasksImmediatelyWhenSpawned(fuseTasksImmediatelyWhenSpawned_),
17 processPendingTasksWhileWaiting(processPendingTasksWhileWaiting_) {}
18
20 return numberOfTasksToHoldBack<other.numberOfTasksToHoldBack
21 or (numberOfTasksToHoldBack==other.numberOfTasksToHoldBack and fusionInstruction.device<other.fusionInstruction.device)
22 or (numberOfTasksToHoldBack==other.numberOfTasksToHoldBack and fusionInstruction.device==other.fusionInstruction.device and fusionInstruction.minTasks<other.fusionInstruction.minTasks)
23 or (numberOfTasksToHoldBack==other.numberOfTasksToHoldBack and fusionInstruction.device==other.fusionInstruction.device and fusionInstruction.minTasks==other.fusionInstruction.minTasks and fusionInstruction.maxTasks<other.fusionInstruction.maxTasks)
24 or (numberOfTasksToHoldBack==other.numberOfTasksToHoldBack and fusionInstruction.device==other.fusionInstruction.device and fusionInstruction.minTasks==other.fusionInstruction.minTasks and fusionInstruction.maxTasks==other.fusionInstruction.maxTasks and fuseTasksImmediatelyWhenSpawned<other.fuseTasksImmediatelyWhenSpawned)
25 or (numberOfTasksToHoldBack==other.numberOfTasksToHoldBack and fusionInstruction.device==other.fusionInstruction.device and fusionInstruction.minTasks==other.fusionInstruction.minTasks and fusionInstruction.maxTasks==other.fusionInstruction.maxTasks and fuseTasksImmediatelyWhenSpawned==other.fuseTasksImmediatelyWhenSpawned and processPendingTasksWhileWaiting<other.processPendingTasksWhileWaiting);
26}
27
29 std::ostringstream msg;
30 msg
31 << "(hold-back=" << numberOfTasksToHoldBack << ",device=" << fusionInstruction.device << ",min-tasks="
32 << fusionInstruction.minTasks << ",max-tasks=" << fusionInstruction.maxTasks << ",fuse-immediately="
33 << fuseTasksImmediatelyWhenSpawned << ",process-pending=" << processPendingTasksWhileWaiting << ")";
34 return msg.str();
35}
36
38 probability(probability_) {}
39
41 "GeneticOptimisation");
42
44 _activeKey(0, FuseInstruction(-1, std::numeric_limits<int>::max(), 0), false, false),
45 _currentWatch("tarch::multicore::orchestration::GeneticOptimisation", "GeneticOptimisation", false, false),
46 _lastDuration(-1.0),
50 normalise();
51}
52
54 const int MaxInitialRage = 16;
55 for (int numberOfTasksToHoldBack = 0; numberOfTasksToHoldBack <= MaxInitialRage; numberOfTasksToHoldBack++)
56 for (int maxTasksToFuse = 0; maxTasksToFuse <= MaxInitialRage; maxTasksToFuse++)
57 for (int minTasksToFuse = 0; minTasksToFuse <= maxTasksToFuse; minTasksToFuse++)
58 for (int targetDevice = -1; targetDevice <= tarch::multicore::Core::getInstance().getNumberOfGPUs();
59 targetDevice++)
60 for (int fuseTasksImmediatelyWhenSpawned = 0; fuseTasksImmediatelyWhenSpawned < 2;
61 fuseTasksImmediatelyWhenSpawned++)
62 for (int processPendingTasksWhileWaiting = 0; processPendingTasksWhileWaiting < 2;
63 processPendingTasksWhileWaiting++) {
64 _configurationVariants.insert(std::pair<Key, Value>(
65 Key(
66 numberOfTasksToHoldBack,
67 FuseInstruction(targetDevice, minTasksToFuse, maxTasksToFuse),
68 fuseTasksImmediatelyWhenSpawned == 0,
69 processPendingTasksWhileWaiting == 0
70 ),
71 Value(1.0)
72 ));
73 }
74}
75
77 double sumOfProbabilities = 0.0;
78 for (auto& p : _configurationVariants) {
79 sumOfProbabilities += p.second.probability;
80 }
81 logInfo(
82 "normalise()",
83 "have "
84 << _configurationVariants.size() << " potential configurations. Renormalise total total probability of "
85 << sumOfProbabilities
86 );
87 for (auto& p : _configurationVariants) {
88 p.second.probability /= sumOfProbabilities;
89 }
90}
91
93 if (nestedParallelismLevel <= 1 and _bspRunThroughsWithActiveKey == 0) {
94 _currentWatch.start();
95 }
96}
97
99 if (nestedParallelismLevel <= 1) {
100 const int BSPRunThroughsWithActiveKey = 16;
101 _bspRunThroughsWithActiveKey++;
102
103 if (_bspRunThroughsWithActiveKey >= BSPRunThroughsWithActiveKey) {
104 _bspRunThroughsWithActiveKey = 0;
105
106 _currentWatch.stop();
107 double newValue = _currentWatch.getCalendarTime();
108
109 constexpr double Min = 1e-8;
110 if (newValue > Min) {
111 // update stats
112 _configurationVariants.at(_activeKey).measurement.setValue(newValue);
113
114 // update probabilities. Increase local ones if appropriate and then re-normalise
115 if (_lastDuration > Min and _lastDuration > _configurationVariants.at(_activeKey).measurement.getValue()) {
116 increaseProbabilityOfActiveConfiguration();
117 removeUnreasonableProbabilities();
118 normalise();
119 }
120 _lastDuration = _configurationVariants.at(_activeKey).measurement.getValue();
121
122 pickNewActiveConfigurationRandomly();
123 }
124 }
125 }
126}
127
129 Key left(
130 _activeKey.numberOfTasksToHoldBack - 1,
131 _activeKey.fusionInstruction,
132 _activeKey.fuseTasksImmediatelyWhenSpawned,
133 _activeKey.processPendingTasksWhileWaiting
134 );
135 Key right(
136 _activeKey.numberOfTasksToHoldBack - 1,
137 _activeKey.fusionInstruction,
138 _activeKey.fuseTasksImmediatelyWhenSpawned,
139 _activeKey.processPendingTasksWhileWaiting
140 );
141 Key down(
142 _activeKey.numberOfTasksToHoldBack,
144 _activeKey.fusionInstruction.device,
145 _activeKey.fusionInstruction.minTasks,
146 _activeKey.fusionInstruction.maxTasks + 1
147 ),
148 _activeKey.fuseTasksImmediatelyWhenSpawned,
149 _activeKey.processPendingTasksWhileWaiting
150 );
151 Key up(
152 _activeKey.numberOfTasksToHoldBack,
154 _activeKey.fusionInstruction.device,
155 _activeKey.fusionInstruction.minTasks + 1,
156 _activeKey.fusionInstruction.maxTasks + 1
157 ),
158 _activeKey.fuseTasksImmediatelyWhenSpawned,
159 _activeKey.processPendingTasksWhileWaiting
160 );
161 if (_configurationVariants.count(left) == 0) {
162 _configurationVariants.insert(std::pair<Key, Value>(left, Value(_configurationVariants.at(_activeKey).probability))
163 );
164 logInfo("increaseProbabilityOfActiveConfiguration()", "insert new potential configuration " << left.toString());
165 }
166 if (_configurationVariants.count(right) == 0) {
167 _configurationVariants.insert(std::pair<Key, Value>(right, Value(_configurationVariants.at(_activeKey).probability))
168 );
169 logInfo("increaseProbabilityOfActiveConfiguration()", "insert new potential configuration " << right.toString());
170 }
171 if (_configurationVariants.count(down) == 0) {
172 _configurationVariants.insert(std::pair<Key, Value>(down, Value(_configurationVariants.at(_activeKey).probability))
173 );
174 logInfo("increaseProbabilityOfActiveConfiguration()", "insert new potential configuration " << down.toString());
175 }
176 if (_configurationVariants.count(up) == 0) {
177 _configurationVariants.insert(std::pair<Key, Value>(up, Value(_configurationVariants.at(_activeKey).probability)));
178 logInfo("increaseProbabilityOfActiveConfiguration()", "insert new potential configuration " << up.toString());
179 }
180
181 _configurationVariants.at(_activeKey).probability *= 1.1;
182}
183
185 constexpr double MinValue = 1e-8;
186
187 double MinProbability = 0.1 / _configurationVariants.size();
188
189 std::map<Key, Value>::iterator p = _configurationVariants.begin();
190 while (p != _configurationVariants.end()) {
191 if (p->second.measurement.getValue() > MinProbability and p->second.probability <= MinProbability) {
192 logInfo(
193 "removeUnreasonableProbabilities()",
194 "remove option " << p->first.toString() << " as it has low probability (" << p->second.probability << ")"
195 );
196 p = _configurationVariants.erase(p);
197 } else {
198 p++;
199 }
200 }
201}
202
204 double targetIntegrand = static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX);
205 double currentIntegrand = 0.0;
206
207 std::map<Key, Value>::iterator p = _configurationVariants.begin();
208 currentIntegrand += p->second.probability;
209 while (currentIntegrand < targetIntegrand) {
210 currentIntegrand += p->second.probability;
211 p++;
212 }
213 if (p == _configurationVariants.end()) {
214 p = _configurationVariants.begin();
215 }
216
217 _activeKey = p->first;
218 logInfo("pickNewActiveConfigurationRandomly()", "picked key " << _activeKey.toString());
219}
220
222 return _activeKey.numberOfTasksToHoldBack;
223}
224
227 _currentDevice++;
228 _currentDevice = _currentDevice % tarch::multicore::Core::getInstance().getNumberOfGPUs();
229 auto result = _activeKey.fusionInstruction;
230 result.device = _currentDevice;
231 return result;
232}
233
235 return _activeKey.fuseTasksImmediatelyWhenSpawned;
236}
237
238bool tarch::multicore::orchestration::GeneticOptimisation::processPendingTasksWhileWaitingInBSPSection() {
239 return _activeKey.processPendingTasksWhileWaiting;
240}
241
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
Log Device.
Definition Log.h:516
static Core & getInstance()
Definition Core.cpp:56
virtual ExecutionPolicy paralleliseForkJoinSection(int nestedParallelismLevel, int numberOfTasks, int taskType) override
Determine how to handle/realise parallelisation within fork/join region.
ExecutionPolicy
Provide hint of execution policy.
Definition Strategy.h:38
STL namespace.
Key(int numberOfTasksToHoldBack_, FuseInstruction fusionInstruction_, bool fuseTasksImmediatelyWhenSpawned_, bool processPendingTasksWhileWaiting_)