Skip to content

Commit 4a29dfa

Browse files
committed
+ clustering support for the dynamic scheduler. Have been sitting on it for a while.
+ Some more minor fixes and timing informations. git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@22753 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 5be1807 commit 4a29dfa

File tree

8 files changed

+202
-10
lines changed

8 files changed

+202
-10
lines changed

SimulationRuntime/ParModelica/auto/Makefile.common

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ libom_pm_autort.a: $(OBJS)
3030
$(AR_) $@ $(OBJS)
3131

3232
.cpp.o: $(DPFILE)
33-
$(CC) $(CPPFLAGS) -c $<
33+
$(CC) $(CPPFLAGS) $(INCDIRS) -c $<
3434

3535
test: test_task_graph.cpp transfer
36-
$(CXX) $(CPPFLAGS) -I. test_task_graph.cpp -o gen_graph$(EXEEXT) libom_pm_autort.a -Wl,-rpath,$(TBB_LIB) -L$(TBB_LIB) -ltbb
36+
$(CXX) $(CPPFLAGS) -I. $(INCDIRS) test_task_graph.cpp -o gen_graph$(EXEEXT) libom_pm_autort.a -L$(TBB_LIB) -ltbb
3737

3838
clean :
3939
rm -f *.o *.a

SimulationRuntime/ParModelica/auto/om_pm_interface.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ void PM_functionInitialEquations(int size, void* data, FunctionType* functionIni
5656

5757
// pm_om_model.ini_system_funcs = functionInitialEquations_systems;
5858
// pm_om_model.INI_scheduler.execute();
59-
59+
pm_om_model.INI_scheduler.execution_timer.start_timer();
6060
for(int i = 0; i < size; ++i)
6161
functionInitialEquations_systems[i](data);
62+
pm_om_model.INI_scheduler.execution_timer.stop_timer();
63+
6264
}
6365

6466

@@ -67,19 +69,22 @@ void PM_functionDAE(int size, void* data, FunctionType* functionDAE_systems) {
6769
// pm_om_model.dae_system_funcs = functionDAE_systems;
6870
// pm_om_model.DAE_scheduler.execute();
6971

72+
pm_om_model.DAE_scheduler.execution_timer.start_timer();
7073
for(int i = 0; i < size; ++i)
7174
functionDAE_systems[i](data);
75+
pm_om_model.DAE_scheduler.execution_timer.stop_timer();
7276

7377
}
7478

7579

7680
void PM_functionODE(int size, void* data, FunctionType* functionODE_systems) {
7781

7882
pm_om_model.ODE_scheduler.execute();
79-
83+
84+
// pm_om_model.ODE_scheduler.execution_timer.start_timer();
8085
// for(int i = 0; i < size; ++i)
8186
// functionODE_systems[i](data);
82-
87+
// pm_om_model.ODE_scheduler.execution_timer.stop_timer();
8388
}
8489

