Skip to content

Commit

Permalink
[OMSI] Added buildModelFMU for simCodeTarget=omsic
Browse files Browse the repository at this point in the history
It's now possible to build first FMUs with --simCodeTarget=omsic
  - Added new simCodeTarget flag "omsic"
  - buildModelFMU can now return resultValues and saves time needed to build model
  - Added OMSIC template functions to callTargetTemplatesFMU in SimCodeMain.mo
  - Added template compilation for OMSI templates in Compiler/Template/Makefile.common

Belonging to [master]:
  - #154
  - #3067

Co-authored-by: niklwors <niiklas.worschech@boschrexroth.de>
Co-authored-by: wibraun <wbraun@fh-bielefeld.de>

Belonging to [master]:
  - #154
  - OpenModelica/OMCompiler#3067
  • Loading branch information
AnHeuermann authored and OpenModelica-Hudson committed Apr 29, 2019
1 parent 10a0a9d commit 67b8802
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 101 deletions.
2 changes: 1 addition & 1 deletion Compiler/Script/CevalScript.mo
Expand Up @@ -231,7 +231,7 @@ protected
Boolean isWindows = Autoconf.os == "Windows_NT";
list<String> makeVarsNoBinding;
algorithm
libsfilename := fileprefix + ".libs";
libsfilename := workDir + fileprefix + ".libs";
libs_str := stringDelimitList(libs, " ");
makeVarsNoBinding := makeVars; // OMC is stupid and wants to constant evaluate inputs with bindings for iterator variables...

Expand Down
67 changes: 56 additions & 11 deletions Compiler/Script/CevalScriptBackend.mo
Expand Up @@ -1422,12 +1422,28 @@ algorithm
then
(cache,Values.BOOL(b));

case (cache,env,"buildModel",vals,_)
equation
case (cache,env,"buildModel", vals as Values.CODE(Absyn.C_TYPENAME(className))::_,_)
algorithm
List.map_0(ClockIndexes.buildModelClocks,System.realtimeClear);
System.realtimeTick(ClockIndexes.RT_CLOCK_SIMULATE_TOTAL);
(b,cache,compileDir,executable,_,_,initfilename,_,_,vals) = buildModel(cache,env, vals, msg);
executable = if not Config.getRunningTestsuite() then compileDir + executable else executable;
if not Config.simCodeTarget() == "omsic" then
(b,cache,compileDir,executable,_,_,initfilename,_,_,vals) := buildModel(cache,env, vals, msg);
else
filenameprefix := Absyn.pathString(className);
try
(cache, Values.STRING(str)) := buildModelFMU(cache, env, className, "2.0", "me", "<default>", true, {"static"});
if stringEmpty(str) then
fail();
end if;
b := true;
else
b := false;
end try;
compileDir := System.pwd() + Autoconf.pathDelimiter;
executable := filenameprefix + "_me_FMU";
initfilename := filenameprefix + "_init_xml";
end if;
executable := if not Config.getRunningTestsuite() then compileDir + executable else executable;
then
(cache,ValuesUtil.makeArray(if b then {Values.STRING(executable),Values.STRING(initfilename)} else {Values.STRING(""),Values.STRING("")}));

Expand Down Expand Up @@ -1498,7 +1514,12 @@ algorithm
case (cache,env,"simulate",vals as Values.CODE(Absyn.C_TYPENAME(className))::_,_)
algorithm
System.realtimeTick(ClockIndexes.RT_CLOCK_SIMULATE_TOTAL);
(b,cache,compileDir,executable,_,outputFormat_str,_,simflags,resultValues,vals) := buildModel(cache,env,vals,msg);
if not Config.simCodeTarget() == "omsic" then
(b,cache,compileDir,executable,_,outputFormat_str,_,simflags,resultValues,vals) := buildModel(cache,env,vals,msg);
else
Error.addMessage(Error.SIMULATOR_BUILD_ERROR, {"Can't simulate for SimCodeTarget=omsic!\n"});
fail();
end if;

if b then
exeDir := compileDir;
Expand Down Expand Up @@ -3544,6 +3565,7 @@ protected
list<String> libs;
Boolean isWindows;
String FMUType = inFMUType;
Real timeCompile;
algorithm
cache := inCache;
if not FMI.checkFMIVersion(FMUVersion) then
Expand All @@ -3564,6 +3586,7 @@ algorithm
Error.addMessage(Error.FMU_EXPORT_NOT_SUPPORTED_CPP, {FMUType});
FMUType := "me";
end if;

