9 #include <dpsim/Scheduler.h>
13 #include <unordered_map>
14 #include <unordered_set>
17 using namespace DPsim;
21 void Scheduler::initMeasurements(
const Task::List &tasks) {
23 for (
auto task : tasks) {
24 mMeasurements[task.get()] = std::vector<TaskTime>();
29 mMeasurements[ptr].push_back(time);
32 void Scheduler::writeMeasurements(String filename) {
33 std::ofstream os(filename);
34 std::unordered_map<String, TaskTime> averages;
35 for (
auto &pair : mMeasurements) {
36 averages[pair.first->toString()] = getAveragedMeasurement(pair.first);
39 for (
auto pair : averages) {
40 os << pair.first <<
"," << pair.second.count() << std::endl;
45 void Scheduler::readMeasurements(
46 String filename, std::unordered_map<String, TaskTime::rep> &measurements) {
47 std::ifstream fs(filename);
54 std::getline(fs, line);
55 int idx =
static_cast<UInt
>(line.find(
','));
61 measurements[line.substr(0, idx)] = std::stol(line.substr(idx + 1));
66 TaskTime avg(0), tot(0);
68 for (TaskTime time : mMeasurements[task]) {
72 if (!mMeasurements[task].empty())
73 avg = tot / mMeasurements[task].size();
78 void Scheduler::resolveDeps(Task::List &tasks,
Edges &inEdges,
81 tasks.push_back(mRoot);
82 std::unordered_map<AttributeBase::Ptr, std::deque<Task::Ptr>,
83 std::hash<AttributeBase::Ptr>,
86 std::unordered_set<AttributeBase::Ptr, std::hash<AttributeBase::Ptr>,
89 for (
auto task : tasks) {
92 if (attr.getPtr() != Scheduler::external.getPtr()) {
93 AttributeBase::Set attrDependencies = attr->getDependencies();
95 dependencies[dep].push_back(task);
98 dependencies[attr].push_back(task);
102 prevStepDependencies.insert(attr);
106 for (
auto from : tasks) {
108 for (
auto to : dependencies[attr]) {
109 outEdges[from].push_back(to);
110 inEdges[to].push_back(from);
112 if (prevStepDependencies.count(attr)) {
113 outEdges[from].push_back(mRoot);
114 inEdges[mRoot].push_back(from);
120 void Scheduler::topologicalSort(
const Task::List &tasks,
const Edges &inEdges,
121 const Edges &outEdges,
122 Task::List &sortedTasks) {
127 Edges inEdgesCpy = inEdges, outEdgesCpy = outEdges;
131 std::deque<Task::Ptr> q;
132 std::unordered_set<Task::Ptr> visited;
138 if (visited.count(t))
142 for (
auto dep : inEdgesCpy[t]) {
143 if (!visited.count(dep)) {
149 for (
auto t : tasks) {
150 if (inEdgesCpy[t].empty()) {
157 Task::Ptr t = q.front();
159 if (!visited.count(t)) {
162 SPDLOG_LOGGER_INFO(mSLog,
"Dropping {:s}", t->toString());
163 }
else if (t != mRoot) {
164 sortedTasks.push_back(t);
167 for (
auto after : outEdgesCpy[t]) {
168 for (
auto edgeIt = inEdgesCpy[after].begin();
169 edgeIt != inEdgesCpy[after].end(); ++edgeIt) {
171 inEdgesCpy[after].erase(edgeIt);
175 if (inEdgesCpy[after].empty()) {
179 outEdgesCpy.erase(t);
184 for (
auto t : tasks) {
185 if (!outEdgesCpy[t].empty() || !inEdgesCpy[t].empty())
190 void Scheduler::levelSchedule(
const Task::List &tasks,
const Edges &inEdges,
191 const Edges &outEdges,
192 std::vector<Task::List> &levels) {
193 std::unordered_map<Task::Ptr, int> time;
195 for (
auto task : tasks) {
196 if (inEdges.find(task) == inEdges.end() || inEdges.at(task).empty()) {
200 for (
auto before : inEdges.at(task)) {
201 if (time[before] > maxdist)
202 maxdist = time[before];
204 time[task] = maxdist + 1;
209 levels.resize(time[tasks.back()] + 1);
210 for (
auto task : tasks) {
211 levels[time[task]].push_back(task);
215 void BarrierTask::addBarrier(
Barrier *b) { mBarriers.push_back(b); }
217 void BarrierTask::execute(Real time, Int timeStepCount) {
218 if (mBarriers.size() == 1) {
219 mBarriers[0]->wait();
221 for (
size_t i = 0; i < mBarriers.size() - 1; i++) {
222 mBarriers[i]->signal();
224 mBarriers[mBarriers.size() - 1]->wait();
Tasks to be defined by every component.
std::unordered_map< CPS::Task::Ptr, std::deque< CPS::Task::Ptr > > Edges
std::chrono::steady_clock::duration TaskTime
Time measurement for the task execution.