8590
void PM_functionAlg(int size, void* data, FunctionType* functionAlg_systems) {
@@ -97,6 +102,7 @@ void dump_times() {
97102
utility::log("") << "Total INI: " << pm_om_model.INI_scheduler.execution_timer.get_elapsed_time() << std::endl;
98103
utility::log("") << "Total DAE: " << pm_om_model.DAE_scheduler.execution_timer.get_elapsed_time() << std::endl;
99104
utility::log("") << "Total ODE: " << pm_om_model.ODE_scheduler.execution_timer.get_elapsed_time() << std::endl;
105+
utility::log("") << "Total ODE: " << pm_om_model.ODE_scheduler.clustering_timer.get_elapsed_time() << std::endl;
100106
utility::log("") << "Total ALG: " << pm_om_model.total_alg_time.get_elapsed_time() << std::endl;
101107
}
102108

SimulationRuntime/ParModelica/auto/om_pm_model.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ bool Equation::depends_on(const TaskNode& other_b) const {
7676

7777

7878
void Equation::execute() {
79-
function_system[node_id](data);
79+
function_system[task_id](data);
8080
}
8181

8282

SimulationRuntime/ParModelica/auto/om_pm_model.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "pm_task_system.hpp"
4444
#include "pm_cluster_level_scheduler.hpp"
45+
#include "pm_cluster_dynamic_scheduler.hpp"
4546

4647
#include "pm_level_scheduler.hpp"
4748
#include "pm_dynamic_scheduler.hpp"
@@ -91,6 +92,7 @@ class OMModel : boost::noncopyable {
9192
// typedef TaskSystem<Equation> TaskSystemT;
9293

9394
typedef StepLevels<Equation> SchedulerT;
95+
// typedef ClusterDynamicScheduler<Equation> SchedulerT;
9496
typedef TaskSystem_v2<Equation> TaskSystemT;
9597

9698

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#pragma once
2+
#ifndef id776A2949_F8C6_41C1_8E5205C1984621C1
3+
#define id776A2949_F8C6_41C1_8E5205C1984621C1
4+
5+
/*
6+
* This file is part of OpenModelica.
7+
*
8+
* Copyright (c) 1998-CurrentYear, Linköping University,
9+
* Department of Computer and Information Science,
10+
* SE-58183 Linköping, Sweden.
11+
*
12+
* All rights reserved.
13+
*
14+
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3
15+
* AND THIS OSMC PUBLIC LICENSE (OSMC-PL).
16+
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
17+
* ACCEPTANCE OF THE OSMC PUBLIC LICENSE.
18+
*
19+
* The OpenModelica software and the Open Source Modelica
20+
* Consortium (OSMC) Public License (OSMC-PL) are obtained
21+
* from Linköping University, either from the above address,
22+
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
23+
* http://www.openmodelica.org, and in the OpenModelica distribution.
24+
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
25+
*
26+
* This program is distributed WITHOUT ANY WARRANTY; without
27+
* even the implied warranty of MERCHANTABILITY or FITNESS
28+
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
29+
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
30+
* OF OSMC-PL.
31+
*
32+
* See the full OSMC Public License conditions for more details.
33+
*
34+
*/
35+
36+
37+
/*
38+
Mahder.Gebremedhin@liu.se 2014-03-06
39+
*/
40+
41+
#include <tbb/flow_graph.h>
42+
#include <tbb/task_scheduler_init.h>
43+
44+
#include "pm_clustering.hpp"
45+
46+
47+
namespace openmodelica {
48+
namespace parmodelica {
49+
50+
template<typename TaskType>
51+
struct ClusterLauncher {
52+
typedef TaskSystem_v2<TaskType> TaskSystemType;
53+
typedef typename TaskSystemType::ClusterType ClusterType;
54+
private:
55+
ClusterType& clust;
56+
57+
public:
58+
ClusterLauncher(ClusterType& c)
59+
: clust(c)
60+
{}
61+
62+
void operator()( tbb::flow::continue_msg ) const {
63+
clust.execute();
64+
}
65+
};
66+
67+
template<typename TaskType>
68+
class ClusterDynamicScheduler {
69+
public:
70+
typedef TaskSystem_v2<TaskType> TaskSystemType;
71+
72+
typedef typename TaskSystemType::GraphType GraphType;
73+
typedef typename TaskSystemType::ClusterType ClusterType;
74+
typedef typename TaskSystemType::ClusterIdType ClusterIdType;
75+
76+
typedef typename TaskType::FunctionType FunctionType;
77+
78+
private:
79+
tbb::task_scheduler_init tbb_system;
80+
81+
tbb::flow::graph dynamic_graph;
82+
tbb::flow::broadcast_node<tbb::flow::continue_msg> flow_root;
83+
84+
bool flow_graph_created;
85+
86+
87+
std::map<ClusterIdType, tbb::flow::continue_node<tbb::flow::continue_msg>* > cluster_flow_id_map;
88+
89+
public:
90+
PMTimer execution_timer;
91+
PMTimer clustering_timer;
92+
TaskSystemType& task_system;
93+
94+
ClusterDynamicScheduler(TaskSystemType& task_system)
95+
: tbb_system()
96+
, flow_root(dynamic_graph)
97+
, flow_graph_created(false)
98+
, task_system(task_system)
99+
{
100+
}
101+
102+
void schedule() {
103+
clustering_timer.start_timer();
104+
cluster_merge_common::apply(task_system);
105+
cluster_merge_common::dump_graph(task_system);
106+
construct_flow_graph();
107+
clustering_timer.stop_timer();
108+
}
109+
110+
void construct_flow_graph()
111+
{
112+
113+
using namespace tbb;
114+
GraphType& sys_graph = task_system.sys_graph;
115+
ClusterIdType& root_node_id = task_system.root_node_id;
116+
117+
typename GraphType::vertex_iterator vert_iter, vert_end;
118+
boost::tie(vert_iter, vert_end) = vertices(sys_graph);
119+
120+
/*! skip the root node. */
121+
++vert_iter;
122+
for ( ; vert_iter != vert_end; ++vert_iter) {
123+
ClusterIdType& curr_clust_id = *vert_iter;
124+
ClusterType& curr_clust = sys_graph[curr_clust_id];
125+
// std::cout << "adding " << curr_b_node.index << std::endl;
126+
127+
/*! create new flow node for tbb. */
128+
flow::continue_node<flow::continue_msg>* curr_f_node =
129+
new flow::continue_node<flow::continue_msg>(dynamic_graph,
130+
ClusterLauncher<TaskType>(curr_clust));
131+
132+
/*! create a maping. we use it to add edges from this node to its children later. */
133+
cluster_flow_id_map.insert(std::make_pair(curr_clust_id,curr_f_node));
134+
135+
/*! Iterate through all parents of the current node and add edges.*/
136+
typename GraphType::inv_adjacency_iterator par_iter, par_end;
137+
boost::tie(par_iter, par_end) = inv_adjacent_vertices( curr_clust_id, sys_graph );
138+
for(; par_iter != par_end; ++par_iter) {
139+
const ClusterIdType& curr_parent_id = *par_iter;
140+
// ClusterType& curr_parent = sys_graph[curr_parent_id];
141+
/*! the parent is the root in the task_graph. So here connect it to
142+
the root of the flow graph*/
143+
if(curr_parent_id == root_node_id) {
144+
flow::make_edge(flow_root, *curr_f_node);
145+
// std::cout << " edge to root " << std::endl;
146+
}
147+
else {
148+
flow::make_edge(*(cluster_flow_id_map.at(curr_parent_id)), *curr_f_node);
149+
// std::cout << " edge to " << sys_graph[*par_iter].index << std::endl;
150+
}
151+
}
152+
}
153+
154+
flow_graph_created = true;
155+
}
156+
157+
158+
void execute() {
159+
160+
if(!flow_graph_created) {
161+
construct_flow_graph();
162+
}
163+
164+
execution_timer.start_timer();
165+
flow_root.try_put( tbb::flow::continue_msg() );
166+
dynamic_graph.wait_for_all();
167+
execution_timer.stop_timer();
168+
}
169+
170+
};
171+
172+
173+
174+
} // parmodelica
175+
} // openmodelica
176+
177+
178+
179+
180+
#endif // header

SimulationRuntime/ParModelica/auto/pm_cluster_level_scheduler.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class StepLevels :
112112
public:
113113

114114
PMTimer execution_timer;
115+
PMTimer clustering_timer;
115116

116117
StepLevels(TaskSystemType& ts) :
117118
task_system(ts)
@@ -156,6 +157,8 @@ class StepLevels :
156157
if(schedule_valid)
157158
return;
158159

160+
clustering_timer.start_timer();
161+
159162
if(task_system.levels_valid == false)
160163
task_system.update_node_levels();
161164

@@ -180,6 +183,7 @@ class StepLevels :
180183
task_system.levels_valid = false;
181184

182185
estimate_speedup();
186+
clustering_timer.stop_timer();
183187

184188
}
185189

SimulationRuntime/ParModelica/auto/pm_cluster_system.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ namespace parmodelica {
6161
// , cost(0)
6262
// {};
6363

64-
// long node_id;
64+
// long task_id;
6565
// int level;
6666
// double cost;
6767

@@ -250,7 +250,7 @@ class TaskSystem_v2 : boost::noncopyable {
250250
total_cost = 0;
251251
root_node_id = boost::add_vertex(sys_graph);
252252
TaskType& root_node = sys_graph[root_node_id].add_task(TaskType());
253-
root_node.node_id = -1;
253+
root_node.task_id = -1;
254254
}
255255

256256
TaskType& add_node(const TaskType& task)
@@ -261,7 +261,7 @@ class TaskSystem_v2 : boost::noncopyable {
261261
ClusterType& new_clust = sys_graph[new_clust_id];
262262

263263
TaskType& new_task = new_clust.add_task(task);
264-
new_task.node_id = node_count;
264+
new_task.task_id = node_count;
265265
++node_count;
266266

267267
int parent_count = 0;

SimulationRuntime/ParModelica/auto/pm_task_system.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct TaskNode {
5959
, cost(0)
6060
{};
6161

62-
long node_id;
62+
long task_id;
6363
int level;
6464
double cost;
6565

0 commit comments

Comments
 (0)