// NOTE: The FMUs use fileNamePrefix for the internal name when it would be expected to be fileNamePrefix that decides the .fmu filename
// The scripting environment from a user's perspective is like that. fmuTargetName is the name of the .fmu in the templates, etc.
filenameprefix := Util.stringReplaceChar(if inFileNamePrefix == "<default>" then Absyn.pathString(className) else inFileNamePrefix, ".", "_");
Expand All @@ -3572,7 +3595,7 @@ algorithm
simSettings := convertSimulationOptionsToSimCode(defaulSimOpt);
Flags.setConfigBool(Flags.BUILDING_FMU, true);
try
(success, cache, libs,_, _) := SimCodeMain.translateModel(SimCodeMain.TranslateModelKind.FMU(FMUVersion, FMUType, fmuTargetName), cache, inEnv, className, filenameprefix, addDummy, SOME(simSettings));
(success, cache, libs, _, _) := SimCodeMain.translateModel(SimCodeMain.TranslateModelKind.FMU(FMUVersion, FMUType, fmuTargetName), cache, inEnv, className, filenameprefix, addDummy, SOME(simSettings));
true := success;
outValue := Values.STRING((if not Config.getRunningTestsuite() then System.pwd() + Autoconf.pathDelimiter else "") + fmuTargetName + ".fmu");
else
Expand Down Expand Up @@ -3606,19 +3629,41 @@ algorithm
return;
end if;

CevalScript.compileModel(filenameprefix+"_FMU" , libs);
System.realtimeTick(ClockIndexes.RT_CLOCK_BUILD_MODEL);
if not Config.simCodeTarget() == "omsic" then
CevalScript.compileModel(filenameprefix+"_FMU" , libs);

ExecStat.execStat("buildModelFMU: Generate the FMI files");
ExecStat.execStat("buildModelFMU: Generate the FMI files");

fmutmp := filenameprefix + ".fmutmp";
logfile := filenameprefix + ".log";
dir := fmutmp+"/sources/";
else
fmutmp := filenameprefix+".fmutmp" + Autoconf.pathDelimiter;
try
CevalScript.compileModel(filenameprefix+"_FMU" , libs, fmutmp);
timeCompile := System.realtimeTock(ClockIndexes.RT_CLOCK_BUILD_MODEL);
else
Error.addMessage(Error.SIMULATOR_BUILD_ERROR, {System.readFile(fmutmp + filenameprefix+"_FMU.log")});
end try;
return;
end if;

for platform in platforms loop
configureFMU(platform, fmutmp, System.realpath(fmutmp)+"/resources/"+System.stringReplace(listGet(Util.stringSplitAtChar(platform," "),1),"/","-")+".log", isWindows);
ExecStat.execStat("buildModelFMU: Generate platform " + platform);
try
configureFMU(platform, fmutmp, System.realpath(fmutmp)+"/resources/"+System.stringReplace(listGet(Util.stringSplitAtChar(platform," "),1),"/","-")+".log", isWindows);
ExecStat.execStat("buildModelFMU: Generate platform " + platform);
else
Error.addMessage(Error.SIMULATOR_BUILD_ERROR, {"Configure for platform:\"" + platform + "\" does not exist"});
end try;
end for;

cmd := "rm -f \"" + fmuTargetName + ".fmu\" && cd \"" + fmutmp + "\" && zip -r \"../" + fmuTargetName + ".fmu\" *";
if 0 <> System.systemCall(cmd, outFile=logfile) then
Error.addMessage(Error.SIMULATOR_BUILD_ERROR, {cmd + "\n\n" + System.readFile(logfile)});
ExecStat.execStat("buildModelFMU failed");
else
timeCompile := System.realtimeTock(ClockIndexes.RT_CLOCK_BUILD_MODEL);
end if;

