Skip to content

Commit

Permalink
Merge remote-tracking branch 'fbergero/fmu-experimental' into merge-f…
Browse files Browse the repository at this point in the history
…mu-experimental

Conflicts:
	Compiler/Util/Flags.mo
  • Loading branch information
lochel committed Oct 14, 2015
2 parents 17c6d82 + 9648600 commit 994c933
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 6 deletions.
85 changes: 85 additions & 0 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -11547,5 +11547,90 @@ algorithm
end matchcontinue;
end getHighestDerivation1;

/*****************************************************************************************************
FMU EXPERIMENTAL
author: F. Bergero. 12/10/2015
*****************************************************************************************************/

function getNLSysRHS
input list<SimCode.SimEqSystem> eqs;
input list<DAE.ComponentRef> res ;
output list<DAE.ComponentRef> unknowns;
algorithm
unknowns := matchcontinue (eqs,res)
local list<SimCode.SimEqSystem> tail;
SimCode.SimEqSystem head;
DAE.Exp exp;
case ({},_)
then res;
case (SimCode.SES_RESIDUAL(exp=exp) :: tail,_)
then getNLSysRHS(tail,listAppend(res,Expression.getAllCrefs(exp)));
case (_,)
equation
print("getNLSysRHS failed\n");
then
fail();
end matchcontinue;
end getNLSysRHS;


function computeDependenciesHelper
input list<SimCode.SimEqSystem> eqs;
input list<DAE.ComponentRef> unknowns;
input list<SimCode.SimEqSystem> res;
output list<SimCode.SimEqSystem> deps;
algorithm
deps := matchcontinue (eqs,unknowns,res)
local list<SimCode.SimEqSystem> tail;
SimCode.SimEqSystem head;
list<DAE.ComponentRef> new_unknowns;
list<SimCode.SimEqSystem> r;
DAE.ComponentRef cref;
list<SimCodeVar.SimVar> vars;
list<DAE.ComponentRef> linsys_unk;
list<DAE.ComponentRef> nlsys_unk;
list<SimCode.SimEqSystem> nlsys_eqs;
DAE.Exp exp;
list<DAE.Exp> beqs;
case ({},_,r)
then r;
case ( (head as SimCode.SES_SIMPLE_ASSIGN(cref=cref,exp=exp))::tail,_,r)
equation
true = List.isMemberOnTrue(cref,unknowns,ComponentReference.crefEqual);
// We must include this equation in the ODE
new_unknowns = Expression.getAllCrefs(exp);
// And include all those one defining the RHS
then computeDependenciesHelper(tail,listAppend(unknowns,new_unknowns), listAppend(r,{head}));
case ( (head as SimCode.SES_LINEAR(lSystem = SimCode.LINEARSYSTEM(vars=vars, beqs=beqs)))::tail,_, r)
equation
// This linear system defines the following crefs
linsys_unk = getSimEqSystemCrefsLHS(head);
// If any of those are in our unkowns me must include this equation system
false = listEmpty(List.intersectionOnTrue(linsys_unk,unknowns,ComponentReference.crefEqual));
// And include all the variables of the RHS to the unkowns
new_unknowns = List.flatten(List.map(beqs, Expression.getAllCrefs));
then computeDependenciesHelper(tail,listAppend(unknowns,new_unknowns),listAppend(r,{head}));
case ( (head as SimCode.SES_NONLINEAR(nlSystem=SimCode.NONLINEARSYSTEM(crefs=nlsys_unk, eqs=nlsys_eqs)))::tail,_,r)
equation
// If any of the uknwonw of the NL system are in our unkowns me must include this equation system
false = listEmpty(List.intersectionOnTrue(nlsys_unk,unknowns,ComponentReference.crefEqual));
new_unknowns = getNLSysRHS(nlsys_eqs,{});
then computeDependenciesHelper(tail,listAppend(unknowns,new_unknowns),listAppend(r,{head}));
case (_::tail,_,r)
then computeDependenciesHelper(tail,unknowns,r);
end matchcontinue;
end computeDependenciesHelper;

public function computeDependencies
input list<SimCode.SimEqSystem> eqs;
input DAE.ComponentRef cref;
output list<SimCode.SimEqSystem> deps;
algorithm
deps := match (eqs,cref)
case (_,_)
then listReverse(computeDependenciesHelper(listReverse(eqs),{cref},{}));
end match;
end computeDependencies;

