Skip to content

Commit

Permalink
- finishing up the OpenTURNS wrapper.
Browse files Browse the repository at this point in the history
- templates in share/omc/scripts/OpenTurns with all the needed stuff
- added runOpenTURNSPythonScript to run the python file
- everything works fine now on windows, can be easily adapted for Linux!
- see testsuite/uncertainties/CantileverBeam.mos
- fixed warning in solver/solver_main.c

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@12081 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
adrpo committed Jun 18, 2012
1 parent afa4ea5 commit fa0fa4e
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 804 deletions.
153 changes: 140 additions & 13 deletions Compiler/BackEnd/OpenTURNS.mo
Expand Up @@ -49,6 +49,7 @@ import CevalScript;
import SimCode;
import Interactive;
import System;
import Settings;
import BackendDump;
import BackendDAEUtil;
import List;
Expand All @@ -59,6 +60,14 @@ import BackendDAEOptimize;
import Expression;
import Util;

// important constants!
constant String cStrSharePath = "share/omc/scripts/OpenTurns/";
constant String cStrWrapperSuffix = "_wrapper";
constant String cStrCWrapperTemplate = "wrapper_template.c";
constant String cStrMakefileWrapperTemplate = "wrapper_template.makefile";
constant String cStrWrapperCompileCmd = "wrapper_template.compile.cmd";
constant String cStrInvokeOpenTurnsCmd = "invoke.cmd";

public function generateOpenTURNSInterface "generates the dll and the python script for connections with OpenTURNS"
input Env.Cache cache;
input Env.Env env;
Expand All @@ -71,12 +80,13 @@ public function generateOpenTURNSInterface "generates the dll and the python scr
output String scriptFile "the name of the generated file";

protected
String cname_str,fileNamePrefix,fileDir;
String cname_str,fileNamePrefix,fileDir,cname_last_str;
list<String> libs;
BackendDAE.BackendDAE dae,strippedDae;
SimCode.SimulationSettings simSettings;
algorithm
cname_str := Absyn.pathString(inPath);
cname_last_str := Absyn.pathLastIdent(inPath);
fileNamePrefix := cname_str;