if not System.regularFileExists(fmuTargetName + ".fmu") then
Expand Down Expand Up @@ -5123,10 +5168,10 @@ algorithm
if success then
try
CevalScript.compileModel(filenameprefix, libs);
timeCompile := System.realtimeTock(ClockIndexes.RT_CLOCK_BUILD_MODEL);
else
success := false;
end try;
timeCompile := System.realtimeTock(ClockIndexes.RT_CLOCK_BUILD_MODEL);
else
timeCompile := 0.0;
end if;
Expand Down
33 changes: 33 additions & 0 deletions Compiler/SimCode/SimCodeMain.mo
Expand Up @@ -75,6 +75,9 @@ import CodegenSparseFMI;
import CodegenCSharp;
import CodegenCpp;
import CodegenCppHpcom;
import CodegenOMSIC;
import CodegenOMSI_common;
import CodegenOMSIC_Equations;
import CodegenXML;
import CodegenJava;
import CodegenJS;
Expand Down Expand Up @@ -679,7 +682,9 @@ algorithm
local
String str, newdir, newpath, resourcesDir, dirname;
String fmutmp;
String guid;
Boolean b;
String fileprefix;
list<String> allFiles, sourceFiles, defaultFiles, extraFiles, runtimeFiles, dgesvFiles;
SimCode.VarInfo varInfo;
case (SimCode.SIMCODE(),"C")
Expand Down Expand Up @@ -754,6 +759,34 @@ algorithm
Tpl.closeFile(Tpl.tplCallWithFailError(CodegenFMU.settingsfile, simCode,
txt=Tpl.redirectToFile(Tpl.emptyTxt, simCode.fileNamePrefix+".fmutmp/sources/omc_simulation_settings.h")));
then ();
case (_,"omsic")
algorithm
guid := System.getUUIDStr();
fileprefix := simCode.fileNamePrefix;

// create tmp directory for generated files, but first remove the old one!
if System.directoryExists(simCode.fullPathPrefix) then
if not System.removeDirectory(simCode.fullPathPrefix) then
Error.addInternalError("Failed to remove directory: " + simCode.fullPathPrefix, sourceInfo());
fail();
end if;
end if;
if not System.createDirectory(simCode.fullPathPrefix) then
Error.addInternalError("Failed to create tmp folder", sourceInfo());
fail();
end if;

SerializeInitXML.simulationInitFileReturnBool(simCode=simCode, guid=guid);
SerializeModelInfo.serialize(simCode, Flags.isSet(Flags.INFO_XML_OPERATIONS));

//runTplWriteFile(func = function CodegenFMU.fmuModelDescriptionFile(in_a_simCode=simCode, in_a_guid=guid, in_a_FMUVersion=FMUVersion, in_a_FMUType=FMUType, in_a_sourceFiles={}), file=simCode.fullPathPrefix+"/"+"modelDescription.xml");
runTpl(func = function CodegenOMSI_common.generateFMUModelDescriptionFile(a_simCode=simCode, a_guid=guid, a_FMUVersion=FMUVersion, a_FMUType=FMUType, a_sourceFiles={}, a_fileName=simCode.fullPathPrefix+"/"+"modelDescription.xml"));
runTplWriteFile(func = function CodegenOMSIC.createMakefile(a_simCode=simCode, a_target=Config.simulationCodeTarget(), a_makeflieName=fileprefix+"_FMU.makefile"), file=simCode.fullPathPrefix+"/"+fileprefix+"_FMU.makefile");

runTplWriteFile(func = function CodegenOMSIC.generateOMSIC(a_simCode=simCode), file=simCode.fullPathPrefix+"/"+fileprefix+"_omsic.c");

runTpl(func = function CodegenOMSI_common.generateEquationsCode(a_simCode=simCode, a_FileNamePrefix=fileprefix));
then ();
case (_,"Cpp")
equation
if(Flags.isSet(Flags.HPCOM)) then
Expand Down
48 changes: 5 additions & 43 deletions Compiler/Template/CodegenOMSIC.tpl
Expand Up @@ -147,14 +147,15 @@ template createMakefile(SimCode simCode, String target, String makeflieName)
let libEnding = match makefileParams.platform case "win32" case "win64" then 'dll' else 'so'
let rpath = match makefileParams.platform case "win32" case "win64" then '' else "-rpath '$$ORIGIN/.'"
let star = match makefileParams.platform case "win32" case "win64" then '' else '*'
let fPIC = match makefileParams.platform case "win32" case "win64" then '' else '-fPIC '

<<
# Makefile generated by OpenModelica
OMHOME=<%makefileParams.omhome%>
OMLIB=<%makefileParams.omhome%>/<%OMLibs%>

CC=<%makefileParams.ccompiler%>
CFLAGS= -fPIC -Wall -Wextra -ansi -pedantic -g
CFLAGS= <%fPIC%>-Wall -Wextra -ansi -pedantic -g
CXX=<%makefileParams.cxxcompiler%>
LD=$(CC) -shared

Expand Down Expand Up @@ -197,7 +198,7 @@ template createMakefile(SimCode simCode, String target, String makeflieName)
KINSOL_LIB=sundials_kinsol
SUNDIALS_NVECSERIAL=sundials_nvecserial

