From 2980576bf1fdb9328ad9087741907d23dd060d23 Mon Sep 17 00:00:00 2001 From: Marcus Walther Date: Mon, 6 Jul 2015 16:51:24 +0200 Subject: [PATCH] - HPCOM-FMU-Support added - the HPCOM-ODE-System size is now checked against the number of sim code equations - Cpp-Runtime does now create a valid modelDescription.xml --- .gitignore | 2 + Compiler/SimCode/HpcOmSimCodeMain.mo | 12 ++- Compiler/SimCode/SimCodeMain.mo | 9 +- Compiler/SimCode/SimCodeUtil.mo | 47 +++++++++- Compiler/Template/CodegenCpp.tpl | 2 +- Compiler/Template/CodegenCppHpcom.tpl | 67 +++++++------- Compiler/Template/CodegenCppInit.tpl | 91 +++++++++++++------ Compiler/Template/CodegenFMUCppHpcom.tpl | 109 +++++++++++++++++++++++ Compiler/Template/Makefile.common | 17 ++-- Compiler/Template/SimCodeTV.mo | 7 ++ Compiler/boot/LoadCompilerSources.mos | 1 + 11 files changed, 287 insertions(+), 77 deletions(-) create mode 100644 Compiler/Template/CodegenFMUCppHpcom.tpl diff --git a/.gitignore b/.gitignore index 508701febca..065d7fceba4 100644 --- a/.gitignore +++ b/.gitignore @@ -106,6 +106,7 @@ Compiler/Script/OpenModelicaScriptingAPIQt.h Compiler/Template/AbsynDumpTpl.mo Compiler/Template/CodegenAdevs.mo Compiler/Template/CodegenC.mo +Compiler/Template/CodegenCFunctions.mo Compiler/Template/CodegenC.mo.log Compiler/Template/CodegenCSharp.mo Compiler/Template/CodegenCpp.mo @@ -116,6 +117,7 @@ Compiler/Template/CodegenFMU1.mo Compiler/Template/CodegenFMU2.mo Compiler/Template/CodegenFMUCommon.mo Compiler/Template/CodegenFMUCpp.mo +Compiler/Template/CodegenFMUCppHpcom.mo Compiler/Template/CodegenJS.mo Compiler/Template/CodegenJava.mo Compiler/Template/CodegenModelica.mo diff --git a/Compiler/SimCode/HpcOmSimCodeMain.mo b/Compiler/SimCode/HpcOmSimCodeMain.mo index 164af6e321b..a577836126f 100644 --- a/Compiler/SimCode/HpcOmSimCodeMain.mo +++ b/Compiler/SimCode/HpcOmSimCodeMain.mo @@ -378,7 +378,7 @@ algorithm System.realtimeTick(ClockIndexes.RT_CLOCK_EXECSTAT_HPCOM_MODULES); //HpcOmTaskGraph.printTaskGraphMeta(taskGraphDataScheduled); - checkOdeSystemSize(taskGraphDataOdeScheduled,odeEquations); + checkOdeSystemSize(taskGraphDataOdeScheduled,odeEquations,sccSimEqMapping); SimCodeFunctionUtil.execStat("hpcom check ODE system size"); //Create Memory-Map and Sim-Code @@ -1249,8 +1249,10 @@ Remark: this can occur when asserts are added to the ode-system. author:marcusw" input HpcOmTaskGraph.TaskGraphMeta iTaskGraphMeta; input list> iOdeEqs; + input array> iSccSimEqMapping; output Boolean oIsCorrect; protected + Integer scc; list sccs; Integer actualSizePre, actualSize; Integer targetSize; @@ -1261,12 +1263,18 @@ algorithm if(intNe(actualSizePre, actualSize)) then print("There are simCode-equations multiple times in the graph structure.\n"); end if; + actualSize := 0; + for scc in sccs loop + actualSize := actualSize + listLength(arrayGet(iSccSimEqMapping, scc)); + end for; + targetSize := listLength(List.flatten(iOdeEqs)); oIsCorrect := intEq(targetSize,actualSize); if(oIsCorrect) then //print("the ODE-system size is correct("+intString(actualSize)+")\n"); else - print("the size should be "+intString(targetSize)+" but it is "+intString(actualSize)+"!\n"); + print("the size of the ODE-system should be "+intString(targetSize)+" but it is "+intString(actualSize)+"!\n"); + print("expected the following sim code equations: " + stringDelimitList(List.map(List.map(List.flatten(iOdeEqs), SimCodeUtil.simEqSystemIndex), intString), ",") + "\n"); print("the ODE-system is NOT correct\n"); end if; end checkOdeSystemSize; diff --git a/Compiler/SimCode/SimCodeMain.mo b/Compiler/SimCode/SimCodeMain.mo index c36b225e843..7aaf61b3440 100644 --- a/Compiler/SimCode/SimCodeMain.mo +++ b/Compiler/SimCode/SimCodeMain.mo @@ -62,6 +62,7 @@ import CevalScriptBackend; import CodegenC; import CodegenFMU; import CodegenFMUCpp; +import CodegenFMUCppHpcom; import CodegenQSS; import CodegenAdevs; import CodegenSparseFMI; @@ -142,7 +143,7 @@ algorithm fileDir := CevalScriptBackend.getFileDir(a_cref, p); (libs,libPaths,includes, includeDirs, recordDecls, functions, outIndexedBackendDAE, _, literals) := SimCodeUtil.createFunctions(p, dae, inBackendDAE, className); - (simCode,_) := SimCodeUtil.createSimCode(outIndexedBackendDAE, + simCode := createSimCode(outIndexedBackendDAE, className, filenamePrefix, fileDir, functions, includes, includeDirs, libs, libPaths,simSettingsOpt, recordDecls, literals,Absyn.FUNCTIONARGS({},{})); timeSimCode := System.realtimeTock(ClockIndexes.RT_CLOCK_SIMCODE); SimCodeFunctionUtil.execStat("SimCode"); @@ -574,7 +575,11 @@ algorithm then (); case (_,"Cpp") equation - Tpl.tplNoret3(CodegenFMUCpp.translateModel, simCode, FMUVersion, FMUType); + if(Flags.isSet(Flags.HPCOM)) then + Tpl.tplNoret3(CodegenFMUCppHpcom.translateModel, simCode, FMUVersion, FMUType); + else + Tpl.tplNoret3(CodegenFMUCpp.translateModel, simCode, FMUVersion, FMUType); + end if; then (); else equation diff --git a/Compiler/SimCode/SimCodeUtil.mo b/Compiler/SimCode/SimCodeUtil.mo index ec16e667752..7c27a4c6288 100644 --- a/Compiler/SimCode/SimCodeUtil.mo +++ b/Compiler/SimCode/SimCodeUtil.mo @@ -10052,20 +10052,44 @@ algorithm end getVarToArrayIndexByType; public function getVarIndexListByMapping "author: marcusw + Return the variable indices stored for the given variable in the mapping-table. If the variable is part of an array, all array indices are returned. This function is used by susan." + input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; + input DAE.ComponentRef iVarName; + input String iIndexForUndefinedReferences; + output list oVarIndexList; //if the variable is part of an array, all array indices are returned in this list (the list contains one element if the variable is a scalar) +algorithm + ((oVarIndexList,_)) := getVarIndexInfosByMapping(iVarToArrayIndexMapping, iVarName, iIndexForUndefinedReferences); +end getVarIndexListByMapping; + +public function getVarIndexByMapping "author: marcusw + Return the variable index stored for the given variable in the mapping-table. This function is used by susan." + input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; + input DAE.ComponentRef iVarName; + input String iIndexForUndefinedReferences; + output String oConcreteVarIndex; //the scalar index of the variable (this value is always part of oVarIndexList) +algorithm + ((_,oConcreteVarIndex)) := getVarIndexInfosByMapping(iVarToArrayIndexMapping, iVarName, iIndexForUndefinedReferences); +end getVarIndexByMapping; + +protected function getVarIndexInfosByMapping "author: marcusw Return the variable indices stored for the given variable in the mapping-table. This function is used by susan." input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; input DAE.ComponentRef iVarName; input String iIndexForUndefinedReferences; - output list oVarIndexList; + output list oVarIndexList; //if the variable is part of an array, all array indices are returned in this list (the list contains one element if the variable is a scalar) + output String oConcreteVarIndex; //the scalar index of the variable (this value is always part of oVarIndexList) protected DAE.ComponentRef varName = iVarName; - Integer arrayIdx, idx, arraySize; + Integer arrayIdx, idx, arraySize, concreteVarIndex; array varIndices; list tmpVarIndexListNew = {}; + list arraySubscripts; + list arrayDimensions; algorithm + arraySubscripts := ComponentReference.crefLastSubs(varName); varName := ComponentReference.crefStripLastSubs(varName);//removeSubscripts(varName); if(BaseHashTable.hasKey(varName, iVarToArrayIndexMapping)) then - ((_,varIndices)) := BaseHashTable.get(varName, iVarToArrayIndexMapping); + ((arrayDimensions,varIndices)) := BaseHashTable.get(varName, iVarToArrayIndexMapping); arraySize := arrayLength(varIndices); for arrayIdx in 0:(arraySize-1) loop idx := arrayGet(varIndices, arraySize-arrayIdx); @@ -10080,13 +10104,28 @@ algorithm end if; end if; end for; + ((concreteVarIndex,_,_)) := List.fold(listReverse(arraySubscripts), getUnrolledArrayIndex, (0, 1, listReverse(arrayDimensions))); + + // ignore all values that are undefined references and part of the same array + idx := 1; + while intLe (idx, concreteVarIndex) loop + if(intLt(arrayGet(varIndices, idx), 1)) then + concreteVarIndex := concreteVarIndex - 1; + end if; + idx := idx + 1; + end while; + + concreteVarIndex := intAbs(arrayGet(varIndices, 1)) - 1 + concreteVarIndex; + oConcreteVarIndex := intString(concreteVarIndex); end if; if(listEmpty(tmpVarIndexListNew)) then Error.addMessage(Error.INTERNAL_ERROR, {"GetVarIndexListByMapping: No Element for " + ComponentReference.printComponentRefStr(varName) + " found!"}); tmpVarIndexListNew := {iIndexForUndefinedReferences}; + oConcreteVarIndex := iIndexForUndefinedReferences; end if; + //print("SimCodeUtil.getVarIndexInfosByMapping: Variable " + ComponentReference.printComponentRefStr(iVarName) + " has variable indices {" + stringDelimitList(tmpVarIndexListNew, ",") + "} and concrete index " + oConcreteVarIndex + "\n"); oVarIndexList := tmpVarIndexListNew; -end getVarIndexListByMapping; +end getVarIndexInfosByMapping; public function isVarIndexListConsecutive "author: marcusw Check if all variable indices of the given variables, stored in the hash table, are consecutive." diff --git a/Compiler/Template/CodegenCpp.tpl b/Compiler/Template/CodegenCpp.tpl index 612e9fe6af8..87afbeb21dc 100644 --- a/Compiler/Template/CodegenCpp.tpl +++ b/Compiler/Template/CodegenCpp.tpl @@ -58,7 +58,7 @@ template translateModel(SimCode simCode) let()= textFile(simulationWriteOutputParameterCppFile(simCode , &extraFuncs , &extraFuncsDecl, "", false),'OMCpp<%fileNamePrefix%>WriteOutputParameter.cpp') let()= textFile(simulationWriteOutputAliasVarsCppFile(simCode , &extraFuncs , &extraFuncsDecl, "", stateDerVectorName, false),'OMCpp<%fileNamePrefix%>WriteOutputAliasVars.cpp') let()= textFile(simulationFactoryFile(simCode , &extraFuncs , &extraFuncsDecl, ""),'OMCpp<%fileNamePrefix%>FactoryExport.cpp') - let()= textFile(modelInitXMLFile(simCode, numRealVars, numIntVars, numBoolVars),'OMCpp<%fileNamePrefix%>Init.xml') + //let()= textFile(modelInitXMLFile(simCode, numRealVars, numIntVars, numBoolVars),'OMCpp<%fileNamePrefix%>Init.xml') let()= textFile(simulationMainRunScript(simCode , &extraFuncs , &extraFuncsDecl, "", "", "", "exec"), '<%fileNamePrefix%><%simulationMainRunScriptSuffix(simCode , &extraFuncs , &extraFuncsDecl, "")%>') let jac = (jacobianMatrixes |> (mat, _, _, _, _, _, _) => (mat |> (eqs,_,_) => algloopfiles(eqs,simCode , &extraFuncs , &extraFuncsDecl, "",contextAlgloopJacobian, stateDerVectorName, false) ;separator="") diff --git a/Compiler/Template/CodegenCppHpcom.tpl b/Compiler/Template/CodegenCppHpcom.tpl index 34b10ad23f7..8a1b43c389d 100644 --- a/Compiler/Template/CodegenCppHpcom.tpl +++ b/Compiler/Template/CodegenCppHpcom.tpl @@ -25,10 +25,10 @@ template translateModel(SimCode simCode) let useMemoryOptimization = Flags.isSet(Flags.HPCOM_MEMORY_OPT) let className = lastIdentOfPath(modelInfo.name) - let numRealVars = numRealvars(modelInfo, hpcomData.hpcOmMemory) - let numIntVars = numIntvars(modelInfo, hpcomData.hpcOmMemory) - let numBoolVars = numBoolvars(modelInfo, hpcomData.hpcOmMemory) - let numPreVars = getPreVarsCount(modelInfo, hpcomData.hpcOmMemory) + let numRealVars = numRealvarsHpcom(modelInfo, hpcomData.hpcOmMemory) + let numIntVars = numIntvarsHpcom(modelInfo, hpcomData.hpcOmMemory) + let numBoolVars = numBoolvarsHpcom(modelInfo, hpcomData.hpcOmMemory) + let numPreVars = numPreVarsHpcom(modelInfo, hpcomData.hpcOmMemory) let() = textFile(simulationMainFile(target, simCode, &extraFuncs, &extraFuncsDecl, "", (if Flags.isSet(USEMPI) then "#include " else ""), @@ -36,17 +36,17 @@ template translateModel(SimCode simCode) (if Flags.isSet(USEMPI) then mpiFinalize() else ""), numRealVars, numIntVars, numBoolVars, numPreVars), 'OMCpp<%fileNamePrefix%>Main.cpp') - let() = textFile(simulationCppFile(simCode, contextOther, update(allEquations, whenClauses, simCode, &extraFuncs, &extraFuncsDecl, "", contextOther, stateDerVectorName, false), + let() = textFile(simulationCppFile(simCode, contextOther, updateHpcom(allEquations, whenClauses, simCode, &extraFuncs, &extraFuncsDecl, "", contextOther, stateDerVectorName, false), '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', &extraFuncs, &extraFuncsDecl, className, - generateAdditionalConstructorDefinitions(hpcomData.schedules), - generateAdditionalConstructorBodyStatements(hpcomData.schedules, className, dotPath(modelInfo.name)), - generateAdditionalDestructorBodyStatements(hpcomData.schedules), + additionalHpcomConstructorDefinitions(hpcomData.schedules), + additionalHpcomConstructorBodyStatements(hpcomData.schedules, className, dotPath(modelInfo.name)), + additionalHpcomDestructorBodyStatements(hpcomData.schedules), stateDerVectorName, false), 'OMCpp<%fileNamePrefix%>.cpp') let() = textFile(simulationHeaderFile(simCode ,contextOther, &extraFuncs, &extraFuncsDecl, "", - generateAdditionalIncludes(simCode, &extraFuncs, &extraFuncsDecl, className, false), + additionalHpcomIncludes(simCode, &extraFuncs, &extraFuncsDecl, className, false), "", - generateAdditionalProtectedMemberDeclaration(simCode, &extraFuncs, &extraFuncsDecl, "", false), + additionalHpcomProtectedMemberDeclaration(simCode, &extraFuncs, &extraFuncsDecl, "", false), memberVariableDefine(modelInfo, varToArrayIndexMapping, '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', Flags.isSet(Flags.GEN_DEBUG_SYMBOLS), false), memberVariableDefinePreVariables(modelInfo, varToArrayIndexMapping, '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', Flags.isSet(Flags.GEN_DEBUG_SYMBOLS), false), false), //CodegenCpp.MemberVariablePreVariables(modelInfo,false), false), @@ -93,18 +93,18 @@ template translateModel(SimCode simCode) end translateModel; // HEADER -template generateAdditionalIncludes(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) +template additionalHpcomIncludes(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) "Generates code for header file for simulation target." ::= match simCode case SIMCODE(__) then << - <%generateAdditionalIncludesForParallelCode(simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace)%> + <%additionalHpcomIncludesForParallelCode(simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace)%> >> end match -end generateAdditionalIncludes; +end additionalHpcomIncludes; -template generateAdditionalIncludesForParallelCode(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace) +template additionalHpcomIncludesForParallelCode(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace) ::= let type = getConfigString(HPCOM_CODE) match type @@ -139,9 +139,9 @@ template generateAdditionalIncludesForParallelCode(SimCode simCode, Text& extraF #include >> end match -end generateAdditionalIncludesForParallelCode; +end additionalHpcomIncludesForParallelCode; -template generateAdditionalProtectedMemberDeclaration(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) +template additionalHpcomProtectedMemberDeclaration(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) "Generates class declarations." ::= match simCode @@ -196,7 +196,7 @@ template generateAdditionalProtectedMemberDeclaration(SimCode simCode, Text& ext >>%> >> end match -end generateAdditionalProtectedMemberDeclaration; +end additionalHpcomProtectedMemberDeclaration; template generateAdditionalStructHeaders(Schedule odeSchedule) ::= @@ -407,7 +407,7 @@ template generateThreadFunctionHeaderDecl(Integer threadIdx) >> end generateThreadFunctionHeaderDecl; -template generateAdditionalConstructorDefinitions(Option> scheduleOpt) +template additionalHpcomConstructorDefinitions(Option> scheduleOpt) ::= let type = getConfigString(HPCOM_CODE) match scheduleOpt @@ -435,9 +435,9 @@ template generateAdditionalConstructorDefinitions(Option> schedulesOpt, String modelNamePrefixStr, String fullModelName) +template additionalHpcomConstructorBodyStatements(Option> schedulesOpt, String modelNamePrefixStr, String fullModelName) ::= let type = getConfigString(HPCOM_CODE) match schedulesOpt @@ -524,7 +524,7 @@ template generateAdditionalConstructorBodyStatements(Option> end destroyArrayLocks; -template generateAdditionalDestructorBodyStatements(Option> schedulesOpt) +template additionalHpcomDestructorBodyStatements(Option> schedulesOpt) ::= let type = getConfigString(HPCOM_CODE) match schedulesOpt @@ -694,10 +694,9 @@ template generateAdditionalDestructorBodyStatements(Option allEquationsPlusWhen, list whenClauses, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) +template updateHpcom(list allEquationsPlusWhen, list whenClauses, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) ::= let &varDecls = buffer "" /*BUFD*/ @@ -716,7 +715,7 @@ template update(list allEquationsPlusWhen, list when <%parCode%> >> end match -end update; +end updateHpcom; template generateParallelEvaluate(list allEquationsPlusWhen, Absyn.Path name, list whenClauses, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Option> schedulesOpt, Context context, Text stateDerVectorName /*=__zDot*/, @@ -1880,41 +1879,41 @@ template simulationMakefile(String target, SimCode simCode, Text& extraFuncs, Te additionalLinkerFlags_MSVC, Flags.isSet(Flags.USEMPI)) end simulationMakefile; -template getPreVarsCount(ModelInfo modelInfo, Option hpcOmMemoryOpt) +template numPreVarsHpcom(ModelInfo modelInfo, Option hpcOmMemoryOpt) ::= match(hpcOmMemoryOpt) case(SOME(hpcomMemory as MEMORYMAP_ARRAY(floatArraySize=floatArraySize,intArraySize=intArraySize,boolArraySize=boolArraySize))) then '<%floatArraySize%> + <%intArraySize%> + <%boolArraySize%>' else CodegenCpp.getPreVarsCount(modelInfo) -end getPreVarsCount; +end numPreVarsHpcom; -template numRealvars(ModelInfo modelInfo, Option hpcOmMemoryOpt) +template numRealvarsHpcom(ModelInfo modelInfo, Option hpcOmMemoryOpt) ::= match(hpcOmMemoryOpt) case(SOME(hpcomMemory as MEMORYMAP_ARRAY(floatArraySize=floatArraySize))) then '<%floatArraySize%>' else '<%CodegenCpp.numRealvars(modelInfo)%>' -end numRealvars; +end numRealvarsHpcom; -template numIntvars(ModelInfo modelInfo, Option hpcOmMemoryOpt) +template numIntvarsHpcom(ModelInfo modelInfo, Option hpcOmMemoryOpt) ::= match(hpcOmMemoryOpt) case(SOME(hpcomMemory as MEMORYMAP_ARRAY(intArraySize=intArraySize))) then '<%intArraySize%>' else CodegenCpp.numIntvars(modelInfo) -end numIntvars; +end numIntvarsHpcom; -template numBoolvars(ModelInfo modelInfo, Option hpcOmMemoryOpt) +template numBoolvarsHpcom(ModelInfo modelInfo, Option hpcOmMemoryOpt) ::= match(hpcOmMemoryOpt) case(SOME(hpcomMemory as MEMORYMAP_ARRAY(boolArraySize=boolArraySize))) then '<%boolArraySize%>' else CodegenCpp.numBoolvars(modelInfo) -end numBoolvars; +end numBoolvarsHpcom; annotation(__OpenModelica_Interface="backend"); end CodegenCppHpcom; diff --git a/Compiler/Template/CodegenCppInit.tpl b/Compiler/Template/CodegenCppInit.tpl index b605d929f3d..9a8a766ca02 100644 --- a/Compiler/Template/CodegenCppInit.tpl +++ b/Compiler/Template/CodegenCppInit.tpl @@ -1,55 +1,77 @@ package CodegenCppInit import interface SimCodeTV; +import interface SimCodeBackendTV; import CodegenUtil.*; +import CodegenFMUCommon; +import CodegenFMU2; +import CodegenFMU1; -template modelInitXMLFile(SimCode simCode, String numRealVars, String numIntVars, String numBoolVars) +template modelInitXMLFile(SimCode simCode, String numRealVars, String numIntVars, String numBoolVars, String FMUVersion, String FMUType, String FMUGuid, Boolean generateFMUModelDescription, String generatorComments) + "Generate a xml file that contains informations for initialization or for the FMU-structure" ::= match simCode case SIMCODE(modelInfo = MODELINFO(__)) then - let variables = modelVariablesXML(modelInfo, varToArrayIndexMapping, '<%numRealVars%> - 1', '<%numIntVars%> - 1', '<%numBoolVars%> - 1') + let variables = modelVariablesXML(modelInfo, varToArrayIndexMapping, '<%numRealVars%> - 1', '<%numIntVars%> - 1', '<%numBoolVars%> - 1', generateFMUModelDescription) let algLoops = (listAppend(allEquations,initialEquations) |> eq => algLoopXML(eq, simCode, varToArrayIndexMapping, '<%numRealVars%> - 1') ;separator="\n") let jacobianMatrixes = jacobianMatrixesXML(simCode.jacobianMatrixes) + let descriptionTag = if generateFMUModelDescription then "fmiModelDescription" else "ModelDescription" + let fmiDescriptionAttributes = if generateFMUModelDescription then fmuDescriptionAttributes(simCode, FMUVersion, FMUType, FMUGuid) else 'modelName="<%dotPath(modelInfo.name)%>"' + let fmiTypeDefinitions = if generateFMUModelDescription then CodegenFMUCommon.fmiTypeDefinitions(modelInfo, FMUVersion) + let fmiDefaultExperiment = if generateFMUModelDescription then CodegenFMUCommon.DefaultExperiment(simulationSettingsOpt) << - - + + + <<%descriptionTag%> <%fmiDescriptionAttributes%>> + <%fmiTypeDefinitions%> + <%fmiDefaultExperiment%> <%variables%> + <%if boolNot(generateFMUModelDescription) then + << <%algLoops%> <%jacobianMatrixes%> - + >> + %> + > >> end modelInitXMLFile; -template modelVariablesXML(ModelInfo modelInfo, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferencesReal, String indexForUndefinedReferencesInt, String indexForUndefinedReferencesBool) +template fmuDescriptionAttributes(SimCode simCode, String FMUVersion, String FMUType, String FMUGuid) +::= + if isFMIVersion20(FMUVersion) then CodegenFMU2.fmiModelDescriptionAttributes(simCode,FMUGuid) + else CodegenFMU1.fmiModelDescriptionAttributes(simCode,FMUGuid) +end fmuDescriptionAttributes; + +template modelVariablesXML(ModelInfo modelInfo, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferencesReal, String indexForUndefinedReferencesInt, String indexForUndefinedReferencesBool, Boolean generateFMUModelDescription) "Generates the xml code for the variable defintions." ::= match modelInfo case MODELINFO(vars=SIMVARS(__),varInfo=VARINFO(numAlgVars= numAlgVars, numDiscreteReal = numDiscreteReal, numOptimizeConstraints = numOptimizeConstraints)) then << - <%vars.stateVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty%> - <%vars.derivativeVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty%> - <%vars.algVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty%> - <%vars.discreteAlgVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty%> + <%vars.stateVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.derivativeVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.algVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.discreteAlgVars |> var => scalarVariableXML(var, varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty%> <%/*vars.realOptimizeConstraintsVars - |> var hasindex i0 => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty*/%> + |> var hasindex i0 => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty*/%> <%/*vars.realOptimizeFinalConstraintsVars - |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty*/%> - <%vars.paramVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty%> - <%vars.aliasVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal) ;separator="\n";empty%> + |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty*/%> + <%vars.paramVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.aliasVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesReal, generateFMUModelDescription) ;separator="\n";empty%> - <%vars.intAlgVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesInt) ;separator="\n";empty%> - <%vars.intParamVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesInt) ;separator="\n";empty%> - <%vars.intAliasVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesInt) ;separator="\n";empty%> + <%vars.intAlgVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesInt, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.intParamVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesInt, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.intAliasVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesInt, generateFMUModelDescription) ;separator="\n";empty%> - <%vars.boolAlgVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesBool) ;separator="\n";empty%> - <%vars.boolParamVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesBool) ;separator="\n";empty%> - <%vars.boolAliasVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesBool) ;separator="\n";empty%> + <%vars.boolAlgVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesBool, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.boolParamVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesBool, generateFMUModelDescription) ;separator="\n";empty%> + <%vars.boolAliasVars |> var => scalarVariableXML(var,varToArrayIndexMapping, indexForUndefinedReferencesBool, generateFMUModelDescription) ;separator="\n";empty%> >> /* <%vars.stringAlgVars |> var hasindex i0 => ScalarVariable(var,i0,"sAlg") ;separator="\n";empty%> @@ -58,31 +80,46 @@ template modelVariablesXML(ModelInfo modelInfo, HashTableCrIListArray.HashTable */ end modelVariablesXML; -template scalarVariableXML(SimVar simVar, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferences) +template scalarVariableXML(SimVar simVar, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferences, Boolean generateFMUModelDescription) "Generates code for ScalarVariable file for FMU target." ::= match simVar case SIMVAR(__) then + let variableCode = if generateFMUModelDescription then CodegenFMUCommon.ScalarVariableType(simVar) else + ScalarVariableType(unit, displayUnit, minValue, maxValue, initialValue, nominalValue, isFixed, type_) << - > - <%ScalarVariableType(unit, displayUnit, minValue, maxValue, initialValue, nominalValue, isFixed, type_)%> + > + <%variableCode%> >> end scalarVariableXML; -template scalarVariableAttributeXML(SimVar simVar, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferences) +template scalarVariableAttributeXML(SimVar simVar, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferences, Boolean generateFMUModelDescription) "Generates code for ScalarVariable Attribute file for FMU target." ::= match simVar case SIMVAR(source = SOURCE(info = info)) then - let valueReference = SimCodeUtil.getVarIndexListByMapping(varToArrayIndexMapping,name,indexForUndefinedReferences) + let valueReference = SimCodeUtil.getVarIndexByMapping(varToArrayIndexMapping,name,indexForUndefinedReferences) + let alias = getAliasVar(aliasvar) + let causalityAtt = CodegenFMUCommon.getCausality(causality) let variability = getVariablity(varKind) - let description = if comment then 'description = "<%Util.escapeModelicaStringToXmlString(comment)%>"' + let description = if comment then 'description="<%Util.escapeModelicaStringToXmlString(comment)%>"' + let additionalAttributes = if generateFMUModelDescription then '' else 'isProtected="<%isProtected%>' << - name = "<%Util.escapeModelicaStringToXmlString(crefStrNoUnderscore(name))%>" valueReference = "<%valueReference%>" <%description%> variability = "<%variability%>" isProtected = "<%isProtected%>" + name="<%Util.escapeModelicaStringToXmlString(crefStrNoUnderscore(name))%>" valueReference="<%valueReference%>" <%description%> variability="<%variability%>" causality="<%causalityAtt%>" alias="<%alias%>" <%additionalAttributes%> >> end scalarVariableAttributeXML; +template getAliasVar(AliasVariable aliasvar) + "Returns the alias Attribute of ScalarVariable." + ::= + match aliasvar + case NOALIAS(__) then "noAlias" + case ALIAS(__) then "alias" + case NEGATEDALIAS(__) then "negatedAlias" + else "noAlias" +end getAliasVar; + template algLoopXML(SimEqSystem eqs, SimCode simCode, HashTableCrIListArray.HashTable varToArrayIndexMapping, String indexForUndefinedReferences) ::= << diff --git a/Compiler/Template/CodegenFMUCppHpcom.tpl b/Compiler/Template/CodegenFMUCppHpcom.tpl new file mode 100644 index 00000000000..93b433ba862 --- /dev/null +++ b/Compiler/Template/CodegenFMUCppHpcom.tpl @@ -0,0 +1,109 @@ +// This file defines templates for transforming Modelica/MetaModelica code to FMU +// code. They are used in the code generator phase of the compiler to write +// target code. +// +// There are one root template intended to be called from the code generator: +// translateModel. These template do not return any +// result but instead write the result to files. All other templates return +// text and are used by the root templates (most of them indirectly). +// +// To future maintainers of this file: +// +// - A line like this +// # var = "" /*BUFD*/ +// declares a text buffer that you can later append text to. It can also be +// passed to other templates that in turn can append text to it. In the new +// version of Susan it should be written like this instead: +// let &var = buffer "" +// +// - A line like this +// ..., Text var /*BUFP*/, ... +// declares that a template takes a text buffer as input parameter. In the +// new version of Susan it should be written like this instead: +// ..., Text &var, ... +// +// - A line like this: +// ..., var /*BUFC*/, ... +// passes a text buffer to a template. In the new version of Susan it should +// be written like this instead: +// ..., &var, ... +// +// - Style guidelines: +// +// - Try (hard) to limit each row to 80 characters +// +// - Code for a template should be indented with 2 spaces +// +// - Exception to this rule is if you have only a single case, then that +// single case can be written using no indentation +// +// This single case can be seen as a clarification of the input to the +// template +// +// - Code after a case should be indented with 2 spaces if not written on the +// same line + +package CodegenFMUCppHpcom + + + +import interface SimCodeBackendTV; +import interface SimCodeTV; +import CodegenFMUCpp.*; +import CodegenCppHpcom.*; +import CodegenUtil; +import CodegenCpp; +import CodegenCppInit; + +template translateModel(SimCode simCode, String FMUVersion, String FMUType) + "Generates C++ code and Makefile for compiling an FMU of a Modelica model. + Calls CodegenCpp.translateModel for the actual model code." +::= + match simCode + case SIMCODE(modelInfo = MODELINFO(__), makefileParams = MAKEFILE_PARAMS(__), hpcomData = HPCOMDATA(__)) then + let guid = getUUIDStr() + let target = simulationCodeTarget() + let stateDerVectorName = "__zDot" + let &extraFuncs = buffer "" /*BUFD*/ + let &extraFuncsDecl = buffer "" /*BUFD*/ + + let className = CodegenCpp.lastIdentOfPath(modelInfo.name) + let numRealVars = numRealvarsHpcom(modelInfo, hpcomData.hpcOmMemory) + let numIntVars = numIntvarsHpcom(modelInfo, hpcomData.hpcOmMemory) + let numBoolVars = numBoolvarsHpcom(modelInfo, hpcomData.hpcOmMemory) + let numPreVars = numPreVarsHpcom(modelInfo, hpcomData.hpcOmMemory) + + let()= textFile(CodegenCppInit.modelInitXMLFile(simCode, numRealVars, numIntVars, numBoolVars, FMUVersion, FMUType, guid, true, "hpcom cpp-runtime"), 'modelDescription.xml') + let cpp = CodegenCpp.translateModel(simCode) + let()= textFile(fmuWriteOutputHeaderFile(simCode , &extraFuncs , &extraFuncsDecl, ""),'OMCpp<%fileNamePrefix%>WriteOutput.h') + let()= textFile(fmuModelHeaderFile(simCode, extraFuncs, extraFuncsDecl, "",guid, FMUVersion), 'OMCpp<%fileNamePrefix%>FMU.h') + let()= textFile(fmuModelCppFile(simCode, extraFuncs, extraFuncsDecl, "",guid, FMUVersion), 'OMCpp<%fileNamePrefix%>FMU.cpp') + //let()= textFile(modelInitXMLFile(simCode, numRealVars, numIntVars, numBoolVars, true, FMUVersion, FMUType, guid), '') + // Def file is only used on windows, to define exported symbols + //let()= textFile(fmudeffile(simCode, FMUVersion), '<%fileNamePrefix%>.def') + let()= textFile(fmuMakefile(target,simCode, extraFuncs, extraFuncsDecl, "", FMUVersion), '<%fileNamePrefix%>_FMU.makefile') + let()= textFile(fmuCalcHelperMainfile(simCode), 'OMCpp<%fileNamePrefix%>CalcHelperMain.cpp') + + let() = textFile(CodegenCpp.simulationCppFile(simCode, contextOther, updateHpcom(allEquations, whenClauses, simCode, &extraFuncs, &extraFuncsDecl, "", contextOther, stateDerVectorName, false), + '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', &extraFuncs, &extraFuncsDecl, className, + additionalHpcomConstructorDefinitions(hpcomData.schedules), + additionalHpcomConstructorBodyStatements(hpcomData.schedules, className, CodegenUtil.dotPath(modelInfo.name)), + additionalHpcomDestructorBodyStatements(hpcomData.schedules), + stateDerVectorName, false), 'OMCpp<%fileNamePrefix%>.cpp') + + let() = textFile(CodegenCpp.simulationHeaderFile(simCode ,contextOther, &extraFuncs, &extraFuncsDecl, "", + additionalHpcomIncludes(simCode, &extraFuncs, &extraFuncsDecl, className, false), + "", + additionalHpcomProtectedMemberDeclaration(simCode, &extraFuncs, &extraFuncsDecl, "", false), + CodegenCpp.memberVariableDefine(modelInfo, varToArrayIndexMapping, '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', Flags.isSet(Flags.GEN_DEBUG_SYMBOLS), false), + CodegenCpp.memberVariableDefinePreVariables(modelInfo, varToArrayIndexMapping, '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', Flags.isSet(Flags.GEN_DEBUG_SYMBOLS), false), false), + 'OMCpp<%fileNamePrefix%>.h') + "" + // empty result of the top-level template .., only side effects + end match +end translateModel; + +annotation(__OpenModelica_Interface="backend"); +end CodegenFMUCppHpcom; + +// vim: filetype=susan sw=2 sts=2 \ No newline at end of file diff --git a/Compiler/Template/Makefile.common b/Compiler/Template/Makefile.common index cd07f0dd911..c8015fb593d 100644 --- a/Compiler/Template/Makefile.common +++ b/Compiler/Template/Makefile.common @@ -1,6 +1,6 @@ .PHONY : all -GENERATED_FILES=AbsynDumpTpl.mo CodegenUtil.mo CodegenC.mo CodegenCFunctions.mo CodegenFMUCommon.mo CodegenFMU.mo CodegenFMU1.mo CodegenFMU2.mo CodegenCSharp.mo CodegenQSS.mo CodegenCpp.mo CodegenCppHpcom.mo CodegenFMUCpp.mo CodegenCppInit.mo CodegenModelica.mo DAEDumpTpl.mo ExpressionDumpTpl.mo GraphvizDump.mo GraphMLDumpTpl.mo NFInstDumpTpl.mo SimCodeDump.mo Unparsing.mo SCodeDumpTpl.mo CodegenAdevs.mo CodegenSparseFMI.mo CodegenXML.mo CodegenJava.mo CodegenJS.mo TplCodegen.mo TaskSystemDump.mo GenerateAPIFunctionsTpl.mo VisualXMLTpl.mo +GENERATED_FILES=AbsynDumpTpl.mo CodegenUtil.mo CodegenC.mo CodegenCFunctions.mo CodegenFMUCommon.mo CodegenFMU.mo CodegenFMU1.mo CodegenFMU2.mo CodegenCSharp.mo CodegenQSS.mo CodegenCpp.mo CodegenCppHpcom.mo CodegenFMUCpp.mo CodegenFMUCppHpcom.mo CodegenCppInit.mo CodegenModelica.mo DAEDumpTpl.mo ExpressionDumpTpl.mo GraphvizDump.mo GraphMLDumpTpl.mo NFInstDumpTpl.mo SimCodeDump.mo Unparsing.mo SCodeDumpTpl.mo CodegenAdevs.mo CodegenSparseFMI.mo CodegenXML.mo CodegenJava.mo CodegenJS.mo TplCodegen.mo TaskSystemDump.mo GenerateAPIFunctionsTpl.mo VisualXMLTpl.mo all : $(GENERATED_FILES) @@ -56,6 +56,14 @@ CodegenFMU2.mo : CodegenFMU2.tpl CodegenFMUCommon.tpl CodegenFMUCommon.mo SimCod @echo " ** CodegenFMU2 template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) @echo " " +CodegenFMUCpp.mo : CodegenFMUCpp.tpl SimCodeTV.mo SimCodeBackendTV.mo CodegenC.tpl CodegenUtil.tpl CodegenCpp.tpl CodegenFMU.tpl + @echo " ** CodegenFMUCpp template compilation ** " + $(OMC) $< > $@.log || (cat $@.log && false) + @echo " " +CodegenFMUCppHpcom.mo : CodegenFMUCppHpcom.tpl CodegenFMUCpp.tpl SimCodeTV.mo SimCodeBackendTV.mo CodegenCppHpcom.tpl CodegenUtil.tpl CodegenCpp.tpl CodegenFMU.tpl + @echo " ** CodegenFMUCppHpcom template compilation ** " + $(OMC) $< > $@.log || (cat $@.log && false) + @echo " " CodegenModelica.mo : CodegenModelica.tpl @echo " ** CodegenModelica template compilation ** " @@ -97,12 +105,7 @@ CodegenCppHpcom.mo : CodegenCppHpcom.tpl SimCodeTV.mo SimCodeBackendTV.mo Codege $(OMC) $< > $@.log || (cat $@.log && false) @echo " " -CodegenFMUCpp.mo : CodegenFMUCpp.tpl SimCodeTV.mo SimCodeBackendTV.mo CodegenC.tpl CodegenUtil.tpl CodegenCpp.tpl CodegenFMU.tpl - @echo " ** CodegenFMUCpp template compilation ** " - $(OMC) $< > $@.log || (cat $@.log && false) - @echo " " - -CodegenCppInit.mo : CodegenCppInit.tpl SimCodeTV.mo CodegenUtil.tpl +CodegenCppInit.mo : CodegenCppInit.tpl SimCodeTV.mo SimCodeBackendTV.mo CodegenUtil.tpl CodegenFMUCommon.tpl @echo " ** CodegenCppInit template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) @echo " " diff --git a/Compiler/Template/SimCodeTV.mo b/Compiler/Template/SimCodeTV.mo index f5376fb0b96..7431c7afee8 100644 --- a/Compiler/Template/SimCodeTV.mo +++ b/Compiler/Template/SimCodeTV.mo @@ -813,6 +813,13 @@ package SimCodeUtil output list oVarIndexList; end getVarIndexListByMapping; + function getVarIndexByMapping + input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; + input DAE.ComponentRef iVarName; + input String iIndexForUndefinedReferences; + output String oVarIndex; + end getVarIndexByMapping; + function isVarIndexListConsecutive input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; input DAE.ComponentRef iVarName; diff --git a/Compiler/boot/LoadCompilerSources.mos b/Compiler/boot/LoadCompilerSources.mos index 0d6238bad3b..9a084f080cc 100644 --- a/Compiler/boot/LoadCompilerSources.mos +++ b/Compiler/boot/LoadCompilerSources.mos @@ -299,6 +299,7 @@ if true then /* Suppress output */ "../Template/CodegenFMU2.mo", "../Template/CodegenFMUCommon.mo", "../Template/CodegenFMUCpp.mo", + "../Template/CodegenFMUCppHpcom.mo", "../Template/CodegenJava.mo", "../Template/CodegenJS.mo", "../Template/CodegenModelica.mo",