Peano
Loading...
Searching...
No Matches
multicore.cpp
Go to the documentation of this file.
1// This file is part of the Peano project. For conditions of distribution and
2// use, please see the copyright notice at www.peano-framework.org
3#include "multicore.h"
4#include "tarch/Assertions.h"
5#include "tarch/mpi/Rank.h"
7
8#ifdef UseSmartMPI
9#include "smartmpi.h"
10#include "topology/topologies.h"
11#endif
12
19
21
22
23namespace {
25
26 tarch::logging::Log _log("tarch::multicore");
27
28 const std::string BSPConcurrencyLevelStatisticsIdentifier("tarch::multicore::bsp-concurrency-level");
29 const std::string SpawnedTasksStatisticsIdentifier("tarch::multicore::spawned-tasks");
30}
31
32
34 #ifdef UseSmartMPI
35 using namespace smartmpi::topology;
36 typedef UseSmartMPI MyTopology;
37 smartmpi::topology::Topology* smartMPITopology = new MyTopology(
38 tarch::mpi::Rank::getInstance().getCommunicator()
39 );
40 smartmpi::init( smartMPITopology );
41
42 smartmpi::appendToSchedulerChain( "HardcodedMigrationScheduler" );
43
44 tarch::mpi::Rank::getInstance().setCommunicator( smartMPITopology->computeNodeOrSmartServerCommunicator );
45 #endif
46}
47
48
50 #ifdef UseSmartMPI
51 smartmpi::shutdown();
52 #endif
53}
54
55
57 assertion(orchestrationStrategy != nullptr);
58 assertion(realisation != nullptr);
59
60 delete orchestrationStrategy;
61 orchestrationStrategy = realisation;
62}
63
64
66 assertion(orchestrationStrategy != nullptr);
67 assertion(realisation != nullptr);
68
69 tarch::multicore::orchestration::Strategy* result = orchestrationStrategy;
70 orchestrationStrategy = realisation;
71 return result;
72}
73
74
78
79
80void tarch::multicore::waitForTasks(const std::set<TaskNumber>& inDependencies) {
81 tarch::multicore::native::waitForTasks(inDependencies);
82}
83
84
85void tarch::multicore::waitForTask(const int taskNumber) {
86 std::set<int> tmp{taskNumber};
87 waitForTasks(tmp);
88}
89
90
91void tarch::multicore::spawnAndWait(const std::vector<Task*>& tasks) {
92 static tarch::logging::Log _log("tarch::multicore");
93
94 if (not tasks.empty()) {
95 static int nestedSpawnAndWaits = 0;
96 static tarch::multicore::BooleanSemaphore nestingSemaphore;
97
98 tarch::multicore::Lock nestingLock(nestingSemaphore, false);
99 nestingLock.lock();
100 nestedSpawnAndWaits++;
101 const int localNestedSpawnAndWaits = nestedSpawnAndWaits;
102 nestingLock.free();
103
104 orchestrationStrategy->startBSPSection(localNestedSpawnAndWaits);
105
106 switch (orchestrationStrategy->paralleliseForkJoinSection(localNestedSpawnAndWaits, tasks.size(), tasks[0]->getTaskType())) {
108 for (auto& p : tasks) {
109 p->run();
110 delete p;
111 }
112 break;
114 ::tarch::logging::Statistics::getInstance().inc(BSPConcurrencyLevelStatisticsIdentifier, static_cast<int>(tasks.size()), true);
115 native::spawnAndWaitAsTaskLoop(tasks);
116 ::tarch::logging::Statistics::getInstance().inc(BSPConcurrencyLevelStatisticsIdentifier, -static_cast<int>(tasks.size()), true);
117 break;
118 }
119
120 orchestrationStrategy->endBSPSection(localNestedSpawnAndWaits);
121
122 nestingLock.lock();
123 nestedSpawnAndWaits--;
124 nestingLock.free();
125 }
126}
127
128
133
134
136 Task* task,
137 const std::set<TaskNumber>& inDependencies,
138 const TaskNumber& taskNumber
139) {
140 assertion(task != nullptr);
141
142 tarch::logging::Statistics::getInstance().inc(SpawnedTasksStatisticsIdentifier, 1, false, true);
143
144 if (task->canFuse()) {
145 taskfusion::translateFusableTaskIntoTaskSequence(task, inDependencies, taskNumber);
146 }
147 else {
148 native::spawnTask(task, inDependencies, taskNumber);
149 }
150}
151
152
153void tarch::multicore::processFusedTask(Task* myTask, const std::list<tarch::multicore::Task*>& tasksOfSameType, int device) {
154 myTask->fuse(tasksOfSameType, device);
155 for (auto& p: tasksOfSameType) {
156 delete p;
157 }
158 delete myTask;
159}
160
161
162#ifndef SharedMemoryParallelisation
163
164void tarch::multicore::native::spawnAndWaitAsTaskLoop(const std::vector<Task*>& tasks) {
165 for (auto& p : tasks) {
166 p->run();
167 delete p;
168 }
169}
170
171
172void tarch::multicore::native::spawnTask(
173 Task* job,
174 const std::set<TaskNumber>& /*inDependencies*/,
175 const TaskNumber& /*taskNumber*/
176) {
177 job->run();
178 delete job;
179}
180
181
182void tarch::multicore::native::waitForTasks(const std::set<TaskNumber>& /*inDependencies*/) {}
183
184
185void tarch::multicore::native::waitForAllTasks() {}
186
187#endif
#define assertion(expr)
tarch::logging::Log _log("::")
Log Device.
Definition Log.h:516
void inc(const std::string &identifier, double value=1.0, bool disableSampling=false, bool clearAfterDatabaseDump=false)
Definition Statistics.h:107
static Statistics & getInstance()
This is not the canonical realisation of singletons as I use it usually for stats in Peano.
void setCommunicator(MPI_Comm communicator, bool recomputeRankAndWorld=true)
Set communicator to be used by Peano.
Definition Rank.cpp:576
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
Create a lock around a boolean semaphore region.
Definition Lock.h:19
void free()
Free the lock.
Definition Lock.cpp:37
Abstract super class for a job.
Definition Task.h:21
virtual bool canFuse() const
Definition Task.cpp:31
virtual void fuse(const std::list< Task * > &otherTasks, int targetDevice=Host)
Fuse multiple tasks.
Definition Task.cpp:42
Interface for any task orchestration.
Definition Strategy.h:36
void spawnAndWaitAsTaskLoop(const std::vector< tarch::multicore::Task * > &tasks)
Map onto native tasking.
Definition Tasks.cpp:111
Strategy * createDefaultStrategy()
Default strategy.
Definition Strategy.cpp:4
void shutdownSmartMPI()
Definition multicore.cpp:49
tarch::multicore::orchestration::Strategy & getOrchestration()
Definition multicore.cpp:75
void processFusedTask(Task *myTask, const std::list< tarch::multicore::Task * > &tasksOfSameType, int device)
Process a fused task.
void waitForTask(const int taskNumber)
Wrapper around waitForTasks() with a single-element set.
Definition multicore.cpp:85
void waitForTasks(const std::set< TaskNumber > &inDependencies)
Wait for set of tasks.
Definition multicore.cpp:80
void setOrchestration(tarch::multicore::orchestration::Strategy *realisation)
Definition multicore.cpp:56
void spawnAndWait(const std::vector< Task * > &tasks)
Fork-join task submission pattern.
Definition multicore.cpp:91
void waitForAllTasks()
Wait for all tasks notably has to take fused tasks into account.
tarch::multicore::orchestration::Strategy * swapOrchestration(tarch::multicore::orchestration::Strategy *realisation)
Swap the active orchestration.
Definition multicore.cpp:65
void spawnTask(Task *task, const std::set< TaskNumber > &inDependencies=tarch::multicore::NoInDependencies, const TaskNumber &taskNumber=tarch::multicore::NoOutDependencies)
Spawns a single task in a non-blocking fashion.
void initSmartMPI()
Switch on SmartMPI.
Definition multicore.cpp:33