OMSU_STATIC_LIB=-Wl,--whole-archive -lOMSISolver_static -lOMSIBase_static -lOMSU_static -Wl,--no-whole-archive
OMSU_STATIC_LIB=-Wl,--whole-archive -lOMSISolver_static -lOMSIBase_static -lOMSIC_static -Wl,--no-whole-archive
OMSU_STATIC_LIBDIR=-L$(OMLIB)/omc/omsi
LIBS = $(OMSU_STATIC_LIB) -Wl,-Bdynamic -l$(EXPAT_LIB) -l$(LAPACK_LIB) <%match makefileParams.platform case "win32" case "win64" then '' else '-l$(BLAS_LIB)'%> $(KINSOL_LIBDIR)/lib$(KINSOL_LIB).<%libEnding%> $(KINSOL_LIBDIR)/lib$(SUNDIALS_NVECSERIAL).<%libEnding%>
LIBSDIR= $(OMSU_STATIC_LIBDIR) -L$(EXPAT_LIBDIR) -L$(LAPACK_LIBDIR) -L$(KINSOL_LIBDIR)
Expand All @@ -221,7 +222,7 @@ template createMakefile(SimCode simCode, String target, String makeflieName)
<%\t%>cp -a $(OMHOME)/include/omc/omsi/* <%includedir%>
<%\t%>cp -a $(OMHOME)/include/omc/omsic/* <%includedir%>
<%\t%>cp -a $(OMLIB)/omc/omsi/libOMSIBase_static.* <%fileNamePrefix%>.fmutmp/sources/libs
<%\t%>cp -a $(OMLIB)/omc/omsi/libOMSU_static.* <%fileNamePrefix%>.fmutmp/sources/libs
<%\t%>cp -a $(OMLIB)/omc/omsi/libOMSIC_static.* <%fileNamePrefix%>.fmutmp/sources/libs
<%\t%>cp -a $(OMLIB)/omc/omsi/libOMSISolver_static.* <%fileNamePrefix%>.fmutmp/sources/libs
<%\t%># Third party libraries
<%\t%>cp -f $(EXPAT_LIBDIR)/lib$(EXPAT_LIB).a <%fileNamePrefix%>.fmutmp/sources/libs
Expand Down Expand Up @@ -373,7 +374,7 @@ template createMakefileIn(SimCode simCode, String target, String FileNamePrefix,
# /MD - link with MSVCRT.LIB
# /link - [linker options and libraries]
# /LIBPATH: - Directories where libs can be found
LDFLAGS=/MD /link /dll /debug /pdb:"<%fileNamePrefix%>.pdb" /LIBPATH:"<%makefileParams.omhome%>/lib/<%getTriple()%>/omc/msvc/" /LIBPATH:"<%makefileParams.omhome%>/lib/<%getTriple()%>/omc/msvc/release/" <%dirExtra%> <%libsPos1%> <%libsPos2%> f2c.lib initialization.lib libexpat.lib math-support.lib meta.lib results.lib simulation.lib solver.lib sundials_kinsol.lib sundials_nvecserial.lib util.lib lapack_win32_MT.lib lis.lib gc-lib.lib user32.lib pthreadVC2.lib wsock32.lib cminpack.lib umfpack.lib amd.lib
LDFLAGS=/MD /link /dll /debug /pdb:"<%fileNamePrefix%>.pdb" /LIBPATH:"<%makefileParams.omhome%>/lib/omc/msvc/" /LIBPATH:"<%makefileParams.omhome%>/lib/omc/msvc/release/" <%dirExtra%> <%libsPos1%> <%libsPos2%> f2c.lib initialization.lib libexpat.lib math-support.lib meta.lib results.lib simulation.lib solver.lib sundials_kinsol.lib sundials_nvecserial.lib util.lib lapack_win32_MT.lib lis.lib gc-lib.lib user32.lib pthreadVC2.lib wsock32.lib cminpack.lib umfpack.lib amd.lib

# /MDd link with MSVCRTD.LIB debug lib
# lib names should not be appended with a d just switch to lib/omc/msvc/debug
Expand Down Expand Up @@ -458,44 +459,5 @@ template createMakefileIn(SimCode simCode, String target, String FileNamePrefix,
end createMakefileIn;


template createFMIImportScript(String fileNamePrefix, String fmuTargetName)
"Generated script for building executable from OMSU using OM FMI-Import."
::=
<<
importFMU("<%fmuTargetName%>.fmu");
getErrorString();
setCommandLineOptions("--simCodeTarget=C");

loadFile("<%fileNamePrefix%>_me_FMU.mo");
getErrorString();
buildModel(<%fileNamePrefix%>_me_FMU);
getErrorString();
>>
end createFMIImportScript;


template createOMSimulationScript(String fileNamePrefix, String fmuTargetName)
"Generate script for simulating OMSU with OMSimulator."
::=
<<
oms_setCommandLineOption("--suppressPath=true")
oms_setTempDirectory("./temp-<%fileNamePrefix%>/")

oms_newModel("<%fileNamePrefix%>")
oms_addSystem("<%fileNamePrefix%>.root", oms_system_sc)
oms_addSubModel("<%fileNamePrefix%>.root.A", "<%fmuTargetName%>.fmu")
oms_setResultFile("<%fileNamePrefix%>", "<%fmuTargetName%>_res.mat")

oms_instantiate("<%fileNamePrefix%>")

oms_initialize("<%fileNamePrefix%>")

oms_simulate("<%fileNamePrefix%>")

oms_terminate("<%fileNamePrefix%>")
oms_delete("<%fileNamePrefix%>")
>>
end createOMSimulationScript;

annotation(__OpenModelica_Interface="backend");
end CodegenOMSIC;
65 changes: 38 additions & 27 deletions Compiler/Template/CodegenOMSI_common.tpl
Expand Up @@ -43,9 +43,20 @@ import CodegenOMSIC_Equations;
import CodegenUtil;
import CodegenUtilSimulation;
import CodegenCFunctions;
import CodegenFMU;


/* public */
template generateFMUModelDescriptionFile(SimCode simCode, String guid, String FMUVersion, String FMUType, list<String> sourceFiles, String fileName)
"Generate modelDescription.xml.
ToDo: Workaround since runTplWriteFile from .mo file loses some spaces."
::=
let content = CodegenFMU.fmuModelDescriptionFile(simCode, guid, FMUVersion, FMUType, sourceFiles)
let () = textFile(content, fileName)
<<>>
end generateFMUModelDescriptionFile;


template generateEquationsCode (SimCode simCode, String FileNamePrefix)
"Entrypoint to generate all Code for linear systems.
Code is generated directly into files"
Expand Down Expand Up @@ -148,44 +159,44 @@ template generateOmsiFunctionCode(OMSIFunction omsiFunction, String FileNamePref
#include <Core/System/IOMSI.h>

>>
end match%>
end match%>


#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/* Instantiation of omsi_function_t */
<%initializationCode%>
/* Instantiation of omsi_function_t */
<%initializationCode%>
/* Evaluation functions for each equation */
<%evaluationCode%>
/* Evaluation functions for each equation */
<%evaluationCode%>
/* Equations evaluation */
<%match Config.simCodeTarget()
case "omsic" then
'omsi_status <%FileNamePrefix%>_<%omsiName%>_allEqns(omsi_function_t* <%omsiName%>, omsi_values* model_vars_and_params, void* data){'
case "omsicpp" then
'omsi_status <%FileNamePrefix%>::omsi_<%modelFunctionnamePrefixStr%>All(omsi_function_t* <%omsiName%>, const omsi_values* model_vars_and_params, void* data){'
end match%>
/* Equations evaluation */
<%match Config.simCodeTarget()
case "omsic" then
'omsi_status <%FileNamePrefix%>_<%omsiName%>_allEqns(omsi_function_t* <%omsiName%>, omsi_values* model_vars_and_params, void* data){'
case "omsicpp" then
'omsi_status <%FileNamePrefix%>::omsi_<%modelFunctionnamePrefixStr%>All(omsi_function_t* <%omsiName%>, const omsi_values* model_vars_and_params, void* data){'
end match%>
/* Variables */
omsi_status status, new_status;
/* Variables */
omsi_status status, new_status;
status = omsi_ok;
<%if not nAlgebraicSystems then "new_status = omsi_ok;"%>
status = omsi_ok;
<%if not nAlgebraicSystems then "new_status = omsi_ok;"%>
<%functionCall%>
<%functionCall%>
return status;
}
return status;
}

#if defined(__cplusplus)
}
#endif
<%\n%>
>>
#if defined(__cplusplus)
}
#endif
<%\n%>
>>
/* leave a newline at the end of file to get rid of the warning */
end generateOmsiFunctionCode;

Expand Down

0 comments on commit 67b8802

Please sign in to comment.