annotation(__OpenModelica_Interface="backend");
end SimCodeUtil;
110 changes: 107 additions & 3 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -875,6 +875,9 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
<%functionODE(odeEquations,(match simulationSettingsOpt case SOME(settings as SIMULATION_SETTINGS(__)) then settings.method else ""), hpcomData.schedules, modelNamePrefixStr)%>
#ifdef FMU_EXPERIMENTAL
<% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then functionODEPartial(odeEquations,(match simulationSettingsOpt case SOME(settings as SIMULATION_SETTINGS(__)) then settings.method else ""), hpcomData.schedules, modelNamePrefixStr, modelInfo)%>
#endif
/* forward the main in the simulation runtime */
extern int _main_SimulationRuntime(int argc, char**argv, DATA *data, threadData_t *threadData);
Expand Down Expand Up @@ -934,6 +937,10 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
<%symbolName(modelNamePrefixStr,"function_initSynchronous")%>,
<%symbolName(modelNamePrefixStr,"function_updateSynchronous")%>,
<%symbolName(modelNamePrefixStr,"function_equationsSynchronous")%>
#ifdef FMU_EXPERIMENTAL
,<%symbolName(modelNamePrefixStr,"functionODE_Partial")%>
#endif
<%\n%>
};

Expand Down Expand Up @@ -5035,8 +5042,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
# /I - Include Directories
# /DNOMINMAX - Define NOMINMAX (does what it says)
# /TP - Use C++ Compiler
CFLAGS=/Od /ZI /EHa /fp:except /I"<%makefileParams.omhome%>/include/omc/c" /I"<%makefileParams.omhome%>/include/omc/msvc/" /I. /DNOMINMAX /TP /DNO_INTERACTIVE_DEPENDENCY /DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME <%if (Flags.isSet(Flags.HPCOM)) then '/openmp'%>

CFLAGS=/Od /ZI /EHa /fp:except /I"<%makefileParams.omhome%>/include/omc/c" /I"<%makefileParams.omhome%>/include/omc/msvc/" /I. /DNOMINMAX /TP /DNO_INTERACTIVE_DEPENDENCY /DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME <%if (Flags.isSet(Flags.HPCOM)) then '/openmp'%> <% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then '/DFMU_EXPERIMENTAL' %>
# /ZI enable Edit and Continue debug info
CDFLAGS = /ZI

