DPsim
Loading...
Searching...
No Matches
OpenMPLevelScheduler.cpp
1/* Copyright 2017-2021 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#include <dpsim/OpenMPLevelScheduler.h>
10#include <omp.h>
11
12#include <iostream>
13
14using namespace CPS;
15using namespace DPsim;
16
17OpenMPLevelScheduler::OpenMPLevelScheduler(Int threads,
18 String outMeasurementFile)
19 : mOutMeasurementFile(outMeasurementFile) {
20 if (threads >= 0)
21 mNumThreads = threads;
22 else
23 mNumThreads = omp_get_num_threads();
24}
25
26void OpenMPLevelScheduler::createSchedule(const Task::List &tasks,
27 const Edges &inEdges,
28 const Edges &outEdges) {
29 Task::List ordered;
30
31 Scheduler::topologicalSort(tasks, inEdges, outEdges, ordered);
32 Scheduler::levelSchedule(ordered, inEdges, outEdges, mLevels);
33
34 if (!mOutMeasurementFile.empty())
35 Scheduler::initMeasurements(tasks);
36}
37
38void OpenMPLevelScheduler::step(Real time, Int timeStepCount) {
39 long i, level = 0;
40 std::chrono::steady_clock::time_point start, end;
41
42 if (!mOutMeasurementFile.empty()) {
43#pragma omp parallel shared(time, timeStepCount) private(level, i, start, end) \
44 num_threads(mNumThreads)
45 for (level = 0; level < static_cast<long>(mLevels.size()); level++) {
46 {
47#pragma omp for schedule(static)
48 for (i = 0; i < static_cast<long>(mLevels[level].size()); i++) {
49 start = std::chrono::steady_clock::now();
50 mLevels[level][i]->execute(time, timeStepCount);
51 end = std::chrono::steady_clock::now();
52 updateMeasurement(mLevels[level][i].get(), end - start);
53 }
54 }
55 }
56 } else {
57#pragma omp parallel shared(time, timeStepCount) private(level, i) \
58 num_threads(mNumThreads)
59 for (level = 0; level < static_cast<long>(mLevels.size()); level++) {
60 {
61#pragma omp for schedule(static)
62 for (i = 0; i < static_cast<long>(mLevels[level].size()); i++) {
63 mLevels[level][i]->execute(time, timeStepCount);
64 }
65 }
66 }
67 }
68}
69
71 if (!mOutMeasurementFile.empty()) {
72 writeMeasurements(mOutMeasurementFile);
73 }
74}
void step(Real time, Int timeStepCount)
Performs a single simulation step.
void stop()
Called on simulation stop to reliably clean up e.g. running helper threads.
void createSchedule(const CPS::Task::List &tasks, const Edges &inEdges, const Edges &outEdges)
Creates the schedule for the given dependency graph.
void writeMeasurements(CPS::String filename)
Write measurement data to file.
Definition Scheduler.cpp:32
void topologicalSort(const CPS::Task::List &tasks, const Edges &inEdges, const Edges &outEdges, CPS::Task::List &sortedTasks)
Simple topological sort, filtering out tasks that do not need to be executed.
static void levelSchedule(const CPS::Task::List &tasks, const Edges &inEdges, const Edges &outEdges, std::vector< CPS::Task::List > &levels)
std::unordered_map< CPS::Task::Ptr, std::deque< CPS::Task::Ptr > > Edges
Definition Scheduler.h:31
void updateMeasurement(CPS::Task *task, TaskTime time)
Definition Scheduler.cpp:28