Skip to content

Commit

Permalink
+ Preparing the run-time for multi-thread execution.
Browse files Browse the repository at this point in the history
+ Moved performSimulation from simulation runtime to generated code.
+ Fixed omp undefined references. 
+ Generate extra equation info. Just the crefs used in equation. To build graphs later.
+ Hope nothing fails.

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15893 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
mahge committed Apr 23, 2013
1 parent 84aecc2 commit 37464d0
Show file tree
Hide file tree
Showing 10 changed files with 560 additions and 211 deletions.
3 changes: 3 additions & 0 deletions Compiler/BackEnd/SimCodeUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -11937,6 +11937,7 @@ algorithm
PriorityQueue.T q;
list<tuple<Integer, list<SimCode.SimEqSystem>>> prios;
list<list<SimCode.SimEqSystem>> lst;
String eq_str;

case (lst, _)
equation
Expand All @@ -11947,6 +11948,8 @@ algorithm
case (lst, 1)
equation
l = List.flatten(lst);
eq_str = Tpl.tplString2(SimCodeDump.dumpEqsSys, l, false);
print(eq_str);
then l::{};
case (lst, _)
equation
Expand Down
7 changes: 7 additions & 0 deletions Compiler/FrontEnd/ExpressionDump.mo
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,13 @@ algorithm
s := Tpl.tplString2(ExpressionDumpTpl.dumpExp, e, "\"");
end printExpStr;

public function printCrefsFromExpStr
input DAE.Exp e;
output String s;
algorithm
s := Tpl.tplString2(ExpressionDumpTpl.dumpExpCrefs, e, "");
end printCrefsFromExpStr;

public function printExp2Str
"function: printExp2Str
Helper function to printExpStr."
Expand Down
32 changes: 32 additions & 0 deletions Compiler/Template/CodegenC.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,35 @@ template simulationFile(SimCode simCode, String guid)
#ifdef __cplusplus
}
#endif

/*! Moved from Simulation runtime to support openmp properly.
This way threads can be launched if neccesary
(i.e. if the generated code linked with openmp).
Otherwise normal execution takes place. SimulationruntimeC.lib
doesn't need to be linked with -fopenmp.*/
int performSimulation_optional_thread(DATA* data, SOLVER_INFO* solverInfo)
{
SIMULATION_INFO *simInfo = &(data->simulationInfo);
solverInfo->currentTime = simInfo->startTime;
int retValue = 0;
#ifdef USE_DEBUG_OUTPUT
printAllVarsDebug(data, 0);
#endif
omp_set_num_threads(4);
#pragma omp parallel
{
retValue = main_simulation_loop(data, solverInfo, simInfo);
} /* end #pragma omp parallel*/

return retValue;
}



/* forward the main in the simulation runtime */
extern int _main_SimulationRuntime(int argc, char**argv, DATA *data);
Expand Down Expand Up @@ -245,6 +274,7 @@ template simulationFileHeader(SimCode simCode)
#include "simulation_runtime.h"
#include "omc_error.h"
#include "model_help.h"
#include "solver_main.h"