Expand Down Expand Up @@ -5094,7 +5100,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
DLLEXT=<%makefileParams.dllext%>
CFLAGS_BASED_ON_INIT_FILE=<%extraCflags%>
DEBUG_FLAGS=<% if boolOr(acceptMetaModelicaGrammar(), Flags.isSet(Flags.GEN_DEBUG_SYMBOLS)) then "-O0 -g"%>
CFLAGS=$(CFLAGS_BASED_ON_INIT_FILE) $(DEBUG_FLAGS) <%makefileParams.cflags%> <%match sopt case SOME(s as SIMULATION_SETTINGS(__)) then '<%s.cflags%> ' /* From the simulate() command */%>
CFLAGS=$(CFLAGS_BASED_ON_INIT_FILE) $(DEBUG_FLAGS) <%makefileParams.cflags%> <%match sopt case SOME(s as SIMULATION_SETTINGS(__)) then '<%s.cflags%> ' /* From the simulate() command */%> <% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then '-DFMU_EXPERIMENTAL' %>
<% if stringEq(Config.simCodeTarget(),"JavaScript") then 'OMC_EMCC_PRE_JS=<%makefileParams.omhome%>/lib/<%getTriple()%>/omc/emcc/pre.js<%\n%>'
%>CPPFLAGS=<%makefileParams.includes ; separator=" "%> -I"<%makefileParams.omhome%>/include/omc/c" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME<% if stringEq(Config.simCodeTarget(),"JavaScript") then " -DOMC_EMCC"%>
LDFLAGS=<%dirExtra%> <%
Expand Down Expand Up @@ -5559,6 +5565,104 @@ template optimizationComponents1(ClassAttributes classAttribute, SimCode simCode
else error(sourceInfo(), 'Unknown Constraint List')
end optimizationComponents1;

template functionXXX_systemPartial(list<SimEqSystem> derivativEquations, String name, Integer n, String modelNamePrefixStr, ModelInfo modelInfo)
::=
let code = match modelInfo
case MODELINFO(vars=SIMVARS(derivativeVars=ders)) then
(ders |> SIMVAR(__) hasindex i0 => equationNames_Partial(SimCodeUtil.computeDependencies(derivativEquations,name),modelNamePrefixStr,i0,crefStr(name)) ; separator="\n")
<<
static void <%modelNamePrefixStr%>_function<%name%><%n%>(DATA *data, threadData_t *threadData, int i)
{
switch (i) {
<%code%>
}
}
>>
end functionXXX_systemPartial;


template functionXXX_systemsPartial(list<list<SimEqSystem>> eqs, String name, Text &loop, Text &varDecls, String modelNamePrefixStr, ModelInfo modelInfo)
::=
let funcs = (eqs |> eq hasindex i0 fromindex 0 => functionXXX_systemPartial(eq,name,i0,modelNamePrefixStr,modelInfo) ; separator="\n")
match listLength(eqs)
case 0 then //empty case
let &loop +=
<<
/* no <%name%> systems */
>>
""
case 1 then //1 function
let &loop +=
<<
<%modelNamePrefixStr%>_function<%name%>0(data, threadData,i);
>>
funcs //just the one function
case nFuncs then //2 and more
let funcNames = eqs |> e hasindex i0 fromindex 0 => 'function<%name%>_system<%i0%>' ; separator=",\n"
let head = if Flags.isSet(Flags.PARMODAUTO) then '#pragma omp parallel for private(id) schedule(<%match noProc() case 0 then "dynamic" else "static"%>)'
let &varDecls += 'int id;<%\n%>'

let &loop +=
/* Text for the loop body that calls the equations */
<<
<%head%>
for(id=0; id<<%nFuncs%>; id++) {
function<%name%>_systems[id](data, threadData);
}
>>
/* Text before the function head */
<<
<%funcs%>
static void (*function<%name%>_systems[<%nFuncs%>])(DATA *, threadData_t *threadData) = {
<%funcNames%>
};
>>
end functionXXX_systemsPartial;

template functionODEPartial(list<list<SimEqSystem>> derivativEquations, Text method, Option<tuple<Schedule,Schedule,Schedule>> hpcOmSchedules, String modelNamePrefix, ModelInfo modelInfo)
"Generates function in simulation file."
::=
let () = System.tmpTickReset(0)
let &nrfuncs = buffer ""
let &varDecls2 = buffer ""
let &varDecls = buffer ""
let &fncalls = buffer ""
let systems = (functionXXX_systemsPartial(derivativEquations, "ODE_Partial", &fncalls, &varDecls, modelNamePrefix, modelInfo))
let &tmp = buffer ""
<<
<%tmp%>
<%systems%>

void <%symbolName(modelNamePrefix,"functionODE_Partial")%>(DATA *data, threadData_t *threadData, int i)
{
TRACE_PUSH
<% if profileFunctions() then "rt_tick(SIM_TIMER_FUNCTION_ODE);" %>
<%varDecls%>
//data->simulationInfo.callStatistics.functionODE++;
<%fncalls%>
TRACE_POP
}
>>
end functionODEPartial;

template equationNames_Partial(list<SimEqSystem> eqs, String modelNamePrefixStr, Integer i0, String cref_der)
"Generates an equation.
This template should not be used for a SES_RESIDUAL.
Residual equations are handled differently."
::=
let odeEqs = eqs |> eq => equationNames_(eq,contextSimulationNonDiscrete,modelNamePrefixStr); separator="\n"
<<
case <%i0%>:
// Assigning <%cref_der%>
<%odeEqs%>
break;
>>
end equationNames_Partial;

annotation(__OpenModelica_Interface="backend");
end CodegenC;

Expand Down
11 changes: 9 additions & 2 deletions Compiler/Template/CodegenFMU.tpl
Expand Up @@ -1070,7 +1070,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
# /I - Include Directories
# /DNOMINMAX - Define NOMINMAX (does what it says)
# /TP - Use C++ Compiler
CFLAGS=/Od /ZI /EHa /fp:except /I"<%makefileParams.omhome%>/include/omc/c" /I"<%makefileParams.omhome%>/include/omc/msvc/" <%if isFMIVersion20(FMUVersion) then '/I"<%makefileParams.omhome%>/include/omc/c/fmi2"' else '/I"<%makefileParams.omhome%>/include/omc/c/fmi1"'%> /I. /DNOMINMAX /TP /DNO_INTERACTIVE_DEPENDENCY
CFLAGS=/Od /ZI /EHa /fp:except /I"<%makefileParams.omhome%>/include/omc/c" /I"<%makefileParams.omhome%>/include/omc/msvc/" <%if isFMIVersion20(FMUVersion) then '/I"<%makefileParams.omhome%>/include/omc/c/fmi2"' else '/I"<%makefileParams.omhome%>/include/omc/c/fmi1"'%> /I. /DNOMINMAX /TP /DNO_INTERACTIVE_DEPENDENCY <% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then '/DFMU_EXPERIMENTAL'%>

# /ZI enable Edit and Continue debug info
CDFLAGS = /ZI
Expand Down Expand Up @@ -1132,7 +1132,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
# Makefile generated by OpenModelica

# Note: Simulation of the fmu with dymola does not work with -finline-small-functions (enabled by most optimization levels)
override CPPFLAGS += -Iinclude/ -Iinclude/fmi<%if isFMIVersion20(FMUVersion) then "2" else "1"%> -I. <%makefileParams.includes ; separator=" "%>
override CPPFLAGS += -Iinclude/ -Iinclude/fmi<%if isFMIVersion20(FMUVersion) then "2" else "1"%> -I. <%makefileParams.includes ; separator=" "%> <% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then '-DFMU_EXPERIMENTAL'%>
ifeq ($(OPENMODELICA_DYNAMIC),)
override CPPFLAGS += -DOMC_MINIMAL_RUNTIME=1 -DCMINPACK_NO_DLL=1
override LDFLAGS += -L"<%makefileParams.omhome%>/lib/<%getTriple()%>/omc"
Expand Down Expand Up @@ -1247,6 +1247,13 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
<%fileNamePrefix%>_fmiGetIntegerStatus @42
<%fileNamePrefix%>_fmiGetBooleanStatus @43
<%fileNamePrefix%>_fmiGetStringStatus @44
<% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then
<<
;***************************************************
; Experimetnal function for FMI for ModelExchange
;****************************************************
<%fileNamePrefix%>_fmiGetSpecificDerivatives @45
>> %>
>>
else
<<
Expand Down
18 changes: 18 additions & 0 deletions Compiler/Template/CodegenFMU2.tpl
Expand Up @@ -64,6 +64,23 @@ case SIMCODE(__) then
<%fmiModelDescriptionAttributes(simCode,guid)%>>
<%ModelExchange(simCode)%>
<%fmiTypeDefinitions(modelInfo, "2.0")%>
<% if Flags.isSet(Flags.FMU_EXPERIMENTAL) then
<<
<LogCategories>
<Category name="logEvents" description="logEvents" />
<Category name="logSingularLinearSystems" description="logSingularLinearSystems" />
<Category name="logNonlinearSystems" description="logNonlinearSystems" />
<Category name="logDynamicStateSelection" description="logDynamicStateSelection" />
<Category name="logStatusWarning" description="logStatusWarning" />
<Category name="logStatusDiscard" description="logStatusDiscard" />
<Category name="logStatusError" description="logStatusError" />
<Category name="logStatusFatal" description="logStatusFatal" />
<Category name="logStatusPending" description="logStatusPending" />
<Category name="logAll" description="logAll" />
<Category name="logFmi2Call" description="logFmi2Call" />
</LogCategories>
>> else
<<
<LogCategories>
<Category name="logEvents" />
<Category name="logSingularLinearSystems" />
Expand All @@ -77,6 +94,7 @@ case SIMCODE(__) then
<Category name="logAll" />
<Category name="logFmi2Call" />
</LogCategories>
>> %>
<%DefaultExperiment(simulationSettingsOpt)%>
<%fmiModelVariables(simCode, "2.0")%>
<%ModelStructureHelper(modelStructure)%>
Expand Down
7 changes: 7 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -838,6 +838,12 @@ package SimCodeUtil
input list<SimCode.ClockedPartition> inPartitions;
output list<SimCode.SubPartition> outSubPartitions;
end getSubPartitions;

function computeDependencies
input list<SimCode.SimEqSystem> eqs;
input DAE.ComponentRef cref;
output list<SimCode.SimEqSystem> deps;
end computeDependencies;
end SimCodeUtil;

package SimCodeFunctionUtil
Expand Down Expand Up @@ -3202,6 +3208,7 @@ package Flags
constant ConfigFlag PROFILING_LEVEL;
constant ConfigFlag CPP_FLAGS;
constant ConfigFlag MATRIX_FORMAT;
constant DebugFlag FMU_EXPERIMENTAL;

function isSet
input DebugFlag inFlag;
Expand Down
6 changes: 5 additions & 1 deletion Compiler/Util/Flags.mo
Expand Up @@ -466,6 +466,9 @@ constant DebugFlag DEBUG_DIFFERENTIATION = DEBUG_FLAG(149, "debugDifferentiation
Util.gettext("Dumps debug output for the differentiation process."));
constant DebugFlag DEBUG_DIFFERENTIATION_VERBOSE = DEBUG_FLAG(150, "debugDifferentiationVerbose", false,
Util.gettext("Dumps verbose debug output for the differentiation process."));
constant DebugFlag FMU_EXPERIMENTAL = DEBUG_FLAG(151, "fmuExperimental", false,
Util.gettext("Include an extra function in the FMU fmi2GetSpecificDerivatives."));


// This is a list of all debug flags, to keep track of which flags are used. A
// flag can not be used unless it's in this list, and the list is checked at
Expand Down Expand Up @@ -622,7 +625,8 @@ constant list<DebugFlag> allDebugFlags = {
DUMP_FUNCTIONS,
BUILD_STATIC_SOURCE_FMU,
DEBUG_DIFFERENTIATION,
DEBUG_DIFFERENTIATION_VERBOSE
DEBUG_DIFFERENTIATION_VERBOSE,
FMU_EXPERIMENTAL
};

public
Expand Down
5 changes: 5 additions & 0 deletions SimulationRuntime/c/openmodelica_func.h
Expand Up @@ -305,6 +305,11 @@ void (*function_updateSynchronous)(DATA *data, threadData_t *threadData, long i)
* Sub-partition's equations
*/
int (*function_equationsSynchronous)(DATA *data, threadData_t *threadData, long i);
#ifdef FMU_EXPERIMENTAL
/* functionODEPartial contains those equations that are needed
* to calculate the state derivative i-th */
void (*functionODEPartial)(DATA *data, threadData_t*, int i);
#endif
};

#ifdef __cplusplus
Expand Down
4 changes: 4 additions & 0 deletions SimulationRuntime/fmi/export/fmi2/fmi2FunctionTypes.h
Expand Up @@ -212,6 +212,10 @@ Types for Functions for FMI2 for Model Exchange

/* Evaluation of the model equations */
typedef fmi2Status fmi2GetDerivativesTYPE (fmi2Component, fmi2Real[], size_t);
#ifdef FMU_EXPERIMENTAL
typedef fmi2Status fmi2GetSpecificDerivativesTYPE (fmi2Component, fmi2Real[], const fmi2ValueReference [], size_t);
#endif

typedef fmi2Status fmi2GetEventIndicatorsTYPE (fmi2Component, fmi2Real[], size_t);
typedef fmi2Status fmi2GetContinuousStatesTYPE (fmi2Component, fmi2Real[], size_t);
typedef fmi2Status fmi2GetNominalsOfContinuousStatesTYPE(fmi2Component, fmi2Real[], size_t);
Expand Down
6 changes: 6 additions & 0 deletions SimulationRuntime/fmi/export/fmi2/fmi2Functions.h
Expand Up @@ -222,6 +222,9 @@ Functions for FMI2 for Model Exchange
#define fmi2SetTime fmi2FullName(fmi2SetTime)
#define fmi2SetContinuousStates fmi2FullName(fmi2SetContinuousStates)
#define fmi2GetDerivatives fmi2FullName(fmi2GetDerivatives)
#ifdef FMU_EXPERIMENTAL
#define fmi2GetSpecificDerivatives fmi2FullName(fmi2GetSpecificDerivatives)
#endif
#define fmi2GetEventIndicators fmi2FullName(fmi2GetEventIndicators)
#define fmi2GetContinuousStates fmi2FullName(fmi2GetContinuousStates)
#define fmi2GetNominalsOfContinuousStates fmi2FullName(fmi2GetNominalsOfContinuousStates)
Expand Down Expand Up @@ -303,6 +306,9 @@ Functions for FMI2 for Model Exchange

/* Evaluation of the model equations */
FMI2_Export fmi2GetDerivativesTYPE fmi2GetDerivatives;
#ifdef FMU_EXPERIMENTAL
FMI2_Export fmi2GetSpecificDerivativesTYPE fmi2GetSpecificDerivatives;
#endif
FMI2_Export fmi2GetEventIndicatorsTYPE fmi2GetEventIndicators;
FMI2_Export fmi2GetContinuousStatesTYPE fmi2GetContinuousStates;
FMI2_Export fmi2GetNominalsOfContinuousStatesTYPE fmi2GetNominalsOfContinuousStates;
Expand Down

0 comments on commit 994c933

Please sign in to comment.