simSettings := CevalScript.convertSimulationOptionsToSimCode(
Expand All @@ -89,31 +99,73 @@ algorithm
dae := BackendDAEOptimize.removeParameters(inDaelow);
//print("generating python script\n");

(scriptFile) := generatePythonScript(fileNamePrefix,templateFile,cname_str,dae,inDaelow);
scriptFile := generatePythonScript(inPath,templateFile,dae,inDaelow);

// Strip correlation vector from dae to be able to compile (bug in OpenModelica with vectors of records )
strippedDae := stripCorrelationFromDae(dae);

strippedDae := BackendDAEUtil.getSolvedSystem(cache, env, strippedDae, NONE(), NONE(), NONE(),NONE());

//print("strippedDae :");
//BackendDump.dump(strippedDae);
//BackendDump.dump(strippedDae);
(_,libs,fileDir,_,_,_) := SimCode.generateModelCode(strippedDae,inProgram,inDAElist,inPath,cname_str,SOME(simSettings),Absyn.FUNCTIONARGS({},{}));

//print("..compiling, fileNamePrefix = "+&fileNamePrefix+&"\n");
CevalScript.compileModel(fileNamePrefix , libs, fileDir, "", "");

generateXMLFile(cname_str,strippedDae);
generateXMLFile(cname_last_str,strippedDae);
generateWrapperLibrary(cname_str,cname_last_str);
end generateOpenTURNSInterface;

protected function generateWrapperLibrary
"@author:adrpo
generates the helpers for the OpenTURNS wrapper:
replace #define MODELNAMESTR \"Full.ModelName\" in wrapper_template.c
replace #define WRAPPERNAME ModelName_wrapper in wrapper_template.c
replace WRAPPERNAME = ModelName_wrapper in wrapper_template.makefile
replace ModelName_wrapper in wrapper_template.command
generates files:
ModelName_wrapper.makefile from wrapper_template.makefile
ModelName_wrapper.c from wrapper_template.c
then compiles the wrapper using the specific wrapper_template.command!"
input String fullClassName;
input String lastClassName;
protected
String strCWrapperContents;
String strWrapperNameDefine;
String strMakefileContents;
String compileWrapperCommand;
algorithm
// read the wrapper_template.c template, replace the extension points
strCWrapperContents := System.readFile(getFullShareFileName(cStrCWrapperTemplate));
strCWrapperContents := System.stringReplace(strCWrapperContents,"<%fullModelName%>", fullClassName);
strCWrapperContents := System.stringReplace(strCWrapperContents,"<%wrapperName%>", lastClassName +& cStrWrapperSuffix);
// dump the result into ModelName_wrapper.c
System.writeFile(lastClassName +& cStrWrapperSuffix +& ".c", strCWrapperContents);

// read the wrapper_template.makefile template, replace the extension points
strMakefileContents := System.readFile(getFullShareFileName(cStrMakefileWrapperTemplate));
strMakefileContents := System.stringReplace(strMakefileContents,"<%fullModelName%>", fullClassName);
strMakefileContents := System.stringReplace(strMakefileContents,"<%wrapperName%>", lastClassName +& cStrWrapperSuffix);
// dump the result into ModelName_wrapper.makefile
System.writeFile(lastClassName +& cStrWrapperSuffix +& ".makefile",strMakefileContents);

// we should check if it works fine!
compileWrapperCommand := System.readFile(getFullShareFileName(cStrWrapperCompileCmd));
compileWrapperCommand := System.stringReplace(compileWrapperCommand,"<%wrapperName%>", lastClassName +& cStrWrapperSuffix);
compileWrapperCommand := System.stringReplace(compileWrapperCommand,"<%currentDirectory%>", System.pwd());
compileWrapperCommand := compileWrapperCommand +& " > " +& lastClassName +& cStrWrapperSuffix +& ".log" +& " 2>&1";
runCommand(compileWrapperCommand);
end generateWrapperLibrary;

protected function generateXMLFile "generates the xml file for the OpenTURNS wrapper"
input String className;
input BackendDAE.BackendDAE dae;
protected
String xmlFileContent;
algorithm
xmlFileContent := generateXMLFileContent(className,dae);
System.writeFile(className+&"_wrapper.xml",xmlFileContent);
System.writeFile(className +& cStrWrapperSuffix +& ".xml", xmlFileContent);
end generateXMLFile;

protected function generateXMLFileContent "help function"
Expand Down Expand Up @@ -142,7 +194,7 @@ algorithm
" <!-- Those data are external to the platform (input files, etc.)-->",
" <data></data>",
"",
" <wrap-mode type=\"static-link\" state=\"shared\">",
" <wrap-mode type=\"static-link\" >",
" <in-data-transfer mode=\"arguments\" />",
" <out-data-transfer mode=\"arguments\" />",
" </wrap-mode>",
Expand All @@ -157,19 +209,20 @@ protected function generateXMLLibrary "help function"
output String content;
protected
list<BackendDAE.Var> varLst;
String inputs,outputs,funcStr;
String inputs,outputs,funcStr,dllStr;
algorithm
varLst := BackendDAEUtil.getAllVarLst(dae);
varLst := List.select(varLst,BackendVariable.varHasUncertaintyAttribute);
inputs := stringDelimitList(generateXMLLibraryInputs(varLst),"\n");
outputs := stringDelimitList(generateXMLLibraryOutputs(varLst),"\n");
funcStr := " <function provided=\"yes\">"+&className+&"_wrapper</function>";
dllStr := " <path>" +& className +& cStrWrapperSuffix +& System.getDllExt() +& "</path>";
funcStr := " <function provided=\"yes\">" +& className +& cStrWrapperSuffix +& "</function>";

content :=stringDelimitList({
"<library>",
"",
" <!-- The path of the shared object -->",
" <path>CantileverBeam_wrapper.dll</path>",
dllStr,
"",
" <!-- This section describes all exchanges data between the wrapper and the platform -->",
" <description>",
Expand Down Expand Up @@ -239,19 +292,20 @@ algorithm
end generateXMLLibraryOutputs;

protected function generatePythonScript "generates the python script as input to OpenTURNS, given a template file name"
input String fileNamePrefix;
input Absyn.Path inModelPath;
input String templateFile;
input String modelName;
input BackendDAE.BackendDAE dae;
input BackendDAE.BackendDAE inDaelow;
output String pythonFileName;
protected
String templateFileContent;
String templateFileContent,modelName,modelLastName;
String distributions,correlationMatrix;
String collectionDistributions,inputDescriptions;
String pythonFileContent;
list<tuple<String,String>> distributionVarLst;
algorithm
modelName := Absyn.pathString(inModelPath);
modelLastName := Absyn.pathLastIdent(inModelPath);
templateFileContent := System.readFile(templateFile);
//generate the different parts of the python file
(distributions,distributionVarLst) := generateDistributions(inDaelow);
Expand All @@ -265,6 +319,7 @@ algorithm
pythonFileContent := System.stringReplace(pythonFileContent,"<%correlationMatrix%>",correlationMatrix);
pythonFileContent := System.stringReplace(pythonFileContent,"<%collectionDistributions%>",collectionDistributions);
pythonFileContent := System.stringReplace(pythonFileContent,"<%inputDescriptions%>",inputDescriptions);
pythonFileContent := System.stringReplace(pythonFileContent,"<%wrapperName%>",modelLastName +& cStrWrapperSuffix);

//Write file
//print("writing python script to file "+&pythonFileName+&"\n");
Expand Down Expand Up @@ -329,6 +384,15 @@ algorithm
DAE.ComponentRef cr;
list<DAE.Exp> expl1,expl2;

case((DAE.DISTRIBUTION(DAE.SCONST(name as "LogNormal"),DAE.ARRAY(array=expl1),DAE.ARRAY(array=expl2)),cr),dae) equation
// e.g. distributionL = Beta(0.93, 3.2, 2.8e7, 4.8e7)
// TODO: make sure that the arguments are in correct order by looking at the expl2 list containing strings of argument names
args = stringDelimitList(List.map(expl1,ExpressionDump.printExpStr),",");
varName = ComponentReference.crefModelicaStr(cr);
distVar ="distribution"+&varName;
// add LogNormal.MUSIGMA!
str = distVar+& " = " +& name +& "(" +& args+& ", " +& "LogNormal.MUSIGMA)\n";
then (str,(varName,distVar));

case((DAE.DISTRIBUTION(DAE.SCONST(name),DAE.ARRAY(array=expl1),DAE.ARRAY(array=expl2)),cr),dae) equation
// e.g. distributionL = Beta(0.93, 3.2, 2.8e7, 4.8e7)
Expand Down Expand Up @@ -568,5 +632,68 @@ algorithm
inputDescriptions := "# input descriptions currently not used, set above";

end generateInputDescriptions;


public function getFullSharePath
"@author: adrpo
returns $OPENMODELICAHOME/share/omc/scripts/OpenTurns/"
output String strFullSharePath;
algorithm
strFullSharePath :=
Settings.getInstallationDirectoryPath() +&
System.pathDelimiter() +&
cStrSharePath +&
System.pathDelimiter();
end getFullSharePath;

public function getFullShareFileName
"@author: adrpo
returns $OPENMODELICAHOME/share/omc/scripts/OpenTurns/FILE_NAME
where FILE_NAME is given as input."
input String strFileName;
output String strFullShareFileName;
algorithm
strFullShareFileName := getFullSharePath() +& strFileName;
end getFullShareFileName;

public function runPythonScript
"@author: adrpo
generates inStrPythonScriptFile.bat and calls it
runs the OpenTurns python handler with the given script"
input String inStrPythonScriptFile;
output String outStrLogFile;
algorithm
outStrLogFile := matchcontinue(inStrPythonScriptFile)
local
String cmdContents, logFile, cmdFile;
case (inStrPythonScriptFile)
equation
cmdContents = System.readFile(getFullShareFileName(cStrInvokeOpenTurnsCmd));
cmdContents = System.stringReplace(cmdContents, "<%pythonScriptOpenModelica%>", inStrPythonScriptFile);
cmdFile = inStrPythonScriptFile +& ".bat";
System.writeFile(cmdFile, cmdContents);
logFile = inStrPythonScriptFile +& ".log";
runCommand(cmdFile +& " > " +& logFile +& " 2>&1");
then
logFile;
end matchcontinue;
end runPythonScript;

protected function runCommand
input String cmd;
algorithm
_ := matchcontinue(cmd)
case (cmd)
equation
print("running: " +& cmd +& "\n");
0 = System.systemCall(cmd);
then
();
case (cmd)
equation
print("running: " +& cmd +& "\n\tfailed!\nCheck the log file!\n");
then
();
end matchcontinue;
end runCommand;

end OpenTURNS;
13 changes: 10 additions & 3 deletions Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -1595,10 +1595,17 @@ annotation(preferredView="text");
end instantiateModel;

function buildOpenTURNSInterface "generates wrapper code for OpenTURNS"
input TypeName classNAme;
input String str;
input TypeName className;
input String pythonTemplateFile;
output String outPythonScript;
external "builtin";
end buildOpenTURNSInterface;

function runOpenTURNSPythonScript "runs OpenTURNS with the given python script returning the log file"
input String pythonScriptFile;
output String logOutputFile;
external "builtin";
end buildOpenTURNSInterface;
end runOpenTURNSPythonScript;

function generateCode "The input is a function name for which C-code is generated and compiled into a dll/so"
input TypeName className;
Expand Down
33 changes: 31 additions & 2 deletions Compiler/Script/CevalScript.mo
Expand Up @@ -798,7 +798,7 @@ algorithm
plotCmd,tmpPlotFile,call,str_1,mp,pathstr,name,cname,fileNamePrefix_s,errMsg,errorStr,uniqueStr,interpolation,
title,xLabel,yLabel,filename2,varNameStr,xml_filename,xml_contents,visvar_str,pwd,omhome,omlib,omcpath,os,
platform,usercflags,senddata,res,workdir,gcc,confcmd,touch_file,uname,filenameprefix,compileDir,from,to,
legendStr, gridStr, logXStr, logYStr, x1Str, x2Str, y1Str, y2Str,scriptFile;
legendStr, gridStr, logXStr, logYStr, x1Str, x2Str, y1Str, y2Str,scriptFile,logFile;
list<Values.Value> vals;
Absyn.Path path,p1,classpath,className;
SCode.Program scodeP,sp;
Expand Down Expand Up @@ -1302,6 +1302,12 @@ algorithm
then
(cache,Values.STRING(scriptFile),st);

case(cache,env,"runOpenTURNSPythonScript",vals,st,msg)
equation
(cache,logFile,st) = runOpenTURNSPythonScript(cache,env,vals,st,msg);
then
(cache,Values.STRING(logFile),st);

case (cache,env,"buildModel",_,st,msg) /* failing build_model */
then (cache,ValuesUtil.makeArray({Values.STRING(""),Values.STRING("")}),st);

Expand Down Expand Up @@ -3098,10 +3104,33 @@ algorithm
//print("lowered class\n");
//print("calling generateOpenTurnsInterface\n");
scriptFile = OpenTURNS.generateOpenTURNSInterface(cache,inEnv,dlow,funcs,className,p,dae,templateFile);
then (cache,templateFile,inSt);
then (cache,scriptFile,inSt);
end matchcontinue;
end buildOpenTURNSInterface;

protected function runOpenTURNSPythonScript
"runs OpenTURNS with the given python script returning the log file"
input Env.Cache inCache;
input Env.Env inEnv;
input list<Values.Value> vals;
input Interactive.SymbolTable inSt;
input Ceval.Msg inMsg;
output Env.Cache outCache;
output String outLogFile;
output Interactive.SymbolTable outSt;
algorithm
(outCache,outLogFile,outSt):= matchcontinue(inCache,inEnv,vals,inSt,inMsg)
local
String pythonScriptFile, logFile;
Env.Cache cache;
case(cache,inEnv,{Values.STRING(pythonScriptFile)},inSt,inMsg)
equation
logFile = OpenTURNS.runPythonScript(pythonScriptFile);
then
(cache,logFile,inSt);
end matchcontinue;
end runOpenTURNSPythonScript;

protected function changeToTempDirectory "function changeToTempDirectory
changes to temp directory (set using the functions from Settings.mo)
if the boolean flag given as input is true"
Expand Down
2 changes: 1 addition & 1 deletion Compiler/scripts/replace-startValue.bat
Expand Up @@ -2,5 +2,5 @@
REM usage: .\replace-startValue.bat variableName variableStartValue Model_init.xml

set XSLTPROCEXE="%OPENMODELICAHOME%\lib\omc\libexec\xsltproc\xsltproc.exe"
%XSLTPROCEXE% --stringparam variableName %1 --stringparam variableStart %2 replace-startValue.xsl %3
%XSLTPROCEXE% --stringparam variableName %1 --stringparam variableStart %2 "%OPENMODELICAHOME%\share\omc\scripts\replace-startValue.xsl" %3

2 changes: 1 addition & 1 deletion Compiler/scripts/replace-startValue.sh
Expand Up @@ -7,5 +7,5 @@ if [ ! -f "${XSLTPROCEXE}" ]
then
XSLTPROCEXE=xsltproc
fi
${XSLTPROCEXE} --stringparam variableName $1 --stringparam variableStart $2 replace-startValue.xsl $3
${XSLTPROCEXE} --stringparam variableName $1 --stringparam variableStart $2 "${OPENMODELICAHOME}/share/omc/scripts/replace-startValue.xsl" $3

8 changes: 6 additions & 2 deletions Makefile.common
Expand Up @@ -20,7 +20,7 @@ INSTALL_SHAREDIR = ${DESTDIR}${datadir}/
INSTALL_MANDIR = ${DESTDIR}${datadir}/man/
INSTALL_JAVADIR = ${DESTDIR}${datadir}/omc/java

.PHONY : interactive omc omcd release debug qtclient mosh all mkbuilddirs fmi test install-dirs susan susan_all susgen sustst install-python
.PHONY : interactive omc omcd release debug qtclient mosh all mkbuilddirs fmi test install-dirs susan susan_all susgen sustst install-python install-openturns

mkbuilddirs:
if [ "$(EXE)" = ".app" ]; then mkdir -p $(builddir_app); fi
Expand All @@ -32,6 +32,7 @@ mkbuilddirs:
mkdir -p $(builddir_inc)
mkdir -p $(builddir_java)
mkdir -p $(builddir_share)/omc/scripts/PythonInterface/OMPython/OMParser
mkdir -p $(builddir_share)/omc/scripts/OpenTurns/
mkdir -p $(builddir_share)/omnotebook
mkdir -p $(builddir_doc)/omc/testmodels
mkdir -p $(builddir_man)/man1/
Expand All @@ -43,6 +44,9 @@ release: omc
install-python:
(time $(MAKE) -C PythonInterface -f $(defaultMakefileTarget))

install-openturns:
(time cp SimulationRuntime/OpenTurns/* $(builddir_share)/omc/scripts/OpenTurns/)

interactive: .testvariables mkbuilddirs
$(MAKE) -C SimulationRuntime/interactive -f $(defaultMakefileTarget)
# Depends on libinteractive.a
Expand Down Expand Up @@ -172,7 +176,7 @@ install-dirs:
test ! -d ${builddir_share}/omedit/nls/ || mkdir -p ${INSTALL_SHAREDIR}/omedit/nls/
mkdir -p ${INSTALL_SHAREDIR}/omc/scripts ${INSTALL_JAVADIR}

install: install-dirs install-python
install: install-dirs install-python install-openturns
echo Installing OpenModelica...
# Application directory (OSX)
if [ "$(EXE)" = ".app" ]; then cp -rp ${builddir_app} $(INSTALL_APPDIR); fi
Expand Down

0 comments on commit fa0fa4e

Please sign in to comment.