#include <assert.h>
#include <string.h>
Expand Down Expand Up @@ -3124,6 +3154,8 @@ template commonHeader(String filePrefix)
#include <omp.h>
#else
#define omp_get_max_threads() 1
int omp_get_thread_num() { return 0; }
void omp_set_num_threads() {}
#endif
#include "modelica.h"
#include <stdio.h>
Expand Down
133 changes: 133 additions & 0 deletions Compiler/Template/ExpressionDumpTpl.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ template dumpExpList(list<DAE.Exp> expl, String stringDelimiter, String expDelim
::= (expl |> exp => dumpExp(exp, stringDelimiter) ;separator=expDelimiter)
end dumpExpList;
template dumpExpListCrefs(list<DAE.Exp> expl, String stringDelimiter, String expDelimiter)
::= (expl |> exp => dumpExpCrefs(exp, stringDelimiter) ;separator=expDelimiter)
end dumpExpListCrefs;
template dumpCref(DAE.ComponentRef cref)
::=
match cref
Expand Down Expand Up @@ -448,6 +452,135 @@ template dumpNamedPattern(tuple<Pattern, String, Type> pattern)
::= match pattern case (pat, id, _) then '<%id%> = <%dumpPattern(pat)%>'
end dumpNamedPattern;



template dumpExpCrefs(DAE.Exp exp, String stringDelimiter)
::=
match exp
case ICONST(__) then ''
case RCONST(__) then ''
case SCONST(__) then ''
case BCONST(__) then ''
case ENUM_LITERAL(__) then AbsynDumpTpl.dumpPath(name)
case CREF(__) then dumpCref(componentRef)
case e as BINARY(__) then
let lhs_str = dumpExpCrefs(exp1, stringDelimiter)
let rhs_str = dumpExpCrefs(exp2, stringDelimiter)
'<%lhs_str%> <%rhs_str%>'
case e as UNARY(__) then
let exp_str = dumpOperand(exp, e, false)
let op_str = dumpUnaryOp(operator)
'<%op_str%><%exp_str%>'
case e as LBINARY(__) then
let lhs_str = dumpExpCrefs(exp1, stringDelimiter)
let rhs_str = dumpExpCrefs(exp2, stringDelimiter)
'<%lhs_str%> <%rhs_str%>'
case e as LUNARY(__) then
let lhs_str = dumpExpCrefs(exp, stringDelimiter)
'<%lhs_str%>'
case e as RELATION(__) then
let lhs_str = dumpExpCrefs(exp1, stringDelimiter)
let rhs_str = dumpExpCrefs(exp2, stringDelimiter)
'<%lhs_str%> <%rhs_str%>'
case IFEXP(__) then
let cond_str = dumpExpCrefs(expCond, stringDelimiter)
let then_str = dumpExpCrefs(expThen, stringDelimiter)
let else_str = dumpExpCrefs(expElse, stringDelimiter)
'<%cond_str%> <%then_str%> <%else_str%>'
case CALL(attr=attr as CALL_ATTR(builtin=true)) then
let argl = dumpExpListCrefs(expLst, stringDelimiter, " ")
'<%argl%>'
case CALL(__) then
let argl = dumpExpListCrefs(expLst, stringDelimiter, " ")
'<%argl%>'
case PARTEVALFUNCTION(__) then
let func_str = AbsynDumpTpl.dumpPathNoQual(path)
let argl = dumpExpList(expList, stringDelimiter, ", ")
'function <%func_str%>(<%argl%>)'
case ARRAY(__) then
let expl = dumpExpList(array, stringDelimiter, ", ")
'<%if typeinfo() then (if scalar then "/* scalar */ " else "/* non-scalar */ ")%>{<%expl%>}'
case MATRIX(__) then
let mat_str = (matrix |> row => dumpExpList(row, stringDelimiter, ", ") ;separator="}, {")
'<%if typeinfo() then '/* matrix <%unparseType(ty) %> */ '%>{{<%mat_str%>}}'
case e as RANGE(__) then
let start_str = dumpOperand(start, e, false)
let step_str = match step case SOME(step) then '<%dumpOperand(step, e, false)%>:'
let stop_str = dumpOperand(stop, e, false)
'<%start_str%>:<%step_str%><%stop_str%>'
case TUPLE(__) then
let tuple_str = dumpExpList(PR, stringDelimiter, ", ")
'(<%tuple_str%>)'
case CAST(__) then
let exp_str = dumpExpCrefs(exp, stringDelimiter)
'(<%exp_str%>)'
case ASUB(__) then
let needs_paren = parenthesizeSubExp(exp)
let lparen = if needs_paren then "("
let rparen = if needs_paren then ")"
let exp_str = dumpExp(exp, stringDelimiter)
let sub_str = dumpExpList(sub, stringDelimiter, ", ")
'<%lparen%><%exp_str%><%rparen%>[<%sub_str%>]'
case TSUB(__) then
let needs_paren = parenthesizeSubExp(exp)
let lparen = if needs_paren then "("
let rparen = if needs_paren then ")"
let exp_str = dumpExp(exp, stringDelimiter)
'<%lparen%><%exp_str%><%rparen%>[<%ix%>]'
case SIZE(__) then
let exp_str = dumpExp(exp, stringDelimiter)
let dim_str = match sz case SOME(dim) then ', <%dumpExp(dim, stringDelimiter)%>'
'size(<%exp_str%><%dim_str%>)'
case CODE(__) then
let code_str = Dump.printCodeStr(code)
'$Code(<%code_str%>)'
case EMPTY(__) then
let name_str = dumpCref(name)
'<EMPTY(scope: <%scope%>, name: <%name_str%>, ty: <%tyStr%>)>'
case REDUCTION(reductionInfo = REDUCTIONINFO(path = name)) then
let name_str = AbsynDumpTpl.dumpPathNoQual(name)
let exp_str = dumpExp(expr, stringDelimiter)
let iter_str = (iterators |> it => dumpReductionIterator(it, stringDelimiter) ;separator=", ")
'<%name_str%>(<%exp_str%> for <%iter_str%>)'
case LIST(__) then
let expl_str = dumpExpList(valList, stringDelimiter, ", ")
'List(<%expl_str%>)'
case CONS(__) then
let car_str = dumpExp(car, stringDelimiter)
let cdr_str = dumpExp(cdr, stringDelimiter)
'listCons(<%car_str%>, <%cdr_str%>)'
case META_TUPLE(__) then
let tuple_str = dumpExpList(listExp, stringDelimiter, ", ")
'Tuple(<%tuple_str%>)'
case META_OPTION(exp = SOME(exp)) then 'SOME(<%dumpExp(exp, stringDelimiter)%>)'
case META_OPTION(__) then 'NONE()'
case METARECORDCALL(__) then
let name_str = AbsynDumpTpl.dumpPath(path)
let args_str = dumpExpList(args, stringDelimiter, ", ")
'<%name_str%>(<%args_str%>)'
case MATCHEXPRESSION(__) then
let match_ty = dumpMatchType(matchType)
let inputs_str = dumpExpList(inputs, stringDelimiter, ", ")
let case_str = (cases |> c => dumpMatchCase(c) ;separator="\n")
<<
<%match_ty%> (<%inputs_str%>)
<%case_str%>
end <%match_ty%>
>>
case BOX(__) then
'#(<%dumpExp(exp, stringDelimiter)%>)'
case UNBOX(__) then
'unbox(<%dumpExp(exp, stringDelimiter)%>)'
case SHARED_LITERAL(__) then
let ty_str = dumpType(ty)
'#SHARED_LITERAL_<%index%>(<%ty_str%>)#'
case PATTERN(__) then dumpPattern(pattern)
else errorMsg("ExpressionDumpTpl.dumpExp: Unknown expression.")
end dumpExpCrefs;
template errorMsg(String errMessage)
::=
let() = Tpl.addTemplateError(errMessage)
Expand Down
89 changes: 89 additions & 0 deletions Compiler/Template/SimCodeDump.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,95 @@ template printEquationExpStrEscaped(EquationExp eq)
'<%printExpStrEscaped(lhs)%> = <%printExpStrEscaped(rhs)%>'
end printEquationExpStrEscaped;


template dumpEqsSys(list<SimEqSystem> eqs, Boolean withOperations)
::= eqs |> eq hasindex i0 =>
match eq
case e as SES_RESIDUAL(__) then
<<
<equation index="<%eqIndex(eq)%>">
<residual><%printExpStrEscaped(e.exp)%></residual>
</equation><%\n%>
>>
case e as SES_SIMPLE_ASSIGN(__) then
'<%eqIndex(eq)%> simple_assign <%crefStr(e.cref)%> : <%printCrefsFromExpStr(e.exp)%><%\n%>'
case e as SES_ARRAY_CALL_ASSIGN(__) then
<<
<equation index="<%eqIndex(eq)%>">
<assign type="array">
<lhs><%crefStr(e.componentRef)%></lhs>
<rhs><%printExpStrEscaped(e.exp)%></rhs>
</assign>
</equation><%\n%>
>>
case e as SES_ALGORITHM(statements={}) then 'empty algorithm<%\n%>'
case e as SES_ALGORITHM(statements=first::_)
then
<<
<equation index="<%eqIndex(eq)%>">
<statement>
<%e.statements |> stmt => escapeModelicaStringToXmlString(ppStmtStr(stmt,2)) %>
</statement>
</equation><%\n%>
>>
case e as SES_LINEAR(__) then
'<%eqIndex(eq)%> linear <%e.vars |> SIMVAR(name=cr) => '<%crefStr(cr)%>' ; separator = " " %> : <%beqs |> exp => '<%printExpStrEscaped(exp)%>' ; separator = " " %><%\n%>'
case e as SES_NONLINEAR(__) then
<<
<%dumpEqsSys(SimCodeUtil.sortEqSystems(e.eqs),withOperations)%>
<%eqIndex(eq)%> non_linear <%e.eqs |> eq => '<%eqIndex(eq)%>' ; separator = " " %><%\n%>
>>
/*
<<
<%dumpEqsSys(SimCodeUtil.sortEqSystems(e.eqs),withOperations)%>
<%eqIndex(eq)%>
<%e.crefs |> cr => '<var><%crefStr(cr)%></var>' ; separator = "\n" %>
<%e.eqs |> eq => '<eq index="<%eqIndex(eq)%>"/>' ; separator = "\n" %>
</nonlinear>
</equation><%\n%>
>>
*/
case e as SES_MIXED(__) then
<<
<%dumpEqs(fill(e.cont,1),withOperations)%>
<%dumpEqs(e.discEqs,withOperations)%><%\n%>
<equation index="<%eqIndex(eq)%>">
<mixed>
<continuous index="<%eqIndex(e.cont)%>" />
<%e.discVars |> SIMVAR(name=cr) => '<var><%crefStr(cr)%></var>' ; separator = ","%>
<%e.discEqs |> eq => '<discrete index="<%eqIndex(eq)%>" />'%>
</mixed>
</equation>
>>
case e as SES_WHEN(__) then
<<
<equation index="<%eqIndex(eq)%>">
<when>
<%conditions |> cond => '<cond><%crefStr(cond)%></cond>' ; separator="\n" %>
<lhs><%crefStr(e.left)%></lhs>
<rhs><%printExpStrEscaped(e.right)%></rhs>
</when>
</equation><%\n%>
>>
case e as SES_IFEQUATION(__) then
let branches = ifbranches |> (_,eqs) => dumpEqsSys(eqs,withOperations)
let elsebr = dumpEqsSys(elsebranch,withOperations)
<<
<%branches%>
<%elsebr%>
<equation index="<%eqIndex(eq)%>">
<ifequation /> <!-- TODO: Fix me -->
</equation><%\n%>
>>
else error(sourceInfo(),"dumpEqs: Unknown equation")
end dumpEqsSys;







end SimCodeDump;

// vim: filetype=susan sw=2 sts=2
4 changes: 4 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2447,6 +2447,10 @@ package ExpressionDump
input DAE.Exp e;
output String s;
end printExpStr;
function printCrefsFromExpStr
input DAE.Exp e;
output String s;
end printCrefsFromExpStr;
end ExpressionDump;

package Config
Expand Down
17 changes: 12 additions & 5 deletions SimulationRuntime/c/simulation/solver/model_help.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,18 @@ void updateDiscreteSystem(DATA *data)
*/
void updateContinuousSystem(DATA *data)
{
functionODE(data);
functionAlgebraics(data);
output_function(data);
function_storeDelayed(data);
storePreValues(data);

// printf("continuous %d \n", omp_get_thread_num());
// fflush(stdout);

if(omp_get_thread_num() == 0)
{
functionODE(data);
functionAlgebraics(data);
output_function(data);
function_storeDelayed(data);
storePreValues(data);
}
}

/*! \fn saveZeroCrossings
Expand Down

0 comments on commit 37464d0

Please sign in to comment.