diff --git a/Compiler/BackEnd/BackendDAECreate.mo b/Compiler/BackEnd/BackendDAECreate.mo index daccdaa15f6..a98988fab01 100644 --- a/Compiler/BackEnd/BackendDAECreate.mo +++ b/Compiler/BackEnd/BackendDAECreate.mo @@ -68,7 +68,7 @@ protected import HashTable; protected import HashTableCrToExpSourceTpl; protected import Inline; protected import List; -protected import SimCodeUtil; +protected import SimCodeFunctionUtil; protected import SCode; protected import System; protected import Types; @@ -154,7 +154,7 @@ algorithm neqStr := intString(BackendDAEUtil.equationSize(eqnarr)); nvarStr := intString(BackendVariable.varsSize(vars_1)); Error.assertionOrAddSourceMessage(not Flags.isSet(Flags.DUMP_BACKENDDAE_INFO),Error.BACKENDDAEINFO_LOWER,{neqStr,nvarStr},Absyn.dummyInfo); - SimCodeUtil.execStat("Generate backend data structure"); + SimCodeFunctionUtil.execStat("Generate backend data structure"); end lower; protected function lower2 diff --git a/Compiler/BackEnd/BackendDAEUtil.mo b/Compiler/BackEnd/BackendDAEUtil.mo index f041ddbbc56..6149e2c730f 100644 --- a/Compiler/BackEnd/BackendDAEUtil.mo +++ b/Compiler/BackEnd/BackendDAEUtil.mo @@ -100,7 +100,7 @@ protected import OnRelaxation; protected import RemoveSimpleEquations; protected import ResolveLoops; protected import SCode; -protected import SimCodeUtil; +protected import SimCodeFunctionUtil; protected import StateMachineFeatures; protected import SymbolicJacobian; protected import SynchronousFeatures; @@ -6591,34 +6591,6 @@ algorithm end match; end traverseBackendDAEExpsOptEqnWithUpdate; -public function traverseAlgorithmExps " - This function goes through the Algorithm structure and finds all the - expressions and performs the function on them -" - replaceable type Type_a subtypeof Any; - input DAE.Algorithm inAlgorithm; - input FuncExpType func; - input Type_a inTypeA; - output Type_a outTypeA; - partial function FuncExpType - input DAE.Exp inExp; - input Type_a inTypeA; - output DAE.Exp outExp; - output Type_a outA; - end FuncExpType; -algorithm - outTypeA := match (inAlgorithm,func,inTypeA) - local - list stmts; - Type_a ext_arg_1; - case (DAE.ALGORITHM_STMTS(statementLst = stmts),_,_) - equation - (_,ext_arg_1) = DAEUtil.traverseDAEEquationsStmts(stmts,func,inTypeA); - then - ext_arg_1; - end match; -end traverseAlgorithmExps; - public function traverseAlgorithmExpsWithUpdate " This function goes through the Algorithm structure and finds all the expressions and performs the function on them @@ -6749,7 +6721,7 @@ algorithm // transformation phase (matching and sorting using index reduction method) sode := causalizeDAE(optdae, NONE(), matchingAlgorithm, daeHandler, true); - SimCodeUtil.execStat("matching and sorting"); + SimCodeFunctionUtil.execStat("matching and sorting"); if Flags.isSet(Flags.GRAPHML) then HpcOmTaskGraph.dumpBipartiteGraph(sode, fileNamePrefix); @@ -6763,13 +6735,13 @@ algorithm (optsode, Util.SUCCESS()) := postOptimizeDAE(sode, postOptModules, matchingAlgorithm, daeHandler); sode1 := FindZeroCrossings.findZeroCrossings(optsode); - SimCodeUtil.execStat("findZeroCrossings"); + SimCodeFunctionUtil.execStat("findZeroCrossings"); _ := traverseBackendDAEExpsNoCopyWithUpdate(sode1, ExpressionSimplify.simplifyTraverseHelper, 0) "simplify all expressions"; - SimCodeUtil.execStat("SimplifyAllExp"); + SimCodeFunctionUtil.execStat("SimplifyAllExp"); outSODE := calculateValues(sode1); - SimCodeUtil.execStat("calculateValue"); + SimCodeFunctionUtil.execStat("calculateValue"); if Flags.isSet(Flags.DUMP_INDX_DAE) then BackendDump.dumpBackendDAE(outSODE, "dumpindxdae"); @@ -6830,7 +6802,7 @@ algorithm BackendDAE.DAE(systs, shared) = optModule(inDAE); systs = filterEmptySystems(systs); dae = BackendDAE.DAE(systs, shared); - SimCodeUtil.execStat("preOpt " + moduleStr); + SimCodeFunctionUtil.execStat("preOpt " + moduleStr); if Flags.isSet(Flags.OPT_DAE_DUMP) then print(stringAppendList({"\npre-optimization module ", moduleStr, ":\n\n"})); BackendDump.printBackendDAE(dae); @@ -6839,7 +6811,7 @@ algorithm then (dae1, status); case (_, (_, moduleStr, b)::rest) equation - SimCodeUtil.execStat(" preOpt " + moduleStr); + SimCodeFunctionUtil.execStat(" preOpt " + moduleStr); str = stringAppendList({"pre-optimization module ", moduleStr, " failed."}); Error.addMessage(Error.INTERNAL_ERROR, {str}); (dae,status) = preOptimizeDAE(inDAE,rest); @@ -6881,7 +6853,7 @@ algorithm BackendDAE.DAE(systs,shared) := inDAE; // reduce index (systs,shared,args,causalized) := mapCausalizeDAE(systs,shared,inMatchingOptions,matchingAlgorithm,stateDeselection,{},{},false); - //SimCodeUtil.execStat("matching"); + //SimCodeFunctionUtil.execStat("matching"); // do late inline outDAE := if dolateinline then BackendInline.lateInlineFunction(BackendDAE.DAE(systs,shared)) else BackendDAE.DAE(systs,shared); // do state selection @@ -6889,7 +6861,7 @@ algorithm // sort assigned equations to blt form systs := mapSortEqnsDAE(systs,shared,{}); outDAE := BackendDAE.DAE(systs,shared); - //SimCodeUtil.execStat("sorting"); + //SimCodeFunctionUtil.execStat("sorting"); end causalizeDAE; protected function mapCausalizeDAE " @@ -6971,10 +6943,10 @@ algorithm nvars = BackendVariable.daenumVariables(syst); neqns = systemSize(syst); syst = Causalize.singularSystemCheck(nvars,neqns,syst,match_opts,matchingAlgorithm,arg,ishared); - // SimCodeUtil.execStat("transformDAE -> singularSystemCheck " + mAmethodstr); + // SimCodeFunctionUtil.execStat("transformDAE -> singularSystemCheck " + mAmethodstr); // match the system and reduce index if neccessary (syst,shared,arg) = matchingAlgorithmfunc(syst, ishared, false, match_opts, sssHandler, arg); - // SimCodeUtil.execStat("transformDAE -> matchingAlgorithm " + mAmethodstr + " index Reduction Method " + str1); + // SimCodeFunctionUtil.execStat("transformDAE -> matchingAlgorithm " + mAmethodstr + " index Reduction Method " + str1); then (syst,shared,SOME(arg),true); case (_,_,_,(_,mAmethodstr),(_,str1,_,_),_) @@ -7009,7 +6981,7 @@ algorithm equation // do state selection outDAE = sDfunc(BackendDAE.DAE(systs,shared),args); - //SimCodeUtil.execStat("transformDAE -> state selection " + methodstr); + //SimCodeFunctionUtil.execStat("transformDAE -> state selection " + methodstr); then outDAE; else inDAE; @@ -7120,7 +7092,7 @@ algorithm BackendDAE.DAE(systs, shared) = optModule(inDAE); systs = filterEmptySystems(systs); dae = BackendDAE.DAE(systs, shared); - SimCodeUtil.execStat("postOpt " + moduleStr); + SimCodeFunctionUtil.execStat("postOpt " + moduleStr); if Flags.isSet(Flags.OPT_DAE_DUMP) then print(stringAppendList({"\npost-optimization module ", moduleStr, ":\n\n"})); BackendDump.printBackendDAE(dae); @@ -7131,7 +7103,7 @@ algorithm case (_, (_, moduleStr, b)::rest, _, _) equation - SimCodeUtil.execStat("postOpt " + moduleStr); + SimCodeFunctionUtil.execStat("postOpt " + moduleStr); str = stringAppendList({"post-optimization module ", moduleStr, " failed."}); Error.addMessage(Error.INTERNAL_ERROR, {str}); (dae,status) = postOptimizeDAE(inDAE,rest,matchingAlgorithm,daeHandler); diff --git a/Compiler/BackEnd/BackendQSS.mo b/Compiler/BackEnd/BackendQSS.mo index 5c340e576d5..6490e7edb51 100644 --- a/Compiler/BackEnd/BackendQSS.mo +++ b/Compiler/BackEnd/BackendQSS.mo @@ -55,7 +55,7 @@ protected import BackendVariable; protected import ComponentReference; protected import HpcOmSimCode; protected import List; -protected import SimCodeUtil; +protected import SimCodeFunctionUtil; public uniontype QSSinfo "- equation indices in static blocks and DEVS structure" @@ -614,7 +614,7 @@ end generateHandler; // then computeAlgs(tail,states,listAppend(i_algs,{cref})); // case ((SimCode.SES_LINEAR(vars=vars)) :: tail,_,_) // equation -// vars_cref = List.map(vars,SimCodeUtil.varName); +// vars_cref = List.map(vars,SimCodeFunctionUtil.varName); // then computeAlgs(tail,states,listAppend(i_algs,vars_cref)); // case ({},_,_) // equation @@ -802,9 +802,9 @@ algorithm case (SimCode.SES_SIMPLE_ASSIGN(cref=cref,exp=exp), SimCodeVar.SIMVARS(paramVars=paramVars,intParamVars=intParamVars,boolParamVars=boolParamVars)) equation - failure(_ = List.position(cref,List.map(paramVars,SimCodeUtil.varName))); - failure(_ = List.position(cref,List.map(intParamVars,SimCodeUtil.varName))); - failure(_ = List.position(cref,List.map(boolParamVars,SimCodeUtil.varName))); + failure(_ = List.position(cref,List.map(paramVars,SimCodeFunctionUtil.varName))); + failure(_ = List.position(cref,List.map(intParamVars,SimCodeFunctionUtil.varName))); + failure(_ = List.position(cref,List.map(boolParamVars,SimCodeFunctionUtil.varName))); t = stringAppend("parameter Real ",System.stringReplace(replaceCref(cref,{},{},{}),".","_")); t = stringAppend(t," = "); t = stringAppend(t,ExpressionDump.printExpStr(replaceVars(exp,{},{},{}))); diff --git a/Compiler/BackEnd/HpcOmMemory.mo b/Compiler/BackEnd/HpcOmMemory.mo index 7e82478d321..3b46f639d32 100644 --- a/Compiler/BackEnd/HpcOmMemory.mo +++ b/Compiler/BackEnd/HpcOmMemory.mo @@ -30,31 +30,34 @@ */ encapsulated package HpcOmMemory - public import BackendDAE; - public import DAE; - public import HashTableCrILst; - public import HpcOmSimCode; - public import HpcOmTaskGraph; - public import SimCode; - public import SimCodeVar; - - protected import Array; - protected import BackendDAEUtil; - protected import BackendDump; - protected import BackendEquation; - protected import BackendVariable; - protected import BaseHashTable; - protected import ComponentReference; - protected import Config; - protected import Debug; - protected import Error; - protected import Expression; - protected import Flags; - protected import GraphML; - protected import HpcOmScheduler; - protected import List; - protected import SimCodeUtil; - protected import Util; +import BackendDAE; +import DAE; +import HashTableCrILst; +import HpcOmSimCode; +import HpcOmTaskGraph; +import SimCode; +import SimCodeVar; + +protected + +import Array; +import BackendDAEUtil; +import BackendDump; +import BackendEquation; +import BackendVariable; +import BaseHashTable; +import ComponentReference; +import Config; +import Debug; +import Error; +import Expression; +import Flags; +import GraphML; +import HpcOmScheduler; +import List; +import SimCodeUtil; +import SimCodeFunctionUtil; +import Util; // ------------------------------------------- // STRUCTURES @@ -2867,7 +2870,7 @@ encapsulated package HpcOmMemory threadText := "Th -1"; if(Util.isSome(simVarOpt)) then simVar := Util.getOption(simVarOpt); - varCompRef := SimCodeUtil.varName(simVar); + varCompRef := SimCodeFunctionUtil.varName(simVar); description := ComponentReference.printComponentRefStr(varCompRef); isValidVar := BaseHashTable.hasKey(varCompRef, iVarNameSCVarIdxMapping); diff --git a/Compiler/BackEnd/HpcOmScheduler.mo b/Compiler/BackEnd/HpcOmScheduler.mo index 91b30c17c9b..5ae39eea5e0 100644 --- a/Compiler/BackEnd/HpcOmScheduler.mo +++ b/Compiler/BackEnd/HpcOmScheduler.mo @@ -42,22 +42,24 @@ public import HpcOmSimCode; public import SimCode; public import SimCodeVar; -protected import Absyn; -protected import Array; -protected import BackendDAEUtil; -protected import BackendVarTransform; -protected import ComponentReference; -protected import DAE; -protected import Debug; -protected import Error; -protected import Expression; -protected import Flags; -protected import HpcOmSchedulerExt; -protected import HpcOmSimCodeMain; -protected import List; -protected import SimCodeUtil; -protected import System; -protected import Util; +protected +import Absyn; +import Array; +import BackendDAEUtil; +import BackendVarTransform; +import ComponentReference; +import DAE; +import Debug; +import Error; +import Expression; +import Flags; +import HpcOmSchedulerExt; +import HpcOmSimCodeMain; +import List; +import SimCodeUtil; +import SimCodeFunctionUtil; +import System; +import Util; public type TaskAssignment = array; //the information which node is assigned to which processor @@ -3296,7 +3298,7 @@ algorithm threadIdx = 1; compIdx = arrayLength(iSccSimEqMapping)+1; // the next available component index taskIdx = arrayLength(iTaskGraph)+1; - simVarIdx = List.fold(List.map(algVars,SimCodeUtil.varIndex),intMax,0)+1;// the next available simVar index + simVarIdx = List.fold(List.map(algVars,SimCodeFunctionUtil.varIndex),intMax,0)+1;// the next available simVar index simEqSysIdx = SimCodeUtil.getMaxSimEqSystemIndex(iSimCode)+1;// the next available simEqSys index lsIdx = List.fold(List.map(List.flatten(odes),SimCodeUtil.getLSindex),intMax,0)+1;// the next available linear system index nlsIdx = List.fold(List.map(List.flatten(odes),SimCodeUtil.getNLSindex),intMax,0)+1;// the next available nonlinear system index @@ -3993,7 +3995,7 @@ algorithm crefLst := List.map1(simEqSysIdcs,SimCodeUtil.getAssignedCrefsOfSimEq,simCodeIn); crefs := List.flatten(crefLst); //print("crefs :\n"+stringDelimitList(List.map(crefs,ComponentReference.debugPrintComponentRefTypeStr),"\n")+"\n"); - simVarLst := List.map1(crefs,SimCodeUtil.get,ht); + simVarLst := List.map1(crefs,SimCodeFunctionUtil.get,ht); // build the new crefs, new simVars numVars := listLength(simVarLst); @@ -6502,7 +6504,7 @@ end revertTaskList; //---------------- protected function setScheduleLockIds "Function creates unique Ids for every tuple of out and ingoing locks - author: mhartung" + author: mhartung" input HpcOmSimCode.Schedule iSchedule; output HpcOmSimCode.Schedule oSchedule; protected @@ -6572,7 +6574,7 @@ algorithm end replaceDepTasksInListByLockIds; -protected function findTaskWithLockId "Function returns a DepTask with the id regarding lockIds or the identity of the given task" +protected function findTaskWithLockId "Function returns a DepTask with the id regarding lockIds or the identity of the given task" input array>> lockIds; input HpcOmSimCode.Task iTask; output HpcOmSimCode.Task oTask; @@ -6708,4 +6710,4 @@ end intListListString; annotation(__OpenModelica_Interface="backend"); -end HpcOmScheduler; \ No newline at end of file +end HpcOmScheduler; diff --git a/Compiler/BackEnd/Initialization.mo b/Compiler/BackEnd/Initialization.mo index 224311d19f2..1d5ad454c68 100644 --- a/Compiler/BackEnd/Initialization.mo +++ b/Compiler/BackEnd/Initialization.mo @@ -66,8 +66,8 @@ protected import ExpressionSimplify; protected import Flags; protected import List; protected import Matching; -protected import SimCodeUtil; protected import Sorting; +protected import SimCodeFunctionUtil; // ============================================================================= // section for all public functions @@ -172,7 +172,7 @@ algorithm // generate initial system and pre-balance it initsyst := BackendDAEUtil.createEqSystem(vars, eqns); (initsyst, dumpVars) := preBalanceInitialSystem(initsyst); - SimCodeUtil.execStat("created initial system"); + SimCodeFunctionUtil.execStat("created initial system"); // split the initial system into independend subsystems initdae := BackendDAE.DAE({initsyst}, shared); @@ -183,7 +183,7 @@ algorithm (systs, shared) := BackendDAEOptimize.partitionIndependentBlocksHelper(initsyst, shared, Error.getNumErrorMessages(), true); initdae := BackendDAE.DAE(systs, shared); - SimCodeUtil.execStat("partitioned initial system"); + SimCodeFunctionUtil.execStat("partitioned initial system"); if Flags.isSet(Flags.OPT_DAE_DUMP) then print(stringAppendList({"\npartitioned initial system:\n\n"})); diff --git a/Compiler/BackEnd/SymbolicJacobian.mo b/Compiler/BackEnd/SymbolicJacobian.mo index b68d0cdf175..bf0c9b01301 100644 --- a/Compiler/BackEnd/SymbolicJacobian.mo +++ b/Compiler/BackEnd/SymbolicJacobian.mo @@ -70,7 +70,7 @@ protected import Graph; protected import HashSet; protected import IndexReduction; protected import List; -protected import SimCodeUtil; +protected import SimCodeFunctionUtil; protected import System; protected import Util; protected import Values; @@ -1699,14 +1699,14 @@ algorithm seedlst = List.map1(comref_vars, createSeedVars, inName); s1 = intString(listLength(inVars)); - //SimCodeUtil.execStat("analytical Jacobians -> starting to generate the jacobian. DiffVars:" + s + " diffed equations: " + s1); + //SimCodeFunctionUtil.execStat("analytical Jacobians -> starting to generate the jacobian. DiffVars:" + s + " diffed equations: " + s1); // Differentiate the ODE system w.r.t states for jacobian (backendDAE as BackendDAE.DAE(shared=shared), funcs) = generateSymbolicJacobian(reduceDAE, inDiffVars, inDifferentiatedVars, BackendVariable.listVar1(seedlst), inStateVars, inInputVars, inParameterVars, inName); if Flags.isSet(Flags.JAC_DUMP2) then print("analytical Jacobians -> generated equations for Jacobian " + inName + " time: " + realString(clock()) + "\n"); end if; - //SimCodeUtil.execStat("analytical Jacobians -> generated jacobian equations"); + //SimCodeFunctionUtil.execStat("analytical Jacobians -> generated jacobian equations"); knvars1 = BackendVariable.daeKnVars(shared); knvarsTmp = BackendVariable.varList(knvars1); @@ -1730,11 +1730,11 @@ algorithm end if; knvars = BackendVariable.listVar1(knvarsTmp); backendDAE = BackendDAEUtil.setKnownVars(backendDAE, knvars); - SimCodeUtil.execStat("analytical Jacobians -> generated optimized jacobians"); + SimCodeFunctionUtil.execStat("analytical Jacobians -> generated optimized jacobians"); // generate sparse pattern (sparsepattern,colsColors) = generateSparsePattern(reduceDAE, inDiffVars, diffedVars); - //SimCodeUtil.execStat("analytical Jacobians -> generated generateSparsePattern"); + //SimCodeFunctionUtil.execStat("analytical Jacobians -> generated generateSparsePattern"); then ((backendDAE, inName, inDiffVars, diffedVars, inVars), sparsepattern, colsColors, funcs); else diff --git a/Compiler/FrontEnd/DAEUtil.mo b/Compiler/FrontEnd/DAEUtil.mo index 63d340601c1..88795c95ba2 100644 --- a/Compiler/FrontEnd/DAEUtil.mo +++ b/Compiler/FrontEnd/DAEUtil.mo @@ -4190,6 +4190,34 @@ protected uniontype TraverseStatementsOptions end TRAVERSE_RHS_ONLY; end TraverseStatementsOptions; +public function traverseAlgorithmExps " + This function goes through the Algorithm structure and finds all the + expressions and performs the function on them +" + replaceable type Type_a subtypeof Any; + input DAE.Algorithm inAlgorithm; + input FuncExpType func; + input Type_a inTypeA; + output Type_a outTypeA; + partial function FuncExpType + input DAE.Exp inExp; + input Type_a inTypeA; + output DAE.Exp outExp; + output Type_a outA; + end FuncExpType; +algorithm + outTypeA := match (inAlgorithm,func,inTypeA) + local + list stmts; + Type_a ext_arg_1; + case (DAE.ALGORITHM_STMTS(statementLst = stmts),_,_) + equation + (_,ext_arg_1) = DAEUtil.traverseDAEEquationsStmts(stmts,func,inTypeA); + then + ext_arg_1; + end match; +end traverseAlgorithmExps; + public function traverseDAEEquationsStmts "Traversing of DAE.Statement." input list inStmts; input FuncExpType func; diff --git a/Compiler/FrontEnd/InstUtil.mo b/Compiler/FrontEnd/InstUtil.mo index 25c7b3ae264..5b28af633a9 100644 --- a/Compiler/FrontEnd/InstUtil.mo +++ b/Compiler/FrontEnd/InstUtil.mo @@ -8526,8 +8526,6 @@ algorithm ((_,b,unbound)) = List.fold1(stmts, checkFunctionDefUseStmt, true, (false,false,unbound)); then ((b,b,unbound)); case (DAE.STMT_ASSERT(cond=DAE.BCONST(false),source=source),_,(_,_,_)) // TODO: Re-write these earlier from assert(false,msg) to terminate(msg) - equation - _ = DAEUtil.getElementSourceFileInfo(source); then ((true,true,{})); case (DAE.STMT_ASSERT(cond=exp1,msg=exp2,source=source),_,(_,_,unbound)) equation @@ -8540,6 +8538,8 @@ algorithm info = DAEUtil.getElementSourceFileInfo(source); (_,(unbound,_)) = Expression.traverseExpTopDown(exp,findUnboundVariableUse,(unbound,info)); then ((true,true,unbound)); + case (DAE.STMT_NORETCALL(exp=DAE.CALL(path=Absyn.IDENT("fail"),expLst={}),source=source),_,(_,_,unbound)) + then ((true,true,{})); case (DAE.STMT_NORETCALL(exp=exp,source=source),_,(_,_,unbound)) equation info = DAEUtil.getElementSourceFileInfo(source); diff --git a/Compiler/Main/Main.mo b/Compiler/Main/Main.mo index 4ef50b615e4..05e442a07a6 100644 --- a/Compiler/Main/Main.mo +++ b/Compiler/Main/Main.mo @@ -47,14 +47,12 @@ import BackendDAE; import BackendDAECreate; import BackendDAEUtil; import CevalScript; -import ClassLoader; import ClockIndexes; import Config; import Corba; import DAE; import DAEDump; import DAEUtil; -//import Database; import Debug; import Dump; import DumpGraphviz; @@ -75,6 +73,7 @@ import Print; import Settings; import SimCode; import SimCodeMain; +import SimCodeFunctionUtil; import SimCodeUtil; import Socket; import System; @@ -482,7 +481,7 @@ algorithm DumpGraphviz.dump(p); end if; - SimCodeUtil.execStat("Parsed file"); + SimCodeFunctionUtil.execStat("Parsed file"); // Instantiate the program. (cache, env, d, cname) = instantiate(p); @@ -492,14 +491,14 @@ algorithm funcs = FCore.getFunctionTree(cache); Print.clearBuf(); - SimCodeUtil.execStat("Transformations before Dump"); + SimCodeFunctionUtil.execStat("Transformations before Dump"); s = DAEDump.dumpStr(d, funcs); - SimCodeUtil.execStat("DAEDump done"); + SimCodeFunctionUtil.execStat("DAEDump done"); Print.printBuf(s); if Flags.isSet(Flags.DAE_DUMP_GRAPHV) then DAEDump.dumpGraphviz(d); end if; - SimCodeUtil.execStat("Misc Dump"); + SimCodeFunctionUtil.execStat("Misc Dump"); // Do any transformations required before going into code generation, e.g. if-equations to expressions. d = if boolNot(Flags.isSet(Flags.TRANSFORMS_BEFORE_DUMP)) then DAEUtil.transformationsBeforeBackend(cache,env,d) else d; @@ -507,7 +506,7 @@ algorithm if not Config.silent() then print(Print.getString()); end if; - SimCodeUtil.execStat("Transformations before backend"); + SimCodeFunctionUtil.execStat("Transformations before backend"); // Run the backend. optimizeDae(cache, env, d, p, cname); @@ -627,7 +626,7 @@ algorithm System.realtimeTock(ClockIndexes.RT_CLOCK_BACKEND); // Is this necessary? SimCodeMain.generateModelCode(inBackendDAE, inProgram, inDAE, inClassName, cname, SOME(sim_settings), Absyn.FUNCTIONARGS({}, {})); - SimCodeUtil.execStat("Codegen Done"); + SimCodeFunctionUtil.execStat("Codegen Done"); end if; end simcodegen; diff --git a/Compiler/Script/CevalScript.mo b/Compiler/Script/CevalScript.mo index 54c688f9de0..259099e48a1 100644 --- a/Compiler/Script/CevalScript.mo +++ b/Compiler/Script/CevalScript.mo @@ -119,6 +119,7 @@ import NFInst; import NFSCodeEnv; import NFSCodeFlatten; import SimCodeMain; +import SimCodeFunction; import System; import Static; import StaticScript; @@ -5213,7 +5214,7 @@ algorithm funcs := FCore.getFunctionTree(cache); // First check if the main function exists... If it does not it might be an interactive function... mainFunction := DAEUtil.getNamedFunction(functionName, funcs); - dependencies := SimCodeMain.getCalledFunctionsInFunction(functionName,funcs); + dependencies := SimCodeFunction.getCalledFunctionsInFunction(functionName,funcs); end getFunctionDependencies; public function collectDependencies @@ -5266,7 +5267,7 @@ algorithm pathstr = generateFunctionName(path); fileName = generateFunctionFileName(path); - SimCodeMain.translateFunctions(program, fileName, SOME(mainFunction), d, metarecordTypes, {}); + SimCodeFunction.translateFunctions(program, fileName, SOME(mainFunction), d, metarecordTypes, {}); compileModel(fileName, {}); then (cache, pathstr, fileName); @@ -5286,7 +5287,7 @@ algorithm fileName = generateFunctionFileName(path); // The list of functions is not ordered, so we need to filter out the main function... d = DAEUtil.getFunctionList(funcs); - SimCodeMain.translateFunctions(program, fileName, NONE(), d, {}, {}); + SimCodeFunction.translateFunctions(program, fileName, NONE(), d, {}, {}); then (cache, pathstr, fileName); @@ -5385,7 +5386,7 @@ algorithm System.writeFile(name + ".deps", "$(GEN_DIR)" + name + ".o: $(GEN_DIR)" + name + ".c" + " " + stringDelimitList(strs," ")); dependencies = List.map1(dependencies,stringAppend,"\""); dependencies = List.map1r(dependencies,stringAppend,"#include \""); - SimCodeMain.translateFunctions(p, name, NONE(), d, {}, dependencies); + SimCodeFunction.translateFunctions(p, name, NONE(), d, {}, dependencies); str = Tpl.tplString(Unparsing.programExternalHeader, {cl}); System.writeFile(name + "_records.c","#include \n" + str); cache = if cleanCache then icache else cache; @@ -7782,8 +7783,8 @@ protected function writeModuleDepends algorithm str := matchcontinue (cl,prefix,suffix,deps) local - String name,fileName; - list allDepends,protectedDepends; + String name,fileName,tmp1; + list allDepends,protectedDepends,tmp2; list elts; SourceInfo info; case (SCode.CLASS(name=name, classDef=SCode.PARTS(elementLst=elts), info = SOURCEINFO()),_,_,_) @@ -7795,6 +7796,27 @@ algorithm allDepends = List.map1(allDepends, stringAppend, ".interface.mo"); str = prefix + name + suffix + ": $(RELPATH_" + name + ") " + stringDelimitList(allDepends," "); then str; + case (SCode.CLASS(name=name, classDef=SCode.PARTS(elementLst=elts), info=info),_,_,_) + algorithm + protectedDepends := List.map(List.select(elts,SCode.elementIsProtectedImport),importDepenency); + protectedDepends := List.select(protectedDepends, isNotBuiltinImport); + allDepends := list(Util.tuple21(e) for e in deps); + for d in protectedDepends loop + if not listMember(d, allDepends) then + Error.addSourceMessage(Error.GENERATE_SEPARATE_CODE_DEPENDENCIES_FAILED_UNKNOWN_PACKAGE, {name,name,d}, info); + fail(); + end if; + end for; + for dep in deps loop + (tmp1,tmp2) := dep; + for d in tmp2 loop + if not listMember(d, allDepends) then + Error.addSourceMessage(Error.GENERATE_SEPARATE_CODE_DEPENDENCIES_FAILED_UNKNOWN_PACKAGE, {name,tmp1,d}, info); + fail(); + end if; + end for; + end for; + then fail(); case (SCode.CLASS(name=name,info=info),_,_,_) equation Error.addSourceMessage(Error.GENERATE_SEPARATE_CODE_DEPENDENCIES_FAILED, {name}, info); diff --git a/Compiler/SimCode/HpcOmSimCodeMain.mo b/Compiler/SimCode/HpcOmSimCodeMain.mo index 373a8313466..507984100e4 100644 --- a/Compiler/SimCode/HpcOmSimCodeMain.mo +++ b/Compiler/SimCode/HpcOmSimCodeMain.mo @@ -60,6 +60,7 @@ protected import HpcOmScheduler; protected import Initialization; protected import List; protected import SimCodeUtil; +protected import SimCodeFunctionUtil; protected import System; protected import Util; @@ -224,7 +225,7 @@ algorithm //dumpSimEqSCCMapping(simeqCompMapping); //dumpSccSimEqMapping(sccSimEqMapping); - SimCodeUtil.execStat("hpcom setup"); + SimCodeFunctionUtil.execStat("hpcom setup"); //Get complete DAE System //----------------------- @@ -241,7 +242,7 @@ algorithm daeSccSimEqMapping = arrayAppend(sccSimEqMapping,daeSccSimEqMapping); schedulerInfo = arrayCreate(arrayLength(taskGraphDae), (-1,-1,-1.0)); HpcOmTaskGraph.dumpAsGraphMLSccLevel(taskGraphDae, taskGraphDataDae,inBackendDAE, fileName, "", {}, {}, daeSccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(false,false,true,true)); - SimCodeUtil.execStat("hpcom create DAE TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom create DAE TaskGraph"); //print("DAE\n"); //HpcOmTaskGraph.printTaskGraph(taskGraphDae); @@ -257,7 +258,7 @@ algorithm fileName = ("taskGraph"+filenamePrefix+"_event.graphml"); schedulerInfo = arrayCreate(arrayLength(taskGraphEvent), (-1,-1,-1.0)); HpcOmTaskGraph.dumpAsGraphMLSccLevel(taskGraphEvent, taskGraphDataEvent,inBackendDAE, fileName, "", {}, {}, sccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(false,false,true,true)); - SimCodeUtil.execStat("hpcom create and dump event TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom create and dump event TaskGraph"); HpcOmSimCode.TASKDEPSCHEDULE(tasks=eventSystemTasks) = HpcOmScheduler.createTaskDepSchedule(taskGraphEvent, taskGraphDataEvent, sccSimEqMapping); _ = List.map(eventSystemTasks, Util.tuple21); @@ -269,7 +270,7 @@ algorithm //------------ taskGraphDataDae = HpcOmTaskGraph.estimateCosts(inBackendDAE,taskGraphDataDae); taskGraphData = HpcOmTaskGraph.createCosts(inBackendDAE, filenamePrefix + "_eqs_prof" , simeqCompMapping, taskGraphData); - SimCodeUtil.execStat("hpcom create costs"); + SimCodeFunctionUtil.execStat("hpcom create costs"); //print cost estimation infos //outputTimeBenchmark(taskGraphData,inBackendDAE); @@ -278,12 +279,12 @@ algorithm taskGraphOde = arrayCopy(taskGraph); taskGraphDataOde = HpcOmTaskGraph.copyTaskGraphMeta(taskGraphData); (taskGraphOde,taskGraphDataOde) = HpcOmTaskGraph.getOdeSystem(taskGraphOde,taskGraphDataOde,inBackendDAE); - SimCodeUtil.execStat("hpcom create ODE TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom create ODE TaskGraph"); taskGraphMetaValid = HpcOmTaskGraph.validateTaskGraphMeta(taskGraphDataOde, inBackendDAE); taskGraphMetaMessage = if taskGraphMetaValid then "TaskgraphMeta valid\n" else "TaskgraphMeta invalid\n"; print(taskGraphMetaMessage); - SimCodeUtil.execStat("hpcom validate TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom validate TaskGraph"); //print("ODE Task Graph Informations\n"); //HpcOmTaskGraph.printTaskGraph(taskGraphOde); @@ -297,7 +298,7 @@ algorithm fileName = ("taskGraph"+filenamePrefix+".graphml"); schedulerInfo = arrayCreate(arrayLength(taskGraph), (-1,-1,-1.0)); HpcOmTaskGraph.dumpAsGraphMLSccLevel(taskGraph, taskGraphData, inBackendDAE, fileName, "", {}, {}, sccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(false,false,true,true)); - SimCodeUtil.execStat("hpcom dump DAE TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom dump DAE TaskGraph"); //Get critical path //---------------------------------- @@ -308,9 +309,9 @@ algorithm criticalPathInfo = criticalPathInfo + " sum: (" + realString(graphCosts) + " ; " + intString(graphOps) + ")"; fileName = ("taskGraph"+filenamePrefix+"ODE.graphml"); schedulerInfo = arrayCreate(arrayLength(taskGraphOde), (-1,-1,-1.0)); - SimCodeUtil.execStat("hpcom assign levels / get crit. path"); + SimCodeFunctionUtil.execStat("hpcom assign levels / get crit. path"); HpcOmTaskGraph.dumpAsGraphMLSccLevel(taskGraphOde, taskGraphDataOde,inBackendDAE, fileName, criticalPathInfo, HpcOmTaskGraph.convertNodeListToEdgeTuples(listHead(criticalPaths)), HpcOmTaskGraph.convertNodeListToEdgeTuples(listHead(criticalPathsWoC)), sccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(true,false,true,true)); - SimCodeUtil.execStat("hpcom dump ODE TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom dump ODE TaskGraph"); if Flags.isSet(Flags.HPCOM_DUMP) then print("Critical Path successfully calculated\n"); @@ -325,11 +326,11 @@ algorithm //------------- (taskGraphDaeSimplified,taskGraphDataDaeSimplified) = (taskGraphDae,taskGraphDataDae); (taskGraphOdeSimplified,taskGraphDataOdeSimplified) = applyGRS(taskGraphOde,taskGraphDataOde, sccSimEqMapping, inBackendDAE); - SimCodeUtil.execStat("hpcom GRS"); + SimCodeFunctionUtil.execStat("hpcom GRS"); fileName = ("taskGraph"+filenamePrefix+"ODE_merged.graphml"); HpcOmTaskGraph.dumpAsGraphMLSccLevel(taskGraphOdeSimplified, taskGraphDataOdeSimplified, inBackendDAE, fileName, criticalPathInfo, HpcOmTaskGraph.convertNodeListToEdgeTuples(listHead(criticalPaths)), HpcOmTaskGraph.convertNodeListToEdgeTuples(listHead(criticalPathsWoC)), sccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(true,false,true,true)); - SimCodeUtil.execStat("hpcom dump simplified TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom dump simplified TaskGraph"); if Flags.isSet(Flags.HPCOM_DUMP) then print("Filter successfully applied. Merged "+intString(intSub(arrayLength(taskGraphOde),arrayLength(taskGraphOdeSimplified)))+" tasks.\n"); @@ -354,13 +355,13 @@ algorithm numProc = Flags.getConfigInt(Flags.NUM_PROC); criticalPathInfo = HpcOmScheduler.analyseScheduledTaskGraph(scheduleOde,numProc,taskGraphOdeScheduled,taskGraphDataOdeScheduled,"ODE system"); schedulerInfo = HpcOmScheduler.convertScheduleStrucToInfo(scheduleOde,arrayLength(taskGraphOdeScheduled)); - SimCodeUtil.execStat("hpcom create schedule"); + SimCodeFunctionUtil.execStat("hpcom create schedule"); fileName = ("taskGraph"+filenamePrefix+"ODE_schedule.graphml"); HpcOmTaskGraph.dumpAsGraphMLSccLevel(taskGraphOdeScheduled, taskGraphDataOdeScheduled, inBackendDAE, fileName, criticalPathInfo, HpcOmTaskGraph.convertNodeListToEdgeTuples(listHead(criticalPaths)), HpcOmTaskGraph.convertNodeListToEdgeTuples(listHead(criticalPathsWoC)), sccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(true,false,true,true)); //HpcOmScheduler.printSchedule(scheduleOde); - SimCodeUtil.execStat("hpcom dump schedule TaskGraph"); + SimCodeFunctionUtil.execStat("hpcom dump schedule TaskGraph"); if Flags.isSet(Flags.HPCOM_DUMP) then print("Schedule created\n"); @@ -372,14 +373,14 @@ algorithm //HpcOmTaskGraph.printTaskGraphMeta(taskGraphDataScheduled); checkOdeSystemSize(taskGraphDataOdeScheduled,odeEquations); - SimCodeUtil.execStat("hpcom check ODE system size"); + SimCodeFunctionUtil.execStat("hpcom check ODE system size"); //Create Memory-Map and Sim-Code //------------------------------ (optTmpMemoryMap, varToArrayIndexMapping, varToIndexMapping) = HpcOmMemory.createMemoryMap(modelInfo, varToArrayIndexMapping, varToIndexMapping, taskGraphOdeSimplified, BackendDAEUtil.transposeMatrix(taskGraphOdeSimplified,arrayLength(taskGraphOdeSimplified)), taskGraphDataOdeSimplified, eqs, filenamePrefix, schedulerInfo, scheduleOde, sccSimEqMapping, criticalPaths, criticalPathsWoC, criticalPathInfo, numProc, allComps); //BaseHashTable.dumpHashTable(varToArrayIndexMapping); - SimCodeUtil.execStat("hpcom create memory map"); + SimCodeFunctionUtil.execStat("hpcom create memory map"); hpcomData = HpcOmSimCode.HPCOMDATA(SOME((scheduleOde, scheduleDae)), optTmpMemoryMap); simCode = SimCode.SIMCODE( modelInfo, simCodeLiterals, simCodeRecordDecls, simCodeExternalFunctionIncludes, allEquations, odeEquations, algebraicEquations, @@ -391,7 +392,7 @@ algorithm //print("Number of literals post: " + intString(listLength(simCodeLiterals)) + "\n"); - SimCodeUtil.execStat("hpcom other"); + SimCodeFunctionUtil.execStat("hpcom other"); print("HpcOm is still under construction.\n"); then simCode; else equation diff --git a/Compiler/SimCode/SerializeModelInfo.mo b/Compiler/SimCode/SerializeModelInfo.mo index c38100be93b..a2273cf630a 100644 --- a/Compiler/SimCode/SerializeModelInfo.mo +++ b/Compiler/SimCode/SerializeModelInfo.mo @@ -54,6 +54,7 @@ import crefStr = ComponentReference.printComponentRefStrFixDollarDer; import expStr = ExpressionDump.printExpStr; import List; import SimCodeUtil; +import SimCodeFunctionUtil; import SCodeDump; import Util; @@ -778,7 +779,7 @@ algorithm File.write(file, ",\"section\":\""); File.write(file, section); File.write(file, "\",\"tag\":\"container\",\"display\":\"mixed\",\"defines\":["); - serializeUses(file,list(SimCodeUtil.varName(v) for v in eq.discVars)); + serializeUses(file,list(SimCodeFunctionUtil.varName(v) for v in eq.discVars)); File.write(file, "],\"equation\":["); serializeEquationIndex(file,eq.cont); list(match () case () equation File.write(file,","); serializeEquationIndex(file,e); then (); end match for e in eq.discEqs); diff --git a/Compiler/SimCode/SimCodeFunction.mo b/Compiler/SimCode/SimCodeFunction.mo new file mode 100644 index 00000000000..136ecc9dd7a --- /dev/null +++ b/Compiler/SimCode/SimCodeFunction.mo @@ -0,0 +1,182 @@ +/* + * This file is part of OpenModelica. + * + * Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), + * c/o Linköpings universitet, Department of Computer and Information Science, + * SE-58183 Linköping, Sweden. + * + * All rights reserved. + * + * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR + * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. + * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES + * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, + * ACCORDING TO RECIPIENTS CHOICE. + * + * The OpenModelica software and the Open Source Modelica + * Consortium (OSMC) Public License (OSMC-PL) are obtained + * from OSMC, either from the above address, + * from the URLs: http://www.ida.liu.se/projects/OpenModelica or + * http://www.openmodelica.org, and in the OpenModelica distribution. + * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. + * + * This program is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH + * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. + * + * See the full OSMC Public License conditions for more details. + * + */ + +encapsulated package SimCodeFunction +"The entry points to this module is the translateFunctions fuction." + +// public imports +public +import Absyn; +import DAE; +import HashTableStringToPath; +import Tpl; +import SimCode; + +// protected imports +protected +import BaseHashTable; +import CodegenC; +import SimCodeFunctionUtil; + +public function translateFunctions " + Entry point to translate Modelica/MetaModelica functions to C functions. + Called from other places in the compiler." + input Absyn.Program program; + input String name; + input Option optMainFunction; + input list idaeElements; + input list metarecordTypes; + input list inIncludes; +algorithm + _ := match (program, name, optMainFunction, idaeElements, metarecordTypes, inIncludes) + local + DAE.Function daeMainFunction; + SimCode.Function mainFunction; + list fns; + list includes, libs, libPaths,includeDirs; + SimCode.MakefileParams makefileParams; + SimCode.FunctionCode fnCode; + list extraRecordDecls; + list literals; + list daeElements; + + case (_, _, SOME(daeMainFunction), daeElements, _, includes) + equation + // Create SimCode.FunctionCode + (daeElements,literals) = SimCodeFunctionUtil.findLiterals(daeMainFunction::daeElements); + (mainFunction::fns, extraRecordDecls, includes, includeDirs, libs,libPaths) = SimCodeFunctionUtil.elaborateFunctions(program, daeElements, metarecordTypes, literals, includes); + SimCodeFunctionUtil.checkValidMainFunction(name, mainFunction); + makefileParams = SimCodeFunctionUtil.createMakefileParams(includeDirs, libs,libPaths, true); + fnCode = SimCode.FUNCTIONCODE(name, SOME(mainFunction), fns, literals, includes, makefileParams, extraRecordDecls); + // Generate code + _ = Tpl.tplString(CodegenC.translateFunctions, fnCode); + then + (); + case (_, _, NONE(), daeElements, _, includes) + equation + // Create SimCode.FunctionCode + (daeElements,literals) = SimCodeFunctionUtil.findLiterals(daeElements); + (fns, extraRecordDecls, includes, includeDirs, libs,libPaths) = SimCodeFunctionUtil.elaborateFunctions(program, daeElements, metarecordTypes, literals, includes); + makefileParams = SimCodeFunctionUtil.createMakefileParams(includeDirs, libs,libPaths, true); + // remove OpenModelica.threadData.ThreadData + fns = removeThreadDataFunction(fns, {}); + extraRecordDecls = removeThreadDataRecord(extraRecordDecls, {}); + + fnCode = SimCode.FUNCTIONCODE(name, NONE(), fns, literals, includes, makefileParams, extraRecordDecls); + // Generate code + _ = Tpl.tplString(CodegenC.translateFunctions, fnCode); + then + (); + end match; +end translateFunctions; + +protected function removeThreadDataRecord +"remove OpenModelica.threadData.ThreadData + as is already defined in openmodelica.h" + input list inRecs; + input list inAcc; + output list outRecs; +algorithm + outRecs := match(inRecs, inAcc) + local + Absyn.Path p; + list acc, rest; + SimCode.RecordDeclaration r; + + case ({}, _) then listReverse(inAcc); + + case (SimCode.RECORD_DECL_FULL(name = "OpenModelica_threadData_ThreadData")::rest, _) + equation + acc = removeThreadDataRecord(rest, inAcc); + then + acc; + + case (SimCode.RECORD_DECL_DEF(path = Absyn.QUALIFIED("OpenModelica",Absyn.QUALIFIED("threadData",Absyn.IDENT("ThreadData"))))::rest, _) + equation + acc = removeThreadDataRecord(rest, inAcc); + then + acc; + + case (r::rest, _) + equation + acc = removeThreadDataRecord(rest, r::inAcc); + then + acc; + + end match; +end removeThreadDataRecord; + +protected function removeThreadDataFunction +"remove OpenModelica.threadData.ThreadData + as is already defined in openmodelica.h" + input list inFuncs; + input list inAcc; + output list outFuncs; +algorithm + outFuncs := match(inFuncs, inAcc) + local + Absyn.Path p; + list acc, rest; + SimCode.Function f; + + case ({}, _) then listReverse(inAcc); + + case (SimCode.RECORD_CONSTRUCTOR(name = Absyn.FULLYQUALIFIED(Absyn.QUALIFIED("OpenModelica",Absyn.QUALIFIED("threadData",Absyn.IDENT("ThreadData")))))::rest, _) + equation + acc = removeThreadDataFunction(rest, inAcc); + then + acc; + + case (f::rest, _) + equation + acc = removeThreadDataFunction(rest, f::inAcc); + then + acc; + + end match; +end removeThreadDataFunction; + +public function getCalledFunctionsInFunction +"Goes through the given DAE, finds the given function and collects + the names of the functions called from within those functions" + input Absyn.Path path; + input DAE.FunctionTree funcs; + output list outPaths; +protected + HashTableStringToPath.HashTable ht; +algorithm + ht := HashTableStringToPath.emptyHashTable(); + ht := SimCodeFunctionUtil.getCalledFunctionsInFunction2(path,Absyn.pathStringNoQual(path),ht,funcs); + outPaths := BaseHashTable.hashTableValueList(ht); +end getCalledFunctionsInFunction; + +annotation(__OpenModelica_Interface="backend"); +end SimCodeFunction; diff --git a/Compiler/SimCode/SimCodeFunctionUtil.mo b/Compiler/SimCode/SimCodeFunctionUtil.mo new file mode 100644 index 00000000000..d0aad49d880 --- /dev/null +++ b/Compiler/SimCode/SimCodeFunctionUtil.mo @@ -0,0 +1,2890 @@ +/* + * This file is part of OpenModelica. + * + * Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC), + * c/o Linköpings universitet, Department of Computer and Information Science, + * SE-58183 Linköping, Sweden. + * + * All rights reserved. + * + * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR + * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. + * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES + * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, + * ACCORDING TO RECIPIENTS CHOICE. + * + * The OpenModelica software and the Open Source Modelica + * Consortium (OSMC) Public License (OSMC-PL) are obtained + * from OSMC, either from the above address, + * from the URLs: http://www.ida.liu.se/projects/OpenModelica or + * http://www.openmodelica.org, and in the OpenModelica distribution. + * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. + * + * This program is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH + * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. + * + * See the full OSMC Public License conditions for more details. + * + */ + +encapsulated package SimCodeFunctionUtil "SimCode functions not related to equation systems" + +import DAE; +import HashTableExpToIndex; +import SimCode; + +protected + +import Array; +import BaseHashTable; +import CevalScript; +import ClockIndexes; +import ComponentReference; +import DAEDump; +import DAEUtil; +import Debug; +import Error; +import Expression; +import ExpressionSimplify; +import ExpressionDump; +import Flags; +import GC; +import Graph; +import List; +import Mod; +import SCode; + +public + +public function elementVars +"Used by templates to get a list of variables from a valueblock." + input list ild; + output list vars; +protected + list ld; +algorithm + ld := List.filter(ild, isVarQ); + vars := List.map(ld, daeInOutSimVar); +end elementVars; + +public function crefSubIsScalar +"Used by templates to determine if a component reference's subscripts are + scalar." + input DAE.ComponentRef cref; + output Boolean isScalar; +protected + list subs; +algorithm + subs := ComponentReference.crefSubs(cref); + isScalar := subsToScalar(subs); +end crefSubIsScalar; + +protected function subsToScalar "scalar expression." + input list inExpSubscriptLst; + output Boolean outBoolean; +algorithm + outBoolean := match (inExpSubscriptLst) + local + Boolean b; + list r; + case {} then true; + case (DAE.SLICE() :: _) then false; + case (DAE.WHOLEDIM() :: _) then false; + case (DAE.INDEX() :: r) + equation + b = subsToScalar(r); + then + b; + end match; +end subsToScalar; + +public function crefNoSub +"Used by templates to determine if a component reference has no subscripts." + input DAE.ComponentRef cref; + output Boolean noSub; +algorithm + noSub := not ComponentReference.crefHaveSubs(cref); +end crefNoSub; + +public function inFunctionContext + input SimCode.Context inContext; + output Boolean outInFunction; +algorithm + outInFunction := match inContext + case SimCode.FUNCTION_CONTEXT() then true; + case SimCode.PARALLEL_FUNCTION_CONTEXT() then true; + else false; + end match; +end inFunctionContext; + +public function crefIsScalar + "Whether a component reference is a scalar depends on what context we are in. + If we are generating code for a function, then only crefs without subscripts + are scalar. If we are generating code for simulation though, then crefs with + only constant subscripts are also scalars, since a variable is generated for + each element of an array in the model." + input DAE.ComponentRef cref; + input SimCode.Context context; + output Boolean isScalar; +algorithm + if inFunctionContext(context) then + isScalar := listEmpty(ComponentReference.crefLastSubs(cref)); + else + isScalar := ComponentReference.crefHasScalarSubscripts(cref); + end if; +end crefIsScalar; + +public function buildCrefExpFromAsub +"Used by templates to convert an ASUB expression to a component reference + with subscripts." + input DAE.Exp cref; + input list subs; + output DAE.Exp cRefOut; +algorithm + cRefOut := matchcontinue(cref, subs) + local + DAE.Exp crefExp; + DAE.Type ty; + DAE.ComponentRef crNew; + list indexes; + + case (_, {}) then cref; + case (DAE.CREF(componentRef=crNew, ty=ty), _) + equation + indexes = List.map(subs, Expression.makeIndexSubscript); + crNew = ComponentReference.subscriptCref(crNew, indexes); + crefExp = Expression.makeCrefExp(crNew, ty); + then + crefExp; + end matchcontinue; +end buildCrefExpFromAsub; + +public function incrementInt +"Used by templates to create new integers that are increments of another." + input Integer inInt; + input Integer increment; + output Integer outInt; +algorithm + outInt := inInt + increment; +end incrementInt; + +public function decrementInt +"Used by templates to create new integers that are increments of another." + input Integer inInt; + input Integer decrement; + output Integer outInt; +algorithm + outInt := inInt - decrement; +end decrementInt; + + +public function protectedVars + input list InSimVars; + output list OutSimVars; + algorithm + OutSimVars:= List.filterOnTrue(InSimVars,isNotProtected); +end protectedVars; + +protected function isNotProtected + input SimCodeVar.SimVar simVar; + output Boolean isProtected; +algorithm + SimCodeVar.SIMVAR(isProtected=isProtected) := simVar; + isProtected := not isProtected; +end isNotProtected; + + +public function makeCrefRecordExp +"Helper function to generate records." + input DAE.ComponentRef inCRefRecord; + input DAE.Var inVar; + output DAE.Exp outExp; +algorithm + outExp := match (inCRefRecord, inVar) + local + DAE.ComponentRef cr, cr1; + String name; + DAE.Type tp; + case (cr, DAE.TYPES_VAR(name=name, ty=tp)) + equation + cr1 = ComponentReference.crefPrependIdent(cr, name, {}, tp); + outExp = Expression.makeCrefExp(cr1, tp); + then + outExp; + end match; +end makeCrefRecordExp; + +public function cref2simvar +"Used by templates to find SIMVAR for given cref (to gain representaion index info mainly)." + input DAE.ComponentRef inCref; + input SimCode.SimCode simCode; + output SimCodeVar.SimVar outSimVar; +algorithm + outSimVar := matchcontinue(inCref, simCode) + local + DAE.ComponentRef cref, badcref; + SimCodeVar.SimVar sv; + SimCode.HashTableCrefToSimVar crefToSimVarHT; + String errstr; + + case (cref, SimCode.SIMCODE(crefToSimVarHT = crefToSimVarHT) ) + equation + sv = get(cref, crefToSimVarHT); + then sv; + + case (_, _) + equation + //print("cref2simvar: " + ComponentReference.printComponentRefStr(inCref) + " not found!\n"); + badcref = ComponentReference.makeCrefIdent("ERROR_cref2simvar_failed", DAE.T_REAL_DEFAULT, {}); + /* Todo: This also generates an error for example itearation variables, so i commented out + "Template did not find the simulation variable for "+ ComponentReference.printComponentRefStr(cref) + ". "; + Error.addInternalError(errstr, sourceInfo());*/ + then + SimCodeVar.SIMVAR(badcref, BackendDAE.VARIABLE(), "", "", "", -2, NONE(), NONE(), NONE(), NONE(), false, DAE.T_REAL_DEFAULT, false, NONE(), SimCodeVar.NOALIAS(), DAE.emptyElementSource, SimCodeVar.INTERNAL(), NONE(), {}, false, true); + end matchcontinue; +end cref2simvar; + +public function isModelTooBigForCSharpInOneFile +"Used by C# template to determine if the generated code should be split into several files + to make Visual Studio responsive when the file is opened (C# compiler is OK, + but VS does not scale well for big C# files)." + input SimCode.SimCode simCode; + output Boolean outIsTooBig; +algorithm + outIsTooBig := match(simCode) + local + Integer numAlgVars; + + case (SimCode.SIMCODE(modelInfo = SimCode.MODELINFO(varInfo = SimCode.VARINFO(numAlgVars = numAlgVars)))) + equation + outIsTooBig = numAlgVars > 1000; + then outIsTooBig; + + end match; +end isModelTooBigForCSharpInOneFile; + +public function derComponentRef +"Used by templates to derrive a cref in a der(cref) expression. + Particularly, this function is called for the C# code generator, + while for C/C++, it is solved by prefixing the cref with '$P$DER' in daeExpCall() template. + The prefixing technique is not usable for C#, because there is no macroprocessor in C#. + TODO: all der(cref) expressions should be eliminated before the expressions enter templates + to pull this logic (and this function) out of templates." + input DAE.ComponentRef inCref; + output DAE.ComponentRef derCref; +algorithm + derCref := ComponentReference.crefPrefixDer(inCref); +end derComponentRef; + +public function hackArrayReverseToCref +"This is a hack transformation of an expanded array back to its cref. +It is used in daeExpArray() (for C# yet) to optimize the generated code. +TODO: This function should not exist! +Rather the array should not be let expanded when SimCode is entering templates. +" + input DAE.Exp inExp; + input SimCode.Context context; + output DAE.Exp outExp; +algorithm + outExp := matchcontinue (inExp, context) + local + list aRest; + DAE.ComponentRef cr; + DAE.Type aty; + DAE.Exp crefExp; + + case(DAE.ARRAY(ty=aty, scalar=true, array =(DAE.CREF(componentRef=cr) ::aRest)), _) + equation + failure(SimCode.FUNCTION_CONTEXT()=context); // only in the function context + failure(SimCode.PARALLEL_FUNCTION_CONTEXT()=context); // only in the function context + { DAE.INDEX(DAE.ICONST(1)) } = ComponentReference.crefLastSubs(cr); + cr = ComponentReference.crefStripLastSubs(cr); + true = isArrayExpansion(aRest, cr, 2); + crefExp = Expression.makeCrefExp(cr, aty); + then + crefExp; + + else inExp; + + end matchcontinue; +end hackArrayReverseToCref; + +protected function isArrayExpansion +"Helper funtion to hackArrayReverseToCref." + input list inArrayElems; + input DAE.ComponentRef inCref; + input Integer index; + output Boolean isExpanded; +algorithm + isExpanded := matchcontinue(inArrayElems, inCref, index) + local + list aRest; + Integer i; + DAE.ComponentRef cr; + case({}, _, _) then true; + case (DAE.CREF(componentRef=cr) :: aRest, _, _) + equation + { DAE.INDEX(DAE.ICONST(i)) } = ComponentReference.crefLastSubs(cr); + true = (i == index); + cr = ComponentReference.crefStripLastSubs(cr); + true = ComponentReference.crefEqualNoStringCompare(inCref, cr); + then isArrayExpansion(aRest, inCref, index+1); + else false; + end matchcontinue; +end isArrayExpansion; + +public function hackMatrixReverseToCref +"This is a hack transformation of an expanded matrix back to its cref. +It is used in daeExpMatrix() (for C# yet) to optimize the generated code. +TODO: This function should not exist! +Rather the matrix should not be let expanded when SimCode is entering templates +" + input DAE.Exp inExp; + input SimCode.Context context; + output DAE.Exp outExp; +algorithm + outExp := matchcontinue (inExp, context) + local + DAE.ComponentRef cr; + DAE.Type aty; + list> rows; + DAE.Exp crefExp; + + case(DAE.MATRIX(ty=aty, matrix = rows as (((DAE.CREF(componentRef=cr))::_)::_) ), _) + equation + failure(SimCode.FUNCTION_CONTEXT()=context); + failure(SimCode.PARALLEL_FUNCTION_CONTEXT()=context); // only in the function context + { DAE.INDEX(DAE.ICONST(1)), DAE.INDEX(DAE.ICONST(1)) } = ComponentReference.crefLastSubs(cr); + cr = ComponentReference.crefStripLastSubs(cr); + true = isMatrixExpansion(rows, cr, 1, 1); + crefExp = Expression.makeCrefExp(cr, aty); + then + crefExp; + + else inExp; + + end matchcontinue; +end hackMatrixReverseToCref; + +protected function isMatrixExpansion +"Helper funtion to hackMatrixReverseToCref." + input list> rows; + input DAE.ComponentRef inCref; + input Integer rowIndex; + input Integer colIndex; + output Boolean isExpanded; +algorithm + isExpanded := matchcontinue(rows, inCref, rowIndex, colIndex) + local + list> restRows; + list restElems; + Integer r, c; + DAE.ComponentRef cr; + case({}, _, _, _) then true; + case({} :: restRows, _, _, _) then isMatrixExpansion(restRows, inCref, rowIndex+1, 1); + case ( (DAE.CREF(componentRef=cr) :: restElems) :: restRows, _, _, _) + equation + { DAE.INDEX(DAE.ICONST(r)), DAE.INDEX(DAE.ICONST(c)) } = ComponentReference.crefLastSubs(cr); + true = (r == rowIndex) and (c == colIndex); + cr = ComponentReference.crefStripLastSubs(cr); + true = ComponentReference.crefEqualNoStringCompare(inCref, cr); + then isMatrixExpansion(restElems :: restRows, inCref, rowIndex, colIndex+1); + else false; + end matchcontinue; +end isMatrixExpansion; + +public function hackGetFirstExternalFunctionLib +"This is a hack to get the original library name given to an external function. +TODO: redesign OMC and Modelica specification so they are not so C/C++ centric." + input list libs; + output String outFirstLib; +algorithm + outFirstLib := matchcontinue (libs) + local + String lib; + + case _ + equation + lib = List.last(libs); + lib = System.stringReplace(lib, "-l", ""); + then + lib; + + else "NO_LIB"; + + end matchcontinue; +end hackGetFirstExternalFunctionLib; + +public function createAssertforSqrt + input DAE.Exp inExp; + output DAE.Exp outExp; +algorithm + outExp := + match (inExp) + case(_) + equation + // Simplify things like abs(exp) >= 0 to exp + (outExp, _) = ExpressionSimplify.simplify(DAE.RELATION(inExp, DAE.GREATEREQ(DAE.T_REAL_DEFAULT), DAE.RCONST(0.0), -1, NONE())); + then outExp; + end match; +end createAssertforSqrt; + +public function createDAEString + input String inString; + output DAE.Exp outExp; + annotation(__OpenModelica_EarlyInline = true); +algorithm + outExp := DAE.SCONST(inString); +end createDAEString; + +/* end of TypeView published functions */ + +// ============================================================================= +// section to generate SimCode from functions +// +// Finds the called functions in BackendDAE and transforms them to a list of +// libraries and a list of SimCode.Function uniontypes. +// ============================================================================= + +protected function orderRecordDecls + input SimCode.RecordDeclaration decl1; + input SimCode.RecordDeclaration decl2; + output Boolean b; +algorithm + b := match (decl1,decl2) + local + Absyn.Path path1,path2; + case (SimCode.RECORD_DECL_DEF(path=path1),SimCode.RECORD_DECL_DEF(path=path2)) then Absyn.pathGe(path1,path2); + else true; + end match; +end orderRecordDecls; + +public function elaborateFunctions + input Absyn.Program program; + input list daeElements; + input list metarecordTypes; + input list literals; + input list includes; + output list functions; + output list extraRecordDecls; + output list outIncludes; + output list includeDirs; + output list libs; + output list libpaths; +protected + list fns; + list outRecordTypes; + HashTableStringToPath.HashTable ht; + list>> g; +algorithm + (extraRecordDecls, outRecordTypes) := elaborateRecordDeclarationsForMetarecords(literals, {}, {}); + (functions, outRecordTypes, extraRecordDecls, outIncludes, includeDirs, libs,libpaths) := elaborateFunctions2(program, daeElements, {}, outRecordTypes, extraRecordDecls, includes, {}, {},{}); + extraRecordDecls := List.unique(extraRecordDecls); + (extraRecordDecls, _) := elaborateRecordDeclarationsFromTypes(metarecordTypes, extraRecordDecls, outRecordTypes); + extraRecordDecls := List.sort(extraRecordDecls, orderRecordDecls); + ht := HashTableStringToPath.emptyHashTableSized(BaseHashTable.lowBucketSize); + (extraRecordDecls,_) := List.mapFold(extraRecordDecls, aliasRecordDeclarations, ht); + // Topological sort since we have no guarantees in the order of generated records + g := Graph.buildGraph(extraRecordDecls, getRecordDependencies, extraRecordDecls); + (extraRecordDecls, {}) := Graph.topologicalSort(g, isRecordDeclEqual); +end elaborateFunctions; + +protected function getRecordDependencies + input SimCode.RecordDeclaration decl; + input list allDecls; + output list dependencies; +algorithm + dependencies := match (decl,allDecls) + local + String name; + list vars; + list tys; + list> tyss; + case (SimCode.RECORD_DECL_FULL(aliasName=SOME(name)),_) + then List.select1(allDecls, isRecordDecl, name); + case (SimCode.RECORD_DECL_FULL(variables=vars),_) + equation + tys = list(getVarType(v) for v in vars); + tyss = List.map1(tys, Types.getAllInnerTypesOfType, Util.anyReturnTrue); + tys = List.flatten(tyss); + dependencies = List.filterMap1(tys, getRecordDependenciesFromType, allDecls); + then List.unique(dependencies); + else {}; + end match; +end getRecordDependencies; + +protected function getVarType + input SimCode.Variable var; + output DAE.Type ty; +algorithm + ty := match var + case SimCode.VARIABLE(ty=ty) then ty; + else DAE.T_ANYTYPE_DEFAULT; + end match; +end getVarType; + +protected function getRecordDependenciesFromType + input DAE.Type ty; + input list allDecls; + output SimCode.RecordDeclaration decl; +protected + Absyn.Path path; + String name; +algorithm + DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path)) := ty; + name := Absyn.pathStringUnquoteReplaceDot(path, "_"); + decl := List.selectFirst1(allDecls, isRecordDecl, name); +end getRecordDependenciesFromType; + +protected function isRecordDecl + input SimCode.RecordDeclaration decl; + input String name; + output Boolean b; +algorithm + b := match (decl,name) + local + String name1; + case (SimCode.RECORD_DECL_FULL(name=name1),_) then stringEq(name,name1); + else false; + end match; +end isRecordDecl; + +protected function isRecordDeclEqual + input SimCode.RecordDeclaration decl1; + input SimCode.RecordDeclaration decl2; + output Boolean b; +algorithm + b := match (decl1,decl2) + local + String name1,name2; + Absyn.Path path1,path2; + case (SimCode.RECORD_DECL_FULL(name=name1),SimCode.RECORD_DECL_FULL(name=name2)) then stringEq(name1,name2); + case (SimCode.RECORD_DECL_DEF(path=path1),SimCode.RECORD_DECL_DEF(path=path2)) then Absyn.pathEqual(path1,path2); + else false; + end match; +end isRecordDeclEqual; + +protected function elaborateFunctions2 + input Absyn.Program program; + input list daeElements; + input list inFunctions; + input list inRecordTypes; + input list inDecls; + input list inIncludes; + input list inIncludeDirs; + input list inLibs; + input list inPaths; + output list outFunctions; + output list outRecordTypes; + output list outDecls; + output list outIncludes; + output list outIncludeDirs; + output list outLibs; + output list outLibsPaths; +algorithm + (outFunctions, outRecordTypes, outDecls, outIncludes, outIncludeDirs, outLibs,outLibsPaths) := + match (program, daeElements, inFunctions, inRecordTypes, inDecls, inIncludes, inIncludeDirs, inLibs,inPaths) + local + Boolean b; + list accfns, fns; + SimCode.Function fn; + list rt, rt_1, rt_2, includes, libs,libPaths; + DAE.Function fel; + list rest; + list decls; + String name; + list includeDirs; + Absyn.Path path; + + case (_, {}, accfns, rt, decls, includes, includeDirs, libs,libPaths) + then (listReverse(accfns), rt, decls, includes, includeDirs, libs,libPaths); + case (_, (DAE.FUNCTION( type_ = DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN_PTR()))) :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) + equation + // skip over builtin functions + (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); + then + (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + case (_, (DAE.FUNCTION(partialPrefix = true) :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) + equation + // skip over partial functions + (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); + then + (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + case (_, DAE.FUNCTION(functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(language="builtin"))::_)::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) + equation + // skip over builtin functions + (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); + then + (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + + case (_, (fel as DAE.FUNCTION(functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="C"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) + equation + // skip over builtin functions + b = listMember(name, SCode.knownExternalCFunctions); + (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), rt, decls, includes, includeDirs, libs,libPaths); + then + (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + + case (_, (fel :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) + equation + (fn, rt_1, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, (fn :: accfns), rt_1, decls, includes, includeDirs, libs,libPaths); + then + (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + end match; +end elaborateFunctions2; + +/* Does the actual work of transforming a DAE.FUNCTION to a SimCode.Function. */ +protected function elaborateFunction + input Absyn.Program program; + input DAE.Function inElement; + input list inRecordTypes; + input list inRecordDecls; + input list inIncludes; + input list inIncludeDirs; + input list inLibs; + input list inLibPaths; + output SimCode.Function outFunction; + output list outRecordTypes; + output list outRecordDecls; + output list outIncludes; + output list outIncludeDirs; + output list outLibs; + output list outLibPaths; +algorithm + (outFunction, outRecordTypes, outRecordDecls, outIncludes, outIncludeDirs, outLibs,outLibPaths):= + matchcontinue (program, inElement, inRecordTypes, inRecordDecls, inIncludes, inIncludeDirs, inLibs,inLibPaths) + local + DAE.Function fn; + String extfnname, lang, str; + list algs, vars; // , bivars, invars, outvars; + list includes, libs, libPaths, fn_libs,fn_paths, fn_includes, fn_includeDirs, rt, rt_1; + Absyn.Path fpath; + list args; + DAE.Type restype, tp; + list extargs; + list simextargs; + SimCode.SimExtArg extReturn; + DAE.ExtArg extretarg; + Option ann; + DAE.ExternalDecl extdecl; + list outVars, inVars, biVars, funArgs, varDecls; + list recordDecls; + list bodyStmts; + list daeElts; + Absyn.Path name; + DAE.ElementSource source; + SourceInfo info; + Boolean dynamicLoad, hasIncludeAnnotation, hasLibraryAnnotation; + list includeDirs; + DAE.FunctionAttributes funAttrs; + list varlst; + DAE.VarKind kind; + SCode.Visibility visibility; + + // Modelica functions. + case (_, DAE.FUNCTION(path = fpath, source = source, visibility = visibility, + functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps + type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes=funAttrs), + partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) + equation + + DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_NON_PARALLEL()) = funAttrs; + + outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); + funArgs = List.map1(args, typesSimFunctionArg, NONE()); + (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + vars = List.filter(daeElts, isVarQ); + varDecls = List.map(vars, daeInOutSimVar); + algs = List.filterOnTrue(daeElts, DAEUtil.isAlgorithm); + bodyStmts = List.map(algs, elaborateStatement); + info = DAEUtil.getElementSourceFileInfo(source); + then + (SimCode.FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, visibility, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + + + case (_, DAE.FUNCTION(path = fpath, source = source, + functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps + type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes=funAttrs), + partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) + equation + + DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_KERNEL_FUNCTION()) = funAttrs; + + outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); + funArgs = List.map1(args, typesSimFunctionArg, NONE()); + (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + vars = List.filter(daeElts, isVarNotInputNotOutput); + varDecls = List.map(vars, daeInOutSimVar); + algs = List.filterOnTrue(daeElts, DAEUtil.isAlgorithm); + bodyStmts = List.map(algs, elaborateStatement); + info = DAEUtil.getElementSourceFileInfo(source); + then + (SimCode.KERNEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + + + case (_, DAE.FUNCTION(path = fpath, source = source, + functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps + type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes = funAttrs), + partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) + equation + + DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_PARALLEL_FUNCTION()) = funAttrs; + + outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); + funArgs = List.map1(args, typesSimFunctionArg, NONE()); + (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + vars = List.filter(daeElts, isVarQ); + varDecls = List.map(vars, daeInOutSimVar); + algs = List.filterOnTrue(daeElts, DAEUtil.isAlgorithm); + bodyStmts = List.map(algs, elaborateStatement); + info = DAEUtil.getElementSourceFileInfo(source); + then + (SimCode.PARALLEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + + // External functions. + case (_, DAE.FUNCTION(path = fpath, source = source, visibility = visibility, + functions = DAE.FUNCTION_EXT(body = daeElts, externalDecl = extdecl)::_, // might be followed by derivative maps + type_ = (DAE.T_FUNCTION(funcArg = args))), rt, recordDecls, includes, includeDirs, libs,libPaths) + equation + DAE.EXTERNALDECL(name=extfnname, args=extargs, + returnArg=extretarg, language=lang, ann=ann) = extdecl; + // outvars = DAEUtil.getOutputVars(daeElts); + // invars = DAEUtil.getInputVars(daeElts); + // bivars = DAEUtil.getBidirVars(daeElts); + funArgs = List.map1(args, typesSimFunctionArg, NONE()); + outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); + inVars = List.map(DAEUtil.getInputVars(daeElts), daeInOutSimVar); + biVars = List.map(DAEUtil.getBidirVars(daeElts), daeInOutSimVar); + (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + info = DAEUtil.getElementSourceFileInfo(source); + (fn_includes, fn_includeDirs, fn_libs, fn_paths,dynamicLoad) = generateExtFunctionIncludes(program, fpath, ann, info); + includes = List.union(fn_includes, includes); + includeDirs = List.union(fn_includeDirs, includeDirs); + libs = List.union(fn_libs, libs); + libPaths = List.union(fn_paths, libPaths); + simextargs = List.map(extargs, extArgsToSimExtArgs); + extReturn = extArgsToSimExtArgs(extretarg); + (simextargs, extReturn) = fixOutputIndex(outVars, simextargs, extReturn); + // make lang to-upper as we have FORTRAN 77 and Fortran 77 in the Modelica Library! + lang = System.toupper(lang); + then + (SimCode.EXTERNAL_FUNCTION(fpath, extfnname, funArgs, simextargs, extReturn, + inVars, outVars, biVars, fn_includes, fn_libs, lang, visibility, info, dynamicLoad), + rt_1, recordDecls, includes, includeDirs, libs,libPaths); + + // Record constructor. + case (_, DAE.RECORD_CONSTRUCTOR(source = source, type_ = DAE.T_FUNCTION(funcArg = args, funcResultType = restype as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(name))),kind=kind), rt, recordDecls, includes, includeDirs, libs,libPaths) + equation + funArgs = List.map1(args, typesSimFunctionArg, NONE()); + (recordDecls, rt_1) = elaborateRecordDeclarationsForRecord(restype, recordDecls, rt); + DAE.T_COMPLEX(varLst = varlst) = restype; + varlst = List.filterOnTrue(varlst, Types.isProtectedVar); + varDecls = List.map(varlst, typesVar); + info = DAEUtil.getElementSourceFileInfo(source); + then + (SimCode.RECORD_CONSTRUCTOR(name, funArgs, varDecls, SCode.PUBLIC(), info, kind), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + + // failure + case (_, fn, _, _, _, _, _,_) + equation + Error.addInternalError("function elaborateFunction failed for function: \n" + DAEDump.dumpFunctionStr(fn), sourceInfo()); + then + fail(); + end matchcontinue; +end elaborateFunction; + +protected function typesSimFunctionArg +"Generates code from a function argument." + input DAE.FuncArg inFuncArg; + input Option binding; + output SimCode.Variable outVar; +algorithm + outVar := matchcontinue (inFuncArg, binding) + local + DAE.Type tty; + String name; + DAE.ComponentRef cref_; + DAE.Const const; + list args; + DAE.Type res_ty; + list var_args; + list tys; + DAE.VarKind kind; + DAE.VarParallelism prl; + + case (DAE.FUNCARG(name=name, ty=DAE.T_FUNCTION(funcArg = args, funcResultType = DAE.T_TUPLE(types = tys))), _) + equation + var_args = List.map1(args, typesSimFunctionArg, NONE()); + tys = List.map(tys, Types.simplifyType); + then + SimCode.FUNCTION_PTR(name, tys, var_args, binding); + + case (DAE.FUNCARG(name=name, ty=DAE.T_FUNCTION(funcArg = args, funcResultType = DAE.T_NORETCALL())), _) + equation + var_args = List.map1(args, typesSimFunctionArg, NONE()); + then + SimCode.FUNCTION_PTR(name, {}, var_args, binding); + + case (DAE.FUNCARG(name=name, ty=DAE.T_FUNCTION(funcArg = args, funcResultType = res_ty)), _) + equation + res_ty = Types.simplifyType(res_ty); + var_args = List.map1(args, typesSimFunctionArg, NONE()); + then + SimCode.FUNCTION_PTR(name, {res_ty}, var_args, binding); + + case (DAE.FUNCARG(name=name, ty=tty, par=prl, const=const), _) + equation + tty = Types.simplifyType(tty); + cref_ = ComponentReference.makeCrefIdent(name, tty, {}); + kind = DAEUtil.const2VarKind(const); + then + SimCode.VARIABLE(cref_, tty, binding, {}, prl, kind); + end matchcontinue; +end typesSimFunctionArg; + +protected function daeInOutSimVar + input DAE.Element inElement; + output SimCode.Variable outVar; +algorithm + outVar := matchcontinue(inElement) + local + String name; + DAE.Type daeType; + DAE.ComponentRef id; + DAE.VarKind kind; + DAE.VarParallelism prl; + list inst_dims; + list inst_dims_exp; + Option binding; + SimCode.Variable var; + case (DAE.VAR(componentRef = DAE.CREF_IDENT(ident=name), ty = daeType as DAE.T_FUNCTION(), parallelism = prl, binding = binding)) + equation + var = typesSimFunctionArg(DAE.FUNCARG(name, daeType, DAE.C_VAR(), prl, NONE()), binding); + then var; + + case (DAE.VAR(componentRef = id, + parallelism = prl, + ty = daeType, + binding = binding, + dims = inst_dims, + kind = kind + )) + equation + daeType = Types.simplifyType(daeType); + inst_dims_exp = List.map(inst_dims, Expression.dimensionSizeExpHandleUnkown); + then SimCode.VARIABLE(id, daeType, binding, inst_dims_exp, prl, kind); + else + equation + // TODO: ArrayEqn fails here + Error.addInternalError("function daeInOutSimVar failed\n", sourceInfo()); + then + fail(); + end matchcontinue; +end daeInOutSimVar; + +protected function extArgsToSimExtArgs + input DAE.ExtArg extArg; + output SimCode.SimExtArg simExtArg; +algorithm + simExtArg := + match (extArg) + local + DAE.ComponentRef componentRef; + DAE.Attributes attributes; + DAE.Type type_; + Boolean isInput; + Boolean isOutput; + Boolean isArray; + DAE.Exp exp_; + Integer outputIndex; + + case DAE.EXTARG(componentRef, attributes, type_) + equation + isInput = Types.isInputAttr(attributes); + isOutput = Types.isOutputAttr(attributes); + outputIndex = if isOutput then -1 else 0; // correct output index is added later by fixOutputIndex + isArray = Types.isArray(type_); + type_ = Types.simplifyType(type_); + then SimCode.SIMEXTARG(componentRef, isInput, outputIndex, isArray, false /*fixed later*/, type_); + + case DAE.EXTARGEXP(exp_, type_) + equation + type_ = Types.simplifyType(type_); + then SimCode.SIMEXTARGEXP(exp_, type_); + + case DAE.EXTARGSIZE(componentRef, attributes, type_, exp_) + equation + isInput = Types.isInputAttr(attributes); + isOutput = Types.isOutputAttr(attributes); + outputIndex = if isOutput then -1 else 0; // correct output index is added later by fixOutputIndex + type_ = Types.simplifyType(type_); + then SimCode.SIMEXTARGSIZE(componentRef, isInput, outputIndex, type_, exp_); + + case DAE.NOEXTARG() then SimCode.SIMNOEXTARG(); + end match; +end extArgsToSimExtArgs; + +protected function fixOutputIndex + input list outVars; + input list simExtArgsIn; + input SimCode.SimExtArg extReturnIn; + output list simExtArgsOut; + output SimCode.SimExtArg extReturnOut; +algorithm + (simExtArgsOut, extReturnOut) := match (outVars, simExtArgsIn, extReturnIn) + local + case (_, _, _) + equation + simExtArgsOut = List.map1(simExtArgsIn, assignOutputIndex, outVars); + extReturnOut = assignOutputIndex(extReturnIn, outVars); + then + (simExtArgsOut, extReturnOut); + end match; +end fixOutputIndex; + +protected function assignOutputIndex + input SimCode.SimExtArg simExtArgIn; + input list outVars; + output SimCode.SimExtArg simExtArgOut; +algorithm + simExtArgOut := + matchcontinue (simExtArgIn, outVars) + local + DAE.ComponentRef cref, fcref; + Boolean isInput; + Integer outputIndex; // > 0 if output + Boolean isArray, hasBinding; + DAE.Type type_; + DAE.Exp exp; + Integer newOutputIndex; + + case (SimCode.SIMEXTARG(cref, isInput, outputIndex, isArray, _, type_), _) + equation + true = outputIndex == -1; + fcref = ComponentReference.crefFirstCref(cref); + (newOutputIndex, hasBinding) = findIndexInList(fcref, outVars, 1); + then + SimCode.SIMEXTARG(cref, isInput, newOutputIndex, isArray, hasBinding, type_); + + case (SimCode.SIMEXTARGSIZE(cref, isInput, outputIndex, type_, exp), _) + equation + true = outputIndex == -1; + (newOutputIndex, _) = findIndexInList(cref, outVars, 1); + then + SimCode.SIMEXTARGSIZE(cref, isInput, newOutputIndex, type_, exp); + + else + simExtArgIn; + end matchcontinue; +end assignOutputIndex; + +protected function findIndexInList + input DAE.ComponentRef cref; + input list outVars; + input Integer inCurrentIndex; + output Integer crefIndexInOutVars; + output Boolean hasBinding; +algorithm + (crefIndexInOutVars, hasBinding) := + matchcontinue (cref, outVars, inCurrentIndex) + local + DAE.ComponentRef name; + list restOutVars; + Option v; + Integer currentIndex; + + case (_, {}, _) then (-1, false); + case (_, SimCode.VARIABLE(name=name, value=v) :: _, currentIndex) + equation + true = ComponentReference.crefEqualNoStringCompare(cref, name); + then (currentIndex, Util.isSome(v)); + case (_, _ :: restOutVars, currentIndex) + equation + currentIndex = currentIndex + 1; + (currentIndex, hasBinding) = findIndexInList(cref, restOutVars, currentIndex); + then (currentIndex, hasBinding); + end matchcontinue; +end findIndexInList; + +protected function elaborateStatement + input DAE.Element inElement; + output SimCode.Statement outStatement; +algorithm + (outStatement):= + matchcontinue (inElement) + local + list stmts; + case (DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(statementLst = stmts))) + then + SimCode.ALGORITHM(stmts); + else + equation + true = Flags.isSet(Flags.FAILTRACE); + Debug.trace("# SimCode.elaborateStatement failed\n"); + then + fail(); + end matchcontinue; +end elaborateStatement; + + +public function checkValidMainFunction +"Verifies that an in-function can be generated. +This is not the case if the input involves function-pointers." + input String name; + input SimCode.Function fn; +algorithm + _ := matchcontinue (name, fn) + local + list inVars; + case (_, SimCode.FUNCTION(functionArguments = inVars)) + equation + failure(_ = List.selectFirst(inVars, isFunctionPtr)); + then (); + case (_, SimCode.EXTERNAL_FUNCTION(inVars = inVars)) + equation + failure(_ = List.selectFirst(inVars, isFunctionPtr)); + then (); + else + equation + Error.addMessage(Error.GENERATECODE_INVARS_HAS_FUNCTION_PTR, {name}); + then fail(); + end matchcontinue; +end checkValidMainFunction; + +public function isBoxedFunction +"Verifies that an in-function can be generated. +This is not the case if the input involves function-pointers." + input SimCode.Function fn; + output Boolean b; +algorithm + b := matchcontinue fn + local + list inVars, outVars; + case (SimCode.FUNCTION(functionArguments = inVars, outVars = outVars)) + equation + List.map_0(inVars, isBoxedArg); + List.map_0(outVars, isBoxedArg); + then true; + case (SimCode.EXTERNAL_FUNCTION(inVars = inVars, outVars = outVars)) + equation + List.map_0(inVars, isBoxedArg); + List.map_0(outVars, isBoxedArg); + then true; + else false; + end matchcontinue; +end isBoxedFunction; + +protected function isFunctionPtr +"Checks if an input variable is a function pointer" + input SimCode.Variable var; + output Boolean b; +algorithm + b := match var + /* Yes, they are VARIABLE, not SimCode.FUNCTION_PTR. */ + case SimCode.FUNCTION_PTR() then true; + else false; + end match; +end isFunctionPtr; + +protected function isBoxedArg +"Checks if a variable is a boxed datatype" + input SimCode.Variable var; +algorithm + _ := match var + case SimCode.FUNCTION_PTR() then (); + case SimCode.VARIABLE(ty = DAE.T_METABOXED()) then (); + case SimCode.VARIABLE(ty = DAE.T_METATYPE()) then (); + case SimCode.VARIABLE(ty = DAE.T_STRING()) then (); + end match; +end isBoxedArg; + +public function findLiterals + "Finds all literal expressions in functions" + input list fns; + output list ofns; + output list literals; +algorithm + (ofns, (_, _, literals)) := DAEUtil.traverseDAEFunctions( + fns, findLiteralsHelper, + (0, HashTableExpToIndex.emptyHashTableSized(BaseHashTable.bigBucketSize), {}), {}); + literals := listReverse(literals); +end findLiterals; + +public + +function findLiteralsHelper + input DAE.Exp inExp; + input tuple> inTpl; + output DAE.Exp exp; + output tuple> tpl; +algorithm + exp := inExp; + tpl := inTpl; + (exp, tpl) := Expression.traverseExpBottomUp(exp, replaceLiteralExp, tpl); + (exp, tpl) := Expression.traverseExpTopDown(exp, replaceLiteralArrayExp, tpl); +end findLiteralsHelper; + +protected + +function replaceLiteralArrayExp + "The tuples contain: + * The expression to be replaced (or not) + * Index of next literal + * HashTable Exp->Index (Number of the literal) + * The list of literals + + Handles only array expressions (needs to be performed in a top-down fashion) + " + input DAE.Exp inExp; + input tuple> inTpl; + output DAE.Exp outExp; + output Boolean cont; + output tuple> outTpl; +algorithm + (outExp,cont,outTpl) := matchcontinue (inExp,inTpl) + local + DAE.Exp exp,exp2; + tuple> tpl; + case (DAE.ARRAY(), _) + equation + isLiteralArrayExp(inExp); + (exp2, tpl) = replaceLiteralExp2(inExp, inTpl); + then (exp2, false, tpl); + case (exp as DAE.ARRAY(), tpl) + equation + failure(isLiteralArrayExp(exp)); + then (exp, false, tpl); + case (exp as DAE.MATRIX(), _) + equation + isLiteralArrayExp(exp); + (exp2, tpl) = replaceLiteralExp2(inExp, inTpl); + then (exp2, false, tpl); + case (exp as DAE.MATRIX(), tpl) + equation + failure(isLiteralArrayExp(exp)); + then (exp, false, tpl); + else (inExp, true, inTpl); + end matchcontinue; +end replaceLiteralArrayExp; + +function replaceLiteralExp + "The tuples contain: + * The expression to be replaced (or not) + * Index of next literal + * HashTable Exp->Index (Number of the literal) + * The list of literals + " + input DAE.Exp inExp; + input tuple> inTpl; + output DAE.Exp outExp; + output tuple> outTpl; +algorithm + (outExp,outTpl) := matchcontinue (inExp,inTpl) + local + DAE.Exp exp; + String msg; + tuple> t; + list es; + case (exp, t) + equation + failure(isLiteralExp(exp)); + then (exp, t); + case (exp, t) + equation + isTrivialLiteralExp(exp); + then (exp, t); + case (DAE.LIST(valList=es), t) + equation + true = listLength(es) > 25; + (exp,t) = replaceLiteralExp2(inExp, t); + then (exp, t); // Too large list; causes performance issues to find all sublists... + case (exp, t) + equation + exp = listToCons(exp); + (exp, t) = Expression.traverseExpBottomUp(exp, replaceLiteralExp, t); + then (exp, t); // All sublists should also be added as literals... + case (exp, _) + equation + failure(_ = listToCons(exp)); + (exp,t) = replaceLiteralExp2(exp, inTpl); + then (exp, t); + case (exp, _) + equation + msg = "function replaceLiteralExp failed. Falling back to not replacing "+ExpressionDump.printExpStr(exp)+"."; + Error.addInternalError(msg, sourceInfo()); + then (inExp,inTpl); + end matchcontinue; +end replaceLiteralExp; + +function replaceLiteralExp2 + "The tuples contain: + * The expression to be replaced (or not) + * Index of next literal + * HashTable Exp->Index (Number of the literal) + * The list of literals + " + input DAE.Exp inExp; + input tuple> inTpl; + output DAE.Exp outExp; + output tuple> outTpl; +algorithm + (outExp,outTpl) := matchcontinue (inExp,inTpl) + local + DAE.Exp exp, nexp; + Integer i, ix; + list l; + DAE.Type et; + HashTableExpToIndex.HashTable ht; + case (exp, (i, ht, l)) + equation + ix = BaseHashTable.get(exp, ht); + nexp = DAE.SHARED_LITERAL(ix, exp); + then (nexp, (i, ht, l)); + case (exp, (i, ht, l)) + equation + ht = BaseHashTable.add((exp, i), ht); + nexp = DAE.SHARED_LITERAL(i, exp); + then (nexp, (i+1, ht, exp::l)); + end matchcontinue; +end replaceLiteralExp2; + +function listToCons +"Converts a DAE.LIST to a chain of DAE.CONS" + input DAE.Exp e; + output DAE.Exp o; +algorithm + o := match e + local + list es; + case DAE.LIST(es as _::_) then listToCons2(es); + end match; +end listToCons; + +function listToCons2 +"Converts a DAE.LIST to a chain of DAE.CONS" + input list ies; + output DAE.Exp o; +algorithm + o := match ies + local + DAE.Exp car, cdr; + list es; + case ({}) then DAE.LIST({}); + case (car::es) + equation + cdr = listToCons2(es); + then DAE.CONS(car, cdr); + end match; +end listToCons2; + +function isTrivialLiteralExp +"Succeeds if the expression should not be translated to a constant literal because it is too simple" + input DAE.Exp exp; +algorithm + _ := match exp + case DAE.BOX(DAE.SCONST(_)) then fail(); + case DAE.BOX(DAE.RCONST(_)) then fail(); + case DAE.BOX(_) then (); + case DAE.ICONST(_) then (); + case DAE.BCONST(_) then (); + case DAE.RCONST(_) then (); + case DAE.ENUM_LITERAL() then (); + case DAE.LIST(valList={}) then (); + case DAE.META_OPTION(NONE()) then (); + case DAE.SHARED_LITERAL() then (); + else fail(); + end match; +end isTrivialLiteralExp; + +function isLiteralArrayExp + input DAE.Exp iexp; +algorithm + _ := match iexp + local + DAE.Exp e1, e2, exp; + list expl; + list> expll; + + case DAE.SCONST(_) then (); + case DAE.ICONST(_) then (); + case DAE.RCONST(_) then (); + case DAE.BCONST(_) then (); + case DAE.ARRAY(array=expl) equation List.map_0(expl, isLiteralArrayExp); then (); + case DAE.MATRIX(matrix=expll) equation List.map_0(List.flatten(expll), isLiteralArrayExp); then (); + case DAE.ENUM_LITERAL() then (); + case DAE.META_OPTION(NONE()) then (); + case DAE.META_OPTION(SOME(exp)) equation isLiteralArrayExp(exp); then (); + case DAE.BOX(exp) equation isLiteralArrayExp(exp); then (); + case DAE.CONS(car = e1, cdr = e2) equation isLiteralArrayExp(e1); isLiteralArrayExp(e2); then (); + case DAE.LIST(valList = expl) equation List.map_0(expl, isLiteralArrayExp); then (); + case DAE.META_TUPLE(expl) equation List.map_0(expl, isLiteralArrayExp); then (); + case DAE.METARECORDCALL(args=expl) equation List.map_0(expl, isLiteralArrayExp); then (); + case DAE.SHARED_LITERAL() then (); + else fail(); + end match; +end isLiteralArrayExp; + +function isLiteralExp +"Returns if the expression may be replaced by a constant literal" + input DAE.Exp iexp; +algorithm + _ := match iexp + local + DAE.Exp e1, e2, exp; + list expl; + case DAE.SCONST(_) then (); + case DAE.ICONST(_) then (); + case DAE.RCONST(_) then (); + case DAE.BCONST(_) then (); + case DAE.ENUM_LITERAL() then (); + case DAE.META_OPTION(NONE()) then (); + case DAE.META_OPTION(SOME(exp)) equation isLiteralExp(exp); then (); + case DAE.BOX(exp) equation isLiteralExp(exp); then (); + case DAE.CONS(car = e1, cdr = e2) equation isLiteralExp(e1); isLiteralExp(e2); then (); + case DAE.LIST(valList = expl) equation List.map_0(expl, isLiteralExp); then (); + case DAE.META_TUPLE(expl) equation List.map_0(expl, isLiteralExp); then (); + case DAE.METARECORDCALL(args=expl) equation List.map_0(expl, isLiteralExp); then (); + case DAE.SHARED_LITERAL() then (); + else fail(); + end match; +end isLiteralExp; + +protected function elaborateRecordDeclarationsFromTypes + input list inTypes; + input list inAccRecordDecls; + input list inReturnTypes; + output list outRecordDecls; + output list outReturnTypes; +algorithm + (outRecordDecls, outReturnTypes) := + match (inTypes, inAccRecordDecls, inReturnTypes) + local + list accRecDecls; + DAE.Type firstType; + list restTypes; + list returnTypes; + + case ({}, accRecDecls, _) + then (accRecDecls, inReturnTypes); + case (firstType :: restTypes, accRecDecls, _) + equation + (accRecDecls, returnTypes) = + elaborateRecordDeclarationsForRecord(firstType, accRecDecls, inReturnTypes); + (accRecDecls, returnTypes) = + elaborateRecordDeclarationsFromTypes(restTypes, accRecDecls, returnTypes); + then (accRecDecls, returnTypes); + end match; +end elaborateRecordDeclarationsFromTypes; + +protected function elaborateRecordDeclarations +"Translate all records used by varlist to structs." + input list inVars; + input list inAccRecordDecls; + input list inReturnTypes; + output list outRecordDecls; + output list outReturnTypes; +algorithm + (outRecordDecls, outReturnTypes) := + matchcontinue (inVars, inAccRecordDecls, inReturnTypes) + local + DAE.Element var; + list rest; + DAE.Type ft; + list rt, rt_1, rt_2; + list accRecDecls; + DAE.Algorithm algorithm_; + list expl; + + case ({}, accRecDecls, rt) then (accRecDecls, rt); + + case (((DAE.VAR(ty = ft)) :: rest), accRecDecls, rt) + equation + (accRecDecls, rt_1) = elaborateRecordDeclarationsForRecord(ft, accRecDecls, rt); + (accRecDecls, rt_2) = elaborateRecordDeclarations(rest, accRecDecls, rt_1); + then + (accRecDecls, rt_2); + + case ((DAE.ALGORITHM(algorithm_ = algorithm_) :: rest), accRecDecls, rt) + equation + true = Config.acceptMetaModelicaGrammar(); + ((_, expl)) = DAEUtil.traverseAlgorithmExps(algorithm_, Expression.traverseSubexpressionsHelper, (matchMetarecordCalls, {})); + (accRecDecls, rt_2) = elaborateRecordDeclarationsForMetarecords(expl, accRecDecls, rt); + // TODO: ? what about rest ? , can be there something else after the ALGORITHM + (accRecDecls, rt_2) = elaborateRecordDeclarations(rest, accRecDecls, rt_2); + then + (accRecDecls, rt_2); + + case ((_ :: rest), accRecDecls, rt) + equation + (accRecDecls, rt_1) = elaborateRecordDeclarations(rest, accRecDecls, rt); + then + (accRecDecls, rt_1); + end matchcontinue; +end elaborateRecordDeclarations; + +protected function matchMetarecordCalls "Used together with getMatchingExps" + input DAE.Exp e; + input list acc; + output DAE.Exp outExp; + output list outExps; +algorithm + (outExp,outExps) := matchcontinue (e,acc) + local + Integer index; + case (DAE.METARECORDCALL(index = index), _) + equation + outExps = List.consOnTrue(-1 <> index, e, acc); + then (e, outExps); + else (e,acc); + end matchcontinue; +end matchMetarecordCalls; + +protected function isVarQ +"Succeeds if inElement is a variable or constant that is not input." + input DAE.Element inElement; +algorithm + _ := match (inElement) + local + DAE.VarKind vk; + DAE.VarDirection vd; + case DAE.VAR(kind=vk, direction=vd) + equation + isVarVarOrConstant(vk); + isDirectionNotInput(vd); + then (); + end match; +end isVarQ; + +protected function isVarNotInputNotOutput +"Succeeds if inElement is a variable or constant that is not input or output. +needed in kernel functions since they shouldn't have output vars." + input DAE.Element inElement; +algorithm + _ := match (inElement) + local + DAE.VarKind vk; + DAE.VarDirection vd; + case DAE.VAR(kind=vk, direction=vd) + equation + isVarVarOrConstant(vk); + isDirectionNotInputNotOutput(vd); + then (); + end match; +end isVarNotInputNotOutput; + +protected function isVarVarOrConstant + input DAE.VarKind inVarKind; +algorithm + _ := match (inVarKind) + case DAE.VARIABLE() then (); + case DAE.PARAM() then (); + case DAE.CONST() then (); + end match; +end isVarVarOrConstant; + +protected function isDirectionNotInput + input DAE.VarDirection inVarDirection; +algorithm + _ := match (inVarDirection) + case DAE.OUTPUT() then (); + case DAE.BIDIR() then (); + end match; +end isDirectionNotInput; + +protected function isDirectionNotInputNotOutput + input DAE.VarDirection inVarDirection; +algorithm + _ := match (inVarDirection) + case DAE.BIDIR() then (); + end match; +end isDirectionNotInputNotOutput; + +protected function filterNg "Sets the number of zero crossings to zero if events are disabled." + input Integer ng; + output Integer outInteger; +algorithm + outInteger := if useZerocrossing() then ng else 0; +end filterNg; + +protected function useZerocrossing + output Boolean res; +algorithm + res := Flags.isSet(Flags.EVENTS); +end useZerocrossing; + +protected function getCrefFromExp "Assume input Exp is CREF and return the ComponentRef, fail otherwise." + input DAE.Exp e; + output Absyn.ComponentRef c; +algorithm + c := match (e) + local + DAE.ComponentRef crefe; + Absyn.ComponentRef crefa; + + case(DAE.CREF(componentRef = crefe)) + equation + crefa = ComponentReference.unelabCref(crefe); + then + crefa; + + else + equation + Error.addInternalError("function getCrefFromExp failed: input was not of type DAE.CREF", sourceInfo()); + then + fail(); + end match; +end getCrefFromExp; + +protected function elaborateRecordDeclarationsForRecord +"Helper function to generateStructsForRecords." + input DAE.Type inRecordType; + input list inAccRecordDecls; + input list inReturnTypes; + output list outRecordDecls; + output list outReturnTypes; +algorithm + (outRecordDecls, outReturnTypes) := match (inRecordType, inAccRecordDecls, inReturnTypes) + local + Absyn.Path path, name; + list varlst; + String sname; + list rt, rt_1, rt_2, fieldNames; + list accRecDecls; + list vars; + Integer index; + SimCode.RecordDeclaration recDecl; + + case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(name), varLst = varlst, source = {_}), accRecDecls, rt) + equation + sname = Absyn.pathStringUnquoteReplaceDot(name, "_"); + if not listMember(sname, rt) then + vars = List.map(varlst, typesVarNoBinding); + vars = List.sort(vars,compareVariable); + rt_1 = sname :: rt; + (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(varlst, accRecDecls, rt_1); + recDecl = SimCode.RECORD_DECL_FULL(sname, NONE(), name, vars); + accRecDecls = List.appendElt(recDecl, accRecDecls); + else + rt_2 = rt; + end if; + then (accRecDecls, rt_2); + + case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)), accRecDecls, rt) + then (accRecDecls, rt); + + case (DAE.T_METARECORD(source = {Absyn.QUALIFIED(name="SourceInfo")}), accRecDecls, rt) + then (accRecDecls, rt); + + case (DAE.T_METARECORD( fields = varlst, source = {path}), accRecDecls, rt) + equation + sname = Absyn.pathStringUnquoteReplaceDot(path, "_"); + if not listMember(sname, rt) then + fieldNames = List.map(varlst, generateVarName); + accRecDecls = SimCode.RECORD_DECL_DEF(path, fieldNames) :: accRecDecls; + rt_1 = sname::rt; + (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(varlst, accRecDecls, rt_1); + else + rt_2 = rt; + end if; + then (accRecDecls, rt_2); + + case (_, accRecDecls, rt) + then (accRecDecls, rt); + + end match; +end elaborateRecordDeclarationsForRecord; + +protected function typesVarNoBinding + input DAE.Var inTypesVar; + output SimCode.Variable outVar; +algorithm + outVar := match (inTypesVar) + local + String name; + DAE.Type ty; + DAE.ComponentRef cref_; + DAE.Attributes attr; + SCode.Parallelism scPrl; + DAE.VarParallelism prl; + + case (DAE.TYPES_VAR(name=name, attributes = attr, ty=ty)) + equation + ty = Types.simplifyType(ty); + cref_ = ComponentReference.makeCrefIdent(name, ty, {}); + DAE.ATTR(parallelism = scPrl) = attr; + prl = scodeParallelismToDAEParallelism(scPrl); + then SimCode.VARIABLE(cref_, ty, NONE(), {}, prl,DAE.VARIABLE()); + end match; +end typesVarNoBinding; + +protected function typesVar + input DAE.Var inTypesVar; + output SimCode.Variable outVar; +algorithm + outVar := match (inTypesVar) + local + String name; + DAE.Type ty; + DAE.ComponentRef cref_; + DAE.Attributes attr; + SCode.Parallelism scPrl; + DAE.VarParallelism prl; + DAE.Exp bindExp; + + case (DAE.TYPES_VAR(name=name, attributes = attr, ty=ty)) + equation + ty = Types.simplifyType(ty); + cref_ = ComponentReference.makeCrefIdent(name, ty, {}); + DAE.ATTR(parallelism = scPrl) = attr; + prl = scodeParallelismToDAEParallelism(scPrl); + bindExp = Types.getBindingExp(inTypesVar, Absyn.IDENT(name)); + then SimCode.VARIABLE(cref_, ty, SOME(bindExp), {}, prl, DAE.VARIABLE()); + end match; +end typesVar; + +protected function scodeParallelismToDAEParallelism + input SCode.Parallelism inParallelism; + output DAE.VarParallelism outParallelism; +algorithm + outParallelism := match(inParallelism) + case(SCode.PARGLOBAL()) then DAE.PARGLOBAL(); + case(SCode.PARLOCAL()) then DAE.PARLOCAL(); + case(SCode.NON_PARALLEL()) then DAE.NON_PARALLEL(); + end match; +end scodeParallelismToDAEParallelism; + +protected function variableName + input SimCode.Variable v; + output String s; +algorithm + s := match v + case SimCode.VARIABLE(name=DAE.CREF_IDENT(ident=s)) then s; + case SimCode.FUNCTION_PTR(name=s) then s; + end match; +end variableName; + +protected function compareVariable + input SimCode.Variable v1; + input SimCode.Variable v2; + output Boolean b; +algorithm + b := stringCompare(variableName(v1),variableName(v2)) > 0; +end compareVariable; + +protected function generateVarName + input DAE.Var inVar; + output String outName; +algorithm + outName := + match (inVar) + local + DAE.Ident name; + case DAE.TYPES_VAR(name = name) then name; + else "NULL"; + end match; +end generateVarName; + +protected function elaborateNestedRecordDeclarations +"Helper function to elaborateRecordDeclarations." + input list inRecordTypes; + input list inAccRecordDecls; + input list inReturnTypes; + output list outRecordDecls; + output list outReturnTypes; +algorithm + (outRecordDecls, outReturnTypes) := matchcontinue (inRecordTypes, inAccRecordDecls, inReturnTypes) + local + DAE.Type ty; + list rest; + list rt, rt_1, rt_2; + list accRecDecls; + case ({}, accRecDecls, rt) + then (accRecDecls, rt); + case (DAE.TYPES_VAR(ty = ty as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)))::rest, accRecDecls, rt) + equation + (accRecDecls, rt_1) = elaborateRecordDeclarationsForRecord(ty, accRecDecls, rt); + (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(rest, accRecDecls, rt_1); + then (accRecDecls, rt_2); + case (_::rest, accRecDecls, rt) + equation + (accRecDecls, rt_1) = elaborateNestedRecordDeclarations(rest, accRecDecls, rt); + then (accRecDecls, rt_1); + end matchcontinue; +end elaborateNestedRecordDeclarations; + +protected function elaborateRecordDeclarationsForMetarecords + input list inExpl; + input list inAccRecordDecls; + input list inReturnTypes; + output list outRecordDecls; + output list outReturnTypes; +algorithm + (outRecordDecls, outReturnTypes) := match (inExpl, inAccRecordDecls, inReturnTypes) + local + list rt, rt_1, rt_2, fieldNames; + list rest; + String name; + Absyn.Path path; + list accRecDecls; + Boolean b; + + case ({}, accRecDecls, rt) then (accRecDecls, rt); + case (DAE.METARECORDCALL(path=path, fieldNames=fieldNames)::rest, accRecDecls, rt) + equation + name = Absyn.pathStringUnquoteReplaceDot(path, "_"); + b = listMember(name, rt); + accRecDecls = List.consOnTrue(not b, SimCode.RECORD_DECL_DEF(path, fieldNames), accRecDecls); + rt_1 = List.consOnTrue(not b, name, rt); + (accRecDecls, rt_2) = elaborateRecordDeclarationsForMetarecords(rest, accRecDecls, rt_1); + then (accRecDecls, rt_2); + case (_::rest, accRecDecls, rt) + equation + (accRecDecls, rt_1) = elaborateRecordDeclarationsForMetarecords(rest, accRecDecls, rt); + then (accRecDecls, rt_1); + end match; +end elaborateRecordDeclarationsForMetarecords; + + +protected function generateExtFunctionIncludes "by investigating the annotation of an external function." + input Absyn.Program program; + input Absyn.Path path; + input Option inAbsynAnnotationOption; + input SourceInfo info; + output list includes; + output list includeDirs; + output list libs; + output list paths; + output Boolean dynamcLoad; +algorithm + (includes, includeDirs, libs,paths, dynamcLoad):= + match (program, path, inAbsynAnnotationOption) + local + SCode.Mod mod; + Boolean b; + String target; + Option odir, resources; + list libNames, fullLibNames, dirs; + + case (_, _, SOME(SCode.ANNOTATION(mod))) + algorithm + b := generateExtFunctionDynamicLoad(mod); + target := Flags.getConfigString(Flags.TARGET); + (libs, libNames) := generateExtFunctionIncludesLibstr(target,mod); + includes := generateExtFunctionIncludesIncludestr(mod); + (libs, dirs, resources) := generateExtFunctionLibraryDirectoryFlags(program, path, mod, libs); + for name in if Flags.isSet(Flags.CHECK_EXT_LIBS) then libNames else {} loop + if target=="msvc" or System.os()=="Windows_NT" then + fullLibNames := {name + System.getDllExt(), "lib" + name + ".a", "lib" + name + ".lib"}; + else + fullLibNames := {"lib" + name + ".a", "lib" + name + System.getDllExt()}; + end if; + lookForExtFunctionLibrary(fullLibNames, dirs, name, resources, path, info); + end for; + paths := generateExtFunctionLibraryDirectoryPaths(program, path, mod); + includeDirs := generateExtFunctionIncludeDirectoryFlags(program, path, mod, includes); + then + (includes, includeDirs, libs,paths, b); + case (_, _, NONE()) then ({}, {}, {},{}, false); + end match; +end generateExtFunctionIncludes; + +protected function lookForExtFunctionLibrary + input list names; + input list dirs; + input String name; + input Option resources; + input Absyn.Path path; + input SourceInfo info; +algorithm + if not max(System.regularFileExists(d+"/"+n) for d in dirs, n in names) then + _ := match resources + local + String resourcesStr, tmpdir, cmd, pwd, contents, found; + Integer status; + Boolean didFind; + case SOME(resourcesStr) + algorithm + if System.directoryExists(resourcesStr) then + didFind := false; + for dir in list(dir for dir guard System.regularFileExists(resourcesStr + "/BuildProjects/" + dir + "/autogen.sh") in System.subDirectories(resourcesStr + "/BuildProjects")) loop + tmpdir := System.createTemporaryDirectory(Settings.getTempDirectoryPath() + "/omc_compile_" + name + "_"); + Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Created directory " + tmpdir}, info); + cmd := "cp -a \"" + resourcesStr + "\"/* \"" + tmpdir + "\""; + Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {cmd}, info); + System.systemCall(cmd); + pwd := System.pwd(); + if 0==System.cd(tmpdir + "/BuildProjects/" + dir) then + Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Changed directory to " + System.pwd()}, info); + // TODO: Add $(host) + cmd := "sh ./autogen.sh && ./configure --libdir='"+userCompiledBinariesDirectory(path)+"' && make && make install"; + status := System.systemCall(cmd, "log"); + contents := System.readFile("log"); + if status <> 0 then + Error.addSourceMessage(Error.COMPILER_WARNING, {"Failed to run "+cmd+": " + contents}, info); + else + Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Succeeded with compilation and installation of the library using:\ncommand: "+cmd+"\n" + contents}, info); + if not max(System.regularFileExists(d+"/"+n) for d in dirs, n in names) then + Error.addSourceMessage(Error.EXT_LIBRARY_NOT_FOUND_DESPITE_COMPILATION_SUCCESS, {cmd, System.pwd()}, info); + else + found := listHead(list(x for x guard System.regularFileExists(x) in List.flatten(list(d+"/"+n for d in dirs, n in names)))); + Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Compiled "+found+" by running build project " + resourcesStr + "/BuildProjects/" + dir}, info); + didFind := true; + end if; + end if; + else + Error.addSourceMessage(Error.COMPILER_WARNING, {"Failed to change directory to " + tmpdir + "/BuildProjects/" + dir}, info); + end if; + System.cd(pwd); + System.removeDirectory(tmpdir); + Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Removed directory " + tmpdir}, info); + if didFind then + break; + end if; + end for; + end if; + then (); + else (); + end match; + if not max(System.regularFileExists(d+"/"+n) for d in dirs, n in names) then + // suppress this warning if we're running the testsuite + if not Config.getRunningTestsuite() then + Error.addSourceMessage(Error.EXT_LIBRARY_NOT_FOUND, {name, sum("\n " + d + "/" + n for d in dirs, n in names)}, info); + end if; + end if; + end if; +end lookForExtFunctionLibrary; + +protected function generateExtFunctionIncludeDirectoryFlags + "Process LibraryDirectory and IncludeDirectory" + input Absyn.Program program; + input Absyn.Path path; + input SCode.Mod inMod; + input list includes; + output list outDirs; +algorithm + outDirs := matchcontinue (program, path, inMod, includes) + local + String str,istr; + case (_, _, _, {}) then {}; + case (_, _, _, _) + equation + SCode.MOD(binding = SOME(Absyn.STRING(str))) = + Mod.getUnelabedSubMod(inMod, "IncludeDirectory"); + str = CevalScript.getFullPathFromUri(program, str, false); + istr = "\"-I"+str+"\""; + then if System.directoryExists(str) then {istr} else {}; + case (_, _, _, _) + equation + str = "modelica://" + Absyn.pathFirstIdent(path) + "/Resources/Include"; + str = CevalScript.getFullPathFromUri(program, str, false); + istr = "\"-I"+str+"\""; + then if System.directoryExists(str) then {istr} else {}; + // Read SourceInfo instead? + else {}; + end matchcontinue; +end generateExtFunctionIncludeDirectoryFlags; + +protected function generateExtFunctionLibraryDirectoryFlags + "Process LibraryDirectory and IncludeDirectory" + input Absyn.Program program; + input Absyn.Path path; + input SCode.Mod inMod; + input list inLibs; + output list outLibs; + output list installDirs; + output Option resources; +algorithm + (outLibs, installDirs, resources) := matchcontinue (program, path, inMod, inLibs) + local + String str, str1, str2, str3, platform1, platform2, target, dir, resourcesStr; + list libs, libs2; + Boolean isLinux; + case (_, _, _, {}) then ({}, {}, NONE()); + case (_, _, _, libs) + algorithm + str := matchcontinue inMod + case _ + equation + SCode.MOD(binding = SOME(Absyn.STRING(str))) = Mod.getUnelabedSubMod(inMod, "LibraryDirectory"); + then str; + else "modelica://" + Absyn.pathFirstIdent(path) + "/Resources/Library"; + end matchcontinue; + str := CevalScript.getFullPathFromUri(program, str, false); + resourcesStr := CevalScript.getFullPathFromUri(program, "modelica://" + Absyn.pathFirstIdent(path) + "/Resources", false); + platform1 := str + "/" + System.openModelicaPlatform(); + platform2 := str + "/" + System.modelicaPlatform(); + isLinux := stringEq("linux",System.os()); + target := Flags.getConfigString(Flags.TARGET); + // please, take care about ordering these libraries, the most specific should have the highest priority + libs2 := str::platform2::platform1::(Settings.getHomeDir(false)+"/.openmodelica/binaries/"+Absyn.pathFirstIdent(path))::(Settings.getInstallationDirectoryPath() + "/lib/" + System.getTriple() + "/omc")::(Settings.getInstallationDirectoryPath() + "/lib/")::{}; + libs := List.fold2(libs2, generateExtFunctionLibraryDirectoryFlags2, isLinux, target, libs); + then (libs, listReverse(libs2), SOME(resourcesStr)); + else (inLibs, {}, NONE()); + end matchcontinue; +end generateExtFunctionLibraryDirectoryFlags; + +protected function generateExtFunctionLibraryDirectoryFlags2 + input String dir; + input Boolean isLinux; + input String target; + input list inLibs; + output list libs; +algorithm + libs := if isLinux then "-Wl,-rpath=\"" + dir + "\""::inLibs else inLibs; + libs := (if target=="msvc" then "/LIBPATH:\"" + dir + "\"" else "\"-L" + dir + "\"")::libs; +end generateExtFunctionLibraryDirectoryFlags2; + +protected function userCompiledBinariesDirectory + input Absyn.Path path; + output String str = Settings.getHomeDir(false)+"/.openmodelica/binaries/"+Absyn.pathFirstIdent(path); +end userCompiledBinariesDirectory; + +protected function generateExtFunctionLibraryDirectoryPaths + "Process LibraryDirectory and IncludeDirectory" + input Absyn.Program program; + input Absyn.Path path; + input SCode.Mod inMod; + output list outLibs; +algorithm + outLibs := matchcontinue (program, path, inMod) + local + String str, str1, str2, str3, platform1, platform2,target; + list libs; + Boolean isLinux; + case (_, _, _) + equation + SCode.MOD(binding = SOME(Absyn.STRING(str))) = + Mod.getUnelabedSubMod(inMod, "LibraryDirectory"); + str = CevalScript.getFullPathFromUri(program, str, false); + platform1 = System.openModelicaPlatform(); + platform2 = System.modelicaPlatform(); + isLinux = stringEq("linux",System.os()); + // please, take care about ordering these libraries, the most specific should go first (in reverse here) + libs = generateExtFunctionLibraryDirectoryPaths2(true, str, isLinux, {} ); + libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform2,""), str + "/" + platform2, isLinux, libs); + libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform1,""), str + "/" + platform1, isLinux, libs); + then libs; + case (_, _, _) + equation + str = "modelica://" + Absyn.pathFirstIdent(path) + "/Resources/Library"; + str = CevalScript.getFullPathFromUri(program, str, false); + platform1 = System.openModelicaPlatform(); + platform2 = System.modelicaPlatform(); + isLinux = stringEq("linux",System.os()); + // please, take care about ordering these libraries, the most specific should go first (in reverse here) + libs = generateExtFunctionLibraryDirectoryPaths2(true, str, isLinux, {} ); + libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform2,""), str + "/" + platform2, isLinux, libs); + libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform1,""), str + "/" + platform1, isLinux, libs); + then libs; + else {}; + end matchcontinue; +end generateExtFunctionLibraryDirectoryPaths; + + +protected function generateExtFunctionLibraryDirectoryPaths2 + input Boolean add; + input String dir; + input Boolean isLinux; + input list inLibs; + output list libs; +algorithm + libs := match (add,dir,isLinux,inLibs) + local + Boolean b; + case (true,_,_,libs) + equation + b = System.directoryExists(dir); + libs = List.consOnTrue(b, dir , libs); + then libs; + else inLibs; + end match; +end generateExtFunctionLibraryDirectoryPaths2; + + +protected function getLibraryStringInMSVCFormat +"Takes an Absyn.STRING describing a library and outputs a list +of strings corresponding to it. +Note: Normally only outputs a single string, but Lapack on MinGW is special." + input Absyn.Exp exp; + output list strs; + output list names; +algorithm + (strs,names) := matchcontinue exp + local + String str; + + // seems lapack can show on Lapack form or lapack (different case) (MLS revision 6155) + // Lapack on MinGW/Windows is linked against f2c + case Absyn.STRING(str) guard str=="Lapack" or str=="lapack" + then ({"lapack_win32_MT.lib", "f2c.lib"}, {}); + + // omcruntime on windows needs linking with mico2313 and wsock and then some :) + case Absyn.STRING("omcruntime") + equation + true = "Windows_NT" == System.os(); + strs = {"f2c.lib", "initialization.lib", "libexpat.lib", "math-support.lib", "meta.lib", "ModelicaExternalC.lib", "results.lib", "simulation.lib", "solver.lib", "sundials_kinsol.lib", "sundials_nvecserial.lib", "util.lib", "lapack_win32_MT.lib"}; + then + (strs, {}); + + // Wonder if there may be issues if we have duplicates in the Corba libs + // and the other libs. Some other developer will probably swear over this + // hack some day, but at least I get an early weekend. + case Absyn.STRING("OpenModelicaCorba") + equation + str = System.getCorbaLibs(); + then ({str},{}); + + case Absyn.STRING("fmilib") + then ({"fmilib.lib","shlwapi.lib"},{}); + + // If the string starts with a -, it's probably -l or -L gcc flags + case Absyn.STRING(str) + equation + true = "-" == stringGetStringChar(str, 1); + then ({str},{}); + + case Absyn.STRING(str) + equation + str = str + ".lib"; + then ({str},{}); + + else + equation + Error.addInternalError("Failed to process Library annotation for external function", sourceInfo()); + then fail(); + end matchcontinue; +end getLibraryStringInMSVCFormat; + +protected function getLibraryStringInGccFormat +"Takes an Absyn.STRING describing a library and outputs a list +of strings corresponding to it. +Note: Normally only outputs a single string, but Lapack on MinGW is special." + input Absyn.Exp exp; + output list strs; + output list names; +algorithm + (strs,names) := matchcontinue exp + local + String str, fopenmp; + + // Lapack is always included + case Absyn.STRING("lapack") then ({},{}); + case Absyn.STRING("Lapack") then ({},{}); + + case Absyn.STRING(str as "omcruntime") + equation + if "Windows_NT" == System.os() then + // omcruntime on windows needs linking with mico2313 and wsock and then some :) + str = "-l" + str; + strs = str :: "-lintl" :: "-liconv" :: "-lexpat" :: "-lsqlite3" :: "-llpsolve55" :: "-lmico2313" :: "-lws2_32" :: "-lregex" :: {}; + else + strs = System.getRuntimeLibs(); + end if; + then (strs,{}); + + // Wonder if there may be issues if we have duplicates in the Corba libs + // and the other libs. Some other developer will probably swear over this + // hack some day, but at least I get an early weekend. + case Absyn.STRING("OpenModelicaCorba") + equation + str = System.getCorbaLibs(); + then ({str},{}); + + case Absyn.STRING("fmilib") + then (if System.os()=="Windows_NT" then {"-lfmilib","-lshlwapi"} else {"-lfmilib"},{}); + + case Absyn.STRING(str) + equation + // If the string is a file, return it as it is + // If the string starts with a -, it's probably -l or -L gcc flags + if System.regularFileExists(str) or "-" == stringGetStringChar(str, 1) then + strs = {str}; + names = {}; + else + strs = {"-l" + str}; + names = {str}; + end if; + + then (strs,names); + + else + equation + Error.addInternalError("Failed to process Library annotation for external function", sourceInfo()); + then fail(); + end matchcontinue; +end getLibraryStringInGccFormat; + +protected function generateExtFunctionIncludesLibstr + input String target; + input SCode.Mod inMod; + output list outStringLst; + output list names; +algorithm + (outStringLst, names) := matchcontinue (target,inMod) + local + list arr; + list libs; + list> libsList, namesList; + Absyn.Exp exp; + case ("msvc",_) + equation + SCode.MOD(binding = SOME(Absyn.ARRAY(arr))) = + Mod.getUnelabedSubMod(inMod, "Library"); + (libsList, namesList) = List.map_2(arr, getLibraryStringInMSVCFormat); + then + (List.flatten(libsList), List.flatten(namesList)); + case ("msvc",_) + equation + SCode.MOD(binding = SOME(exp)) = + Mod.getUnelabedSubMod(inMod, "Library"); + (libs,names) = getLibraryStringInMSVCFormat(exp); + then + (libs,names); + case (_,_) + equation + SCode.MOD(binding = SOME(Absyn.ARRAY(arr))) = + Mod.getUnelabedSubMod(inMod, "Library"); + (libsList, namesList) = List.map_2(arr, getLibraryStringInGccFormat); + then + (List.flatten(libsList), List.flatten(namesList)); + case (_,_) + equation + SCode.MOD(binding = SOME(exp)) = + Mod.getUnelabedSubMod(inMod, "Library"); + (libs,names) = getLibraryStringInGccFormat(exp); + then + (libs,names); + else ({},{}); + end matchcontinue; +end generateExtFunctionIncludesLibstr; + +protected function generateExtFunctionIncludesIncludestr + input SCode.Mod inMod; + output list includes; +algorithm + includes := matchcontinue (inMod) + local + String inc, inc_1; + Integer lineNumberStart; + String str,fileName; + case (_) + equation + SCode.MOD(binding = SOME(Absyn.STRING(inc)), info = SOURCEINFO(fileName=fileName,lineNumberStart=lineNumberStart)) = + Mod.getUnelabedSubMod(inMod, "Include"); + str = "#line "+intString(lineNumberStart)+" \""+fileName+"\""; + inc_1 = System.unescapedString(inc); + includes = if Config.acceptMetaModelicaGrammar() or Flags.isSet(Flags.GEN_DEBUG_SYMBOLS) then {str,inc_1} else {inc_1}; + then includes; + else {}; + end matchcontinue; +end generateExtFunctionIncludesIncludestr; + +protected function generateExtFunctionDynamicLoad + input SCode.Mod inMod; + output Boolean outDynamicLoad; +algorithm + outDynamicLoad:= matchcontinue (inMod) + local + Boolean b; + case (_) + equation + SCode.MOD(binding = SOME((Absyn.BOOL(b)))) = + Mod.getUnelabedSubMod(inMod, "DynamicLoad"); + then + b; + else false; + end matchcontinue; +end generateExtFunctionDynamicLoad; + +public function getImplicitRecordConstructors + "If a record instance is sent to a function we need to generate code for the + record constructor even if it's not explicitly called, because the constructor + is used by the generated code. This function checks the arguments of a + function for these implicit record constructor calls and returns a list of all + record constructors that are used." + input list inExpLst; + output list outExpLst; +algorithm + outExpLst := matchcontinue(inExpLst) + local + DAE.ComponentRef cref; + DAE.Type record_type; + Absyn.Path record_path; + list rest_expr; + DAE.Exp record_cref; + case ({}) then {}; + // A record component reference. + case (DAE.CREF( + componentRef = cref, + ty = (DAE.T_COMPLEX( + complexClassType = ClassInf.RECORD(path = record_path)))) :: rest_expr) + equation + // Make sure it has no subscripts, i.e. it's a component reference for + // an entire record instance. + {} = ComponentReference.crefLastSubs(cref); + // Build a DAE.CREF from the record path. + cref = ComponentReference.pathToCref(record_path); + record_cref = Expression.crefExp(cref); + rest_expr = getImplicitRecordConstructors(rest_expr); + then record_cref :: rest_expr; + case (_ :: rest_expr) + equation + rest_expr = getImplicitRecordConstructors(rest_expr); + then rest_expr; + end matchcontinue; +end getImplicitRecordConstructors; + +protected function getCalledFunctionsInFunctions "Goes through the given DAE, finds the given functions and collects + the names of the functions called from within those functions" + input list paths; + input HashTableStringToPath.HashTable inHt; + input DAE.FunctionTree funcs; + output HashTableStringToPath.HashTable outHt; +algorithm + outHt := match (paths, inHt, funcs) + local + list rest; + Absyn.Path path; + HashTableStringToPath.HashTable ht; + + case ({}, ht, _) then ht; + case (path::rest, ht, _) + equation + ht = getCalledFunctionsInFunction2(path, Absyn.pathStringNoQual(path), ht, funcs); + ht = getCalledFunctionsInFunctions(rest, ht, funcs); + then ht; + end match; +end getCalledFunctionsInFunctions; + +public function getCalledFunctionsInFunction2 "Goes through the given DAE, finds the given function and collects + the names of the functions called from within those functions" + input Absyn.Path inPath; + input String pathstr; + input HashTableStringToPath.HashTable inHt "paths to not add"; + input DAE.FunctionTree funcs; + output HashTableStringToPath.HashTable outHt "paths to not add"; +algorithm + outHt := matchcontinue (inPath, pathstr, inHt, funcs) + local + String str; + Absyn.Path path; + DAE.Function funcelem; + list calledfuncs, varfuncs; + list els; + HashTableStringToPath.HashTable ht; + + case (_, _, ht, _) + equation + BaseHashTable.get(pathstr, ht); + then ht; + + case (path, _, ht, _) + equation + funcelem = DAEUtil.getNamedFunction(path, funcs); + els = DAEUtil.getFunctionElements(funcelem); + // SimCode.Function reference variables are filtered out + varfuncs = List.fold(els, DAEUtil.collectFunctionRefVarPaths, {}); + (_, (_, varfuncs)) = DAEUtil.traverseDAE2(els, Expression.traverseSubexpressionsHelper, (DAEUtil.collectValueblockFunctionRefVars, varfuncs)); + (_, (_, (calledfuncs, _))) = DAEUtil.traverseDAE2(els, Expression.traverseSubexpressionsHelper, (matchNonBuiltinCallsAndFnRefPaths, ({}, varfuncs))); + ht = BaseHashTable.add((pathstr, path), ht); + ht = addDestructor(funcelem, ht); + ht = getCalledFunctionsInFunctions(calledfuncs, ht, funcs); + then ht; + + case (path, _, _, _) + equation + failure(_ = DAEUtil.getNamedFunction(path, funcs)); + str = "function getCalledFunctionsInFunction2: Class " + pathstr + " not found in global scope."; + Error.addInternalError(str, sourceInfo()); + then + fail(); + end matchcontinue; +end getCalledFunctionsInFunction2; + +protected function addDestructor + input DAE.Function func; + input HashTableStringToPath.HashTable inHt; + output HashTableStringToPath.HashTable outHt; +algorithm + outHt := match (func,inHt) + local + Absyn.Path path; + String pathstr; + case (DAE.FUNCTION(type_=DAE.T_FUNCTION(funcResultType=DAE.T_COMPLEX(complexClassType=ClassInf.EXTERNAL_OBJ(path=path)))),_) + equation + path = Absyn.joinPaths(path,Absyn.IDENT("destructor")); + then addDestructor2(path,Absyn.pathStringNoQual(path),inHt); + else inHt; + end match; +end addDestructor; + +protected function addDestructor2 + input Absyn.Path path; + input String pathstr; + input HashTableStringToPath.HashTable inHt; + output HashTableStringToPath.HashTable ht = inHt; +algorithm + if not BaseHashTable.hasKey(pathstr, ht) then + BaseHashTable.add((pathstr, path), ht); + end if; +end addDestructor2; + +protected function matchNonBuiltinCallsAndFnRefPaths "The extra argument is a tuple; the second list is the list of variable + names to filter out (so we don't add function references variables)" + input DAE.Exp inExp; + input tuple, list> itpl; + output DAE.Exp outExp; + output tuple, list> otpl; +algorithm + (outExp,otpl) := matchcontinue (inExp,itpl) + local + Absyn.Path path; + list acc, filter; + case (DAE.CALL(path = path, attr = DAE.CALL_ATTR(builtin = false)), (acc, filter)) + equation + path = Absyn.makeNotFullyQualified(path); + false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); + then (inExp, (path::acc, filter)); + case (DAE.REDUCTION(reductionInfo = DAE.REDUCTIONINFO(path = path)), (acc, filter)) + equation + false = List.isMemberOnTrue(path, {Absyn.IDENT("list"),Absyn.IDENT("listReverse"),Absyn.IDENT("array"),Absyn.IDENT("min"),Absyn.IDENT("max"),Absyn.IDENT("sum"),Absyn.IDENT("product")}, Absyn.pathEqual); + false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); + then (inExp, (path::acc, filter)); + case (DAE.PARTEVALFUNCTION(path = path), (acc, filter)) + equation + path = Absyn.makeNotFullyQualified(path); + false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); + then (inExp, (path::acc, filter)); + case (DAE.CREF(ty = DAE.T_FUNCTION_REFERENCE_FUNC(builtin = false)), (acc, filter)) + equation + path = Absyn.crefToPath(getCrefFromExp(inExp)); + false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); + then (inExp, (path::acc, filter)); + else (inExp,itpl); + end matchcontinue; +end matchNonBuiltinCallsAndFnRefPaths; +protected function aliasRecordDeclarations + input SimCode.RecordDeclaration inDecl; + input HashTableStringToPath.HashTable inHt; + output SimCode.RecordDeclaration decl; + output HashTableStringToPath.HashTable ht; +algorithm + (decl,ht) := match (inDecl,inHt) + local + list vars; + Absyn.Path name; + String str,sname; + Option alias; + case (SimCode.RECORD_DECL_FULL(sname, _, name, vars),_) + equation + str = stringDelimitList(List.map(vars, variableString), "\n"); + (alias,ht) = aliasRecordDeclarations2(str, name, inHt); + then (SimCode.RECORD_DECL_FULL(sname, alias, name, vars),ht); + else (inDecl,inHt); + end match; +end aliasRecordDeclarations; + +protected function aliasRecordDeclarations2 + input String str; + input Absyn.Path path; + input HashTableStringToPath.HashTable inHt; + output Option alias; + output HashTableStringToPath.HashTable ht; +algorithm + (alias,ht) := matchcontinue (str,path,inHt) + local + String aliasStr; + case (_,_,_) + equation + aliasStr = Absyn.pathStringUnquoteReplaceDot(BaseHashTable.get(str, inHt),"_"); + then (SOME(aliasStr),inHt); + else + equation + ht = BaseHashTable.add((str,path),inHt); + then (NONE(),ht); + end matchcontinue; +end aliasRecordDeclarations2; + +protected function variableString + input SimCode.Variable var; + output String str; +algorithm + str := match var + local + DAE.ComponentRef name; + DAE.Type ty; + case SimCode.VARIABLE(name=name, ty=ty) + then Types.unparseType(ty) + " " + ComponentReference.printComponentRefStr(name); + case SimCode.FUNCTION_PTR(name=str) + then "modelica_fnptr " + str; + end match; +end variableString; + +/****** HashTable ComponentRef -> SimCodeVar.SimVar ******/ +/* a workaround to enable "cross public import" */ + + +/* HashTable instance specific code */ + +protected function keyEqual + input SimCode.Key key1; + input SimCode.Key key2; + output Boolean res; +algorithm + res := ComponentReference.crefEqualNoStringCompare(key1, key2); +end keyEqual; + +/* end of HashTable instance specific code */ + +public function emptyHashTableSized " + author: PA + Returns an empty HashTable. + Using the bucketsize 100 and array size 10." + input Integer size; + output SimCode.HashTableCrefToSimVar hashTable; +protected + array>> arr; + list>> lst; + array>> emptyarr; + Integer szArr; +algorithm + arr := arrayCreate(size, {}); + emptyarr := arrayCreate(size, NONE()); + szArr:=realInt(realMul(intReal(size), 0.6)); + hashTable := SimCode.HASHTABLE(arr, SimCode.VALUE_ARRAY(0, szArr, emptyarr), size, 0); +end emptyHashTableSized; + +public function add " + author: PA + + Add a Key-Value tuple to hashtable. + If the Key-Value tuple already exists, the function updates the Value. +" + input tuple entry; + input SimCode.HashTableCrefToSimVar hashTable; + output SimCode.HashTableCrefToSimVar outHashTable; +algorithm + outHashTable := matchcontinue (entry, hashTable) + local + Integer indx, newpos, n, n_1, bsize, indx_1; + SimCode.ValueArray varr_1, varr; + list> indexes; + array>> hashvec_1, hashvec; + tuple v, newv; + SimCode.Key key; + SimCode.Value value; + /* Adding when not existing previously */ + case ((v as (key, _)), (SimCode.HASHTABLE(hashvec, varr, bsize, _))) + equation + failure((_) = get(key, hashTable)); + indx = ComponentReference.hashComponentRefMod(key,bsize); + newpos = valueArrayLength(varr); + varr_1 = valueArrayAdd(varr, v); + indexes = hashvec[indx + 1]; + hashvec_1 = arrayUpdate(hashvec, indx + 1, ((key, newpos) :: indexes)); + n_1 = valueArrayLength(varr_1); + then SimCode.HASHTABLE(hashvec_1, varr_1, bsize, n_1); + + /* adding when already present => Updating value */ + case ((newv as (key, _)), (SimCode.HASHTABLE(hashvec, varr, bsize, n))) + equation + (_, indx) = get1(key, hashTable); + // print("adding when present, indx =" );print(intString(indx));print("\n"); + varr_1 = valueArraySetnth(varr, indx, newv); + then SimCode.HASHTABLE(hashvec, varr_1, bsize, n); + case (_, _) + equation + print("- HashTableCrefToSimVar.add failed\n"); + then + fail(); + end matchcontinue; +end add; + +public function addNoUpdCheck " + author: PA + + Add a Key-Value tuple to hashtable. + If the Key-Value tuple already exists, the function updates the Value. +" + input tuple entry; + input SimCode.HashTableCrefToSimVar hashTable; + output SimCode.HashTableCrefToSimVar outHashTable; +algorithm + outHashTable := matchcontinue (entry, hashTable) + local + Integer hval, indx, newpos, n, n_1, bsize, indx_1; + SimCode.ValueArray varr_1, varr; + list> indexes; + array>> hashvec_1, hashvec; + String name_str; + tuple v, newv; + SimCode.Key key; + SimCode.Value value; + + // adding when not existing previously + case ((v as (key, _)), SimCode.HASHTABLE(hashvec, varr, bsize, _)) + equation + indx = ComponentReference.hashComponentRefMod(key,bsize); + newpos = valueArrayLength(varr); + varr_1 = valueArrayAdd(varr, v); + indexes = hashvec[indx + 1]; + hashvec_1 = arrayUpdate(hashvec, indx + 1, ((key, newpos) :: indexes)); + n_1 = valueArrayLength(varr_1); + then SimCode.HASHTABLE(hashvec_1, varr_1, bsize, n_1); + + // failure + else + equation + print("- HashTableCrefToSimVar.addNoUpdCheck failed\n"); + then + fail(); + end matchcontinue; +end addNoUpdCheck; + +public function get " +author: PA + + Returns a Value given a Key and a HashTable. +" + input SimCode.Key key; + input SimCode.HashTableCrefToSimVar hashTable; + output SimCode.Value value; +algorithm + (value, _):= get1(key, hashTable); +end get; + +protected function get1 "help function to get" + input SimCode.Key key; + input SimCode.HashTableCrefToSimVar hashTable; + output SimCode.Value value; + output Integer indx; +algorithm + (value, indx):= + match (key, hashTable) + local + Integer bsize, n; + list> indexes; + SimCode.Value v; + array>> hashvec; + SimCode.ValueArray varr; + SimCode.Key k; + case (_, (SimCode.HASHTABLE(hashvec, varr, bsize, _))) + equation + indx = ComponentReference.hashComponentRefMod(key,bsize); + indexes = hashvec[indx + 1]; + indx = get2(key, indexes); + (k, v) = valueArrayNth(varr, indx); + true = keyEqual(k, key); + then + (v, indx); + end match; +end get1; + +protected function get2 " + author: PA + + Helper function to get +" + input SimCode.Key key; + input list> keyIndices; + output Integer index; +algorithm + index := + matchcontinue (key, keyIndices) + local + SimCode.Key key2; + list> xs; + case (_, ((key2, index) :: _)) + equation + true = keyEqual(key, key2); + then + index; + case (_, (_ :: xs)) + equation + index = get2(key, xs); + then + index; + end matchcontinue; +end get2; + +public function valueArrayLength " + author: PA + + Returns the number of elements in the ValueArray +" + input SimCode.ValueArray valueArray; + output Integer size; +algorithm + size := match (valueArray) + case (SimCode.VALUE_ARRAY(numberOfElements = size)) then size; + end match; +end valueArrayLength; + +public function valueArrayAdd "author: PA + Adds an entry last to the ValueArray, increasing array size + if no space left by factor 1.4 +" + input SimCode.ValueArray valueArray; + input tuple entry; + output SimCode.ValueArray outValueArray; +algorithm + outValueArray:= + matchcontinue (valueArray, entry) + local + Integer n_1, n, size, expandsize, expandsize_1, newsize; + array>> arr_1, arr, arr_2; + Real rsize, rexpandsize; + case (SimCode.VALUE_ARRAY(numberOfElements = n, arrSize = size, valueArray = arr), _) + equation + (n < size) = true "Have space to add array elt."; + n_1 = n + 1; + arr_1 = arrayUpdate(arr, n + 1, SOME(entry)); + then + SimCode.VALUE_ARRAY(n_1, size, arr_1); + + case (SimCode.VALUE_ARRAY(numberOfElements = n, arrSize = size, valueArray = arr), _) + equation + (n < size) = false "Do NOT have splace to add array elt. Expand with factor 1.4"; + rsize = intReal(size); + rexpandsize = rsize * 0.4; + expandsize = realInt(rexpandsize); + expandsize_1 = intMax(expandsize, 1); + newsize = expandsize_1 + size; + arr_1 = Array.expand(expandsize_1, arr, NONE()); + n_1 = n + 1; + arr_2 = arrayUpdate(arr_1, n + 1, SOME(entry)); + then + SimCode.VALUE_ARRAY(n_1, newsize, arr_2); + case (_, _) + equation + print("-HashTableCrefToSimVar.valueArrayAdd failed\n"); + then + fail(); + end matchcontinue; +end valueArrayAdd; + +public function valueArraySetnth "author: PA + Set the n:th variable in the ValueArray to value. +" + input SimCode.ValueArray valueArray; + input Integer pos; + input tuple entry; + output SimCode.ValueArray outValueArray; +algorithm + outValueArray:= + matchcontinue (valueArray, pos, entry) + local + array>> arr_1, arr; + Integer n, size; + case (SimCode.VALUE_ARRAY(n, size, arr), _, _) + equation + (pos < size) = true; + arr_1 = arrayUpdate(arr, pos + 1, SOME(entry)); + then + SimCode.VALUE_ARRAY(n, size, arr_1); + case (_, _, _) + equation + print("-HashTableCrefToSimVar.valueArraySetnth failed\n"); + then + fail(); + end matchcontinue; +end valueArraySetnth; + +public function valueArrayNth "author: PA + + Retrieve the n:th Vale from ValueArray, index from 0..n-1. + " + input SimCode.ValueArray valueArray; + input Integer pos; + output SimCode.Key key; + output SimCode.Value value; +algorithm + (key, value) := + matchcontinue (valueArray, pos) + local + SimCode.Key k; + SimCode.Value v; + Integer n; + array>> arr; + case (SimCode.VALUE_ARRAY(numberOfElements = n, valueArray = arr), _) + equation + (pos < n) = true; + SOME((k, v)) = arr[pos + 1]; + then + (k, v); + case (SimCode.VALUE_ARRAY(numberOfElements = n, valueArray = arr), _) + equation + (pos < n) = true; + NONE() = arr[pos + 1]; + then + fail(); + end matchcontinue; +end valueArrayNth; + +/***** end of HashTable ComponentRef -> SimCodeVar.SimVar *******/ + +public function createMakefileParams + input list includes; + input list libs; + input list libPaths; + input Boolean isFunction; + output SimCode.MakefileParams makefileParams; +protected + String omhome, ccompiler, cxxcompiler, linker, exeext, dllext, cflags, ldflags, rtlibs, platform, fopenmp,compileDir; +algorithm + ccompiler := if stringEq(Config.simCodeTarget(),"JavaScript") then "emcc" else + (if Flags.isSet(Flags.HPCOM) then System.getOMPCCompiler() else System.getCCompiler()); + cxxcompiler := if stringEq(Config.simCodeTarget(),"JavaScript") then "emcc" else System.getCXXCompiler(); + linker := if stringEq(Config.simCodeTarget(),"JavaScript") then "emcc" else System.getLinker(); + exeext := if stringEq(Config.simCodeTarget(),"JavaScript") then ".js" else System.getExeExt(); + dllext := System.getDllExt(); + omhome := Settings.getInstallationDirectoryPath(); + omhome := System.trim(omhome, "\""); // Remove any quotation marks from omhome. + cflags := System.getCFlags() + " " + + (if Flags.isSet(Flags.HPCOM) then "-fopenmp" else ""); + cflags := if stringEq(Config.simCodeTarget(),"JavaScript") then "-Os -Wno-warn-absolute-paths" else cflags; + ldflags := System.getLDFlags(); + rtlibs := if isFunction then System.getRTLibs() else System.getRTLibsSim(); + platform := System.modelicaPlatform(); + compileDir := System.pwd() + System.pathDelimiter(); + makefileParams := SimCode.MAKEFILE_PARAMS(ccompiler, cxxcompiler, linker, exeext, dllext, + omhome, cflags, ldflags, rtlibs, includes, libs,libPaths, platform,compileDir); +end createMakefileParams; + +public + +function codegenResetTryThrowIndex +algorithm + setGlobalRoot(Global.codegenTryThrowIndex, {}); +end codegenResetTryThrowIndex; + +function codegenPushTryThrowIndex + input Integer i; +protected + list lst; +algorithm + lst := getGlobalRoot(Global.codegenTryThrowIndex); + setGlobalRoot(Global.codegenTryThrowIndex, i::lst); +end codegenPushTryThrowIndex; + +function codegenPopTryThrowIndex +protected + list lst; +algorithm + lst := getGlobalRoot(Global.codegenTryThrowIndex); + _::lst := lst; + setGlobalRoot(Global.codegenTryThrowIndex, lst); +end codegenPopTryThrowIndex; + +function codegenPeekTryThrowIndex + output Integer i; +protected + list lst; +algorithm + lst := getGlobalRoot(Global.codegenTryThrowIndex); + i := match lst + case i::_ then i; + else -1; + end match; +end codegenPeekTryThrowIndex; + +public function execStat + "Prints an execution stat on the format: + *** %name% -> time: %time%, memory %memory% + Where you provide name, and time is the time since the last call using this + index (the clock is reset after each call). The memory is the total memory + consumed by the compiler at this point in time. + " + input String name; +algorithm + execStat2(Flags.isSet(Flags.EXEC_STAT),name); +end execStat; + +protected function execStat2 + input Boolean cond; + input String name; +algorithm + _ := match (cond,name) + local + Real t,total,used,allocated; + String timeStr,totalTimeStr,gcStr; + case (false,_) then (); + else + equation + t = System.realtimeTock(ClockIndexes.RT_CLOCK_EXECSTAT); + total = System.realtimeTock(ClockIndexes.RT_CLOCK_EXECSTAT_CUMULATIVE); + gcStr = GC.profStatsStr(GC.getProfStats(), head=""); + timeStr = System.snprintff("%.4g",20,t); + totalTimeStr = System.snprintff("%.4g",20,total); + if Flags.isSet(Flags.GC_PROF) then + Error.addMessage(Error.EXEC_STAT_GC,{name,timeStr,totalTimeStr,gcStr}); + else + Error.addMessage(Error.EXEC_STAT,{name,timeStr,totalTimeStr}); + end if; + System.realtimeTick(ClockIndexes.RT_CLOCK_EXECSTAT); + then (); + end match; +end execStat2; + +public function varIndex + input SimCodeVar.SimVar var; + output Integer index; +algorithm + SimCodeVar.SIMVAR(index=index) := var; +end varIndex; + +public function varName + input SimCodeVar.SimVar var; + output DAE.ComponentRef name; +algorithm + SimCodeVar.SIMVAR(name=name) := var; +end varName; + +public function isParallelFunctionContext + input SimCode.Context context; + output Boolean outBool; +algorithm + outBool := match(context) + case (SimCode.PARALLEL_FUNCTION_CONTEXT()) then true; + else false; + end match; +end isParallelFunctionContext; + +function twodigit + input Integer i; + output String outS; +algorithm + outS := + matchcontinue (i) + local String s; + case _ + equation + (i < 10) = true; + s = intString(i); + s = stringAppend("0", s); + then + s; + else intString(i); + end matchcontinue; +end twodigit; + +public function generateSubPalceholders + input DAE.ComponentRef cr; + output String outdef; +protected + list dims; + Integer nrdims; + list idxstrlst; +algorithm + dims := ComponentReference.crefDims(cr); + nrdims := listLength(dims); + idxstrlst := List.map(List.intRange(nrdims),intString); + outdef := stringDelimitList(List.threadMap(List.fill("i_", nrdims), idxstrlst, stringAppend), ","); +end generateSubPalceholders; + +annotation(__OpenModelica_Interface="backend"); +end SimCodeFunctionUtil; diff --git a/Compiler/SimCode/SimCodeMain.mo b/Compiler/SimCode/SimCodeMain.mo index dbc2724483e..8eae968104a 100644 --- a/Compiler/SimCode/SimCodeMain.mo +++ b/Compiler/SimCode/SimCodeMain.mo @@ -49,7 +49,6 @@ import DAE; import FCore; import GlobalScript; import HashTableExpToIndex; -import HashTableStringToPath; import Tpl; import Values; import SimCode; @@ -58,7 +57,6 @@ import SimCode; protected import BackendDAECreate; import BackendQSS; -import BaseHashTable; import ClockIndexes; import CevalScript; import CodegenC; @@ -147,7 +145,7 @@ algorithm (simCode,_) := SimCodeUtil.createSimCode(outIndexedBackendDAE, className, filenamePrefix, fileDir, functions, includes, includeDirs, libs, libPaths,simSettingsOpt, recordDecls, literals,Absyn.FUNCTIONARGS({},{})); timeSimCode := System.realtimeTock(ClockIndexes.RT_CLOCK_SIMCODE); - SimCodeUtil.execStat("SimCode"); + SimCodeFunctionUtil.execStat("SimCode"); System.realtimeTick(ClockIndexes.RT_CLOCK_TEMPLATES); callTargetTemplatesFMU(simCode, Config.simCodeTarget(), FMUVersion, FMUType); @@ -188,7 +186,7 @@ algorithm (simCode,_) := SimCodeUtil.createSimCode(outIndexedBackendDAE, className, filenamePrefix, fileDir, functions, includes, includeDirs, libs,libPaths, simSettingsOpt, recordDecls, literals,Absyn.FUNCTIONARGS({},{})); timeSimCode := System.realtimeTock(ClockIndexes.RT_CLOCK_SIMCODE); - SimCodeUtil.execStat("SimCode"); + SimCodeFunctionUtil.execStat("SimCode"); System.realtimeTick(ClockIndexes.RT_CLOCK_TEMPLATES); callTargetTemplatesXML(simCode, Config.simCodeTarget()); @@ -388,12 +386,12 @@ algorithm (libs, libPaths,includes, includeDirs, recordDecls, functions, outIndexedBackendDAE, _, literals) := SimCodeUtil.createFunctions(p, dae, inBackendDAE, className); simCode := createSimCode(outIndexedBackendDAE, className, filenamePrefix, fileDir, functions, includes, includeDirs, libs,libPaths, simSettingsOpt, recordDecls, literals, args); timeSimCode := System.realtimeTock(ClockIndexes.RT_CLOCK_SIMCODE); - SimCodeUtil.execStat("SimCode"); + SimCodeFunctionUtil.execStat("SimCode"); System.realtimeTick(ClockIndexes.RT_CLOCK_TEMPLATES); callTargetTemplates(simCode, inBackendDAE, Config.simCodeTarget()); timeTemplates := System.realtimeTock(ClockIndexes.RT_CLOCK_TEMPLATES); - SimCodeUtil.execStat("Templates"); + SimCodeFunctionUtil.execStat("Templates"); end generateModelCode; protected function createSimCode " @@ -633,12 +631,12 @@ algorithm System.realtimeTick(ClockIndexes.RT_CLOCK_EXECSTAT); System.realtimeTick(ClockIndexes.RT_CLOCK_EXECSTAT_CUMULATIVE); (cache, graph, dae, st) = CevalScript.runFrontEnd(cache, graph, className, st, false); - SimCodeUtil.execStat("FrontEnd"); + SimCodeFunctionUtil.execStat("FrontEnd"); timeFrontend = System.realtimeTock(ClockIndexes.RT_CLOCK_FRONTEND); System.realtimeTick(ClockIndexes.RT_CLOCK_BACKEND); dae = DAEUtil.transformationsBeforeBackend(cache, graph, dae); - SimCodeUtil.execStat("Transformations before backend"); + SimCodeFunctionUtil.execStat("Transformations before backend"); description = DAEUtil.daeDescription(dae); dlow = BackendDAECreate.lower(dae, cache, graph, BackendDAE.EXTRA_INFO(description,filenameprefix)); //BackendDump.printBackendDAE(dlow); @@ -663,137 +661,5 @@ algorithm end matchcontinue; end translateModel; -public function translateFunctions " - Entry point to translate Modelica/MetaModelica functions to C functions. - Called from other places in the compiler." - input Absyn.Program program; - input String name; - input Option optMainFunction; - input list idaeElements; - input list metarecordTypes; - input list inIncludes; -algorithm - _ := match (program, name, optMainFunction, idaeElements, metarecordTypes, inIncludes) - local - DAE.Function daeMainFunction; - SimCode.Function mainFunction; - list fns; - list includes, libs, libPaths,includeDirs; - SimCode.MakefileParams makefileParams; - SimCode.FunctionCode fnCode; - list extraRecordDecls; - list literals; - list daeElements; - - case (_, _, SOME(daeMainFunction), daeElements, _, includes) - equation - // Create SimCode.FunctionCode - (daeElements,literals) = SimCodeUtil.findLiterals(daeMainFunction::daeElements); - (mainFunction::fns, extraRecordDecls, includes, includeDirs, libs,libPaths) = SimCodeUtil.elaborateFunctions(program, daeElements, metarecordTypes, literals, includes); - SimCodeUtil.checkValidMainFunction(name, mainFunction); - makefileParams = SimCodeUtil.createMakefileParams(includeDirs, libs,libPaths, true); - fnCode = SimCode.FUNCTIONCODE(name, SOME(mainFunction), fns, literals, includes, makefileParams, extraRecordDecls); - // Generate code - _ = Tpl.tplString(CodegenC.translateFunctions, fnCode); - then - (); - case (_, _, NONE(), daeElements, _, includes) - equation - // Create SimCode.FunctionCode - (daeElements,literals) = SimCodeUtil.findLiterals(daeElements); - (fns, extraRecordDecls, includes, includeDirs, libs,libPaths) = SimCodeUtil.elaborateFunctions(program, daeElements, metarecordTypes, literals, includes); - makefileParams = SimCodeUtil.createMakefileParams(includeDirs, libs,libPaths, true); - // remove OpenModelica.threadData.ThreadData - fns = removeThreadDataFunction(fns, {}); - extraRecordDecls = removeThreadDataRecord(extraRecordDecls, {}); - - fnCode = SimCode.FUNCTIONCODE(name, NONE(), fns, literals, includes, makefileParams, extraRecordDecls); - // Generate code - _ = Tpl.tplString(CodegenC.translateFunctions, fnCode); - then - (); - end match; -end translateFunctions; - -protected function removeThreadDataRecord -"remove OpenModelica.threadData.ThreadData - as is already defined in openmodelica.h" - input list inRecs; - input list inAcc; - output list outRecs; -algorithm - outRecs := match(inRecs, inAcc) - local - Absyn.Path p; - list acc, rest; - SimCode.RecordDeclaration r; - - case ({}, _) then listReverse(inAcc); - - case (SimCode.RECORD_DECL_FULL(name = "OpenModelica_threadData_ThreadData")::rest, _) - equation - acc = removeThreadDataRecord(rest, inAcc); - then - acc; - - case (SimCode.RECORD_DECL_DEF(path = Absyn.QUALIFIED("OpenModelica",Absyn.QUALIFIED("threadData",Absyn.IDENT("ThreadData"))))::rest, _) - equation - acc = removeThreadDataRecord(rest, inAcc); - then - acc; - - case (r::rest, _) - equation - acc = removeThreadDataRecord(rest, r::inAcc); - then - acc; - - end match; -end removeThreadDataRecord; - -protected function removeThreadDataFunction -"remove OpenModelica.threadData.ThreadData - as is already defined in openmodelica.h" - input list inFuncs; - input list inAcc; - output list outFuncs; -algorithm - outFuncs := match(inFuncs, inAcc) - local - Absyn.Path p; - list acc, rest; - SimCode.Function f; - - case ({}, _) then listReverse(inAcc); - - case (SimCode.RECORD_CONSTRUCTOR(name = Absyn.FULLYQUALIFIED(Absyn.QUALIFIED("OpenModelica",Absyn.QUALIFIED("threadData",Absyn.IDENT("ThreadData")))))::rest, _) - equation - acc = removeThreadDataFunction(rest, inAcc); - then - acc; - - case (f::rest, _) - equation - acc = removeThreadDataFunction(rest, f::inAcc); - then - acc; - - end match; -end removeThreadDataFunction; - -public function getCalledFunctionsInFunction -"Goes through the given DAE, finds the given function and collects - the names of the functions called from within those functions" - input Absyn.Path path; - input DAE.FunctionTree funcs; - output list outPaths; -protected - HashTableStringToPath.HashTable ht; -algorithm - ht := HashTableStringToPath.emptyHashTable(); - ht := SimCodeUtil.getCalledFunctionsInFunction2(path,Absyn.pathStringNoQual(path),ht,funcs); - outPaths := BaseHashTable.hashTableValueList(ht); -end getCalledFunctionsInFunction; - annotation(__OpenModelica_Interface="backend"); end SimCodeMain; diff --git a/Compiler/SimCode/SimCodeUtil.mo b/Compiler/SimCode/SimCodeUtil.mo index 5f8f92013c9..7df8a02f41c 100644 --- a/Compiler/SimCode/SimCodeUtil.mo +++ b/Compiler/SimCode/SimCodeUtil.mo @@ -100,379 +100,14 @@ import Mod; import PriorityQueue; import Settings; import SimCodeDump; +import SimCodeFunctionUtil; +import SimCodeFunctionUtil.{execStat,varName}; import SymbolicJacobian; import System; import Util; import ValuesUtil; import VisualXML; -// ============================================================================= -// section for public function for SimCodeTV -// -// ============================================================================= - -public function elementVars -"Used by templates to get a list of variables from a valueblock." - input list ild; - output list vars; -protected - list ld; -algorithm - ld := List.filter(ild, isVarQ); - vars := List.map(ld, daeInOutSimVar); -end elementVars; - -public function crefSubIsScalar -"Used by templates to determine if a component reference's subscripts are - scalar." - input DAE.ComponentRef cref; - output Boolean isScalar; -protected - list subs; -algorithm - subs := ComponentReference.crefSubs(cref); - isScalar := subsToScalar(subs); -end crefSubIsScalar; - -public function crefNoSub -"Used by templates to determine if a component reference has no subscripts." - input DAE.ComponentRef cref; - output Boolean noSub; -algorithm - noSub := not ComponentReference.crefHaveSubs(cref); -end crefNoSub; - -public function inFunctionContext - input SimCode.Context inContext; - output Boolean outInFunction; -algorithm - outInFunction := match inContext - case SimCode.FUNCTION_CONTEXT() then true; - case SimCode.PARALLEL_FUNCTION_CONTEXT() then true; - else false; - end match; -end inFunctionContext; - -public function crefIsScalar - "Whether a component reference is a scalar depends on what context we are in. - If we are generating code for a function, then only crefs without subscripts - are scalar. If we are generating code for simulation though, then crefs with - only constant subscripts are also scalars, since a variable is generated for - each element of an array in the model." - input DAE.ComponentRef cref; - input SimCode.Context context; - output Boolean isScalar; -algorithm - if inFunctionContext(context) then - isScalar := listEmpty(ComponentReference.crefLastSubs(cref)); - else - isScalar := ComponentReference.crefHasScalarSubscripts(cref); - end if; -end crefIsScalar; - -public function buildCrefExpFromAsub -"Used by templates to convert an ASUB expression to a component reference - with subscripts." - input DAE.Exp cref; - input list subs; - output DAE.Exp cRefOut; -algorithm - cRefOut := matchcontinue(cref, subs) - local - DAE.Exp crefExp; - DAE.Type ty; - DAE.ComponentRef crNew; - list indexes; - - case (_, {}) then cref; - case (DAE.CREF(componentRef=crNew, ty=ty), _) - equation - indexes = List.map(subs, Expression.makeIndexSubscript); - crNew = ComponentReference.subscriptCref(crNew, indexes); - crefExp = Expression.makeCrefExp(crNew, ty); - then - crefExp; - end matchcontinue; -end buildCrefExpFromAsub; - -public function incrementInt -"Used by templates to create new integers that are increments of another." - input Integer inInt; - input Integer increment; - output Integer outInt; -algorithm - outInt := inInt + increment; -end incrementInt; - -public function decrementInt -"Used by templates to create new integers that are increments of another." - input Integer inInt; - input Integer decrement; - output Integer outInt; -algorithm - outInt := inInt - decrement; -end decrementInt; - - -public function protectedVars - input list InSimVars; - output list OutSimVars; - algorithm - OutSimVars:= List.filterOnTrue(InSimVars,isNotProtected); -end protectedVars; - -protected function isNotProtected - input SimCodeVar.SimVar simVar; - output Boolean isProtected; -algorithm - SimCodeVar.SIMVAR(isProtected=isProtected) := simVar; - isProtected := not isProtected; -end isNotProtected; - - -public function makeCrefRecordExp -"Helper function to generate records." - input DAE.ComponentRef inCRefRecord; - input DAE.Var inVar; - output DAE.Exp outExp; -algorithm - outExp := match (inCRefRecord, inVar) - local - DAE.ComponentRef cr, cr1; - String name; - DAE.Type tp; - case (cr, DAE.TYPES_VAR(name=name, ty=tp)) - equation - cr1 = ComponentReference.crefPrependIdent(cr, name, {}, tp); - outExp = Expression.makeCrefExp(cr1, tp); - then - outExp; - end match; -end makeCrefRecordExp; - -public function cref2simvar -"Used by templates to find SIMVAR for given cref (to gain representaion index info mainly)." - input DAE.ComponentRef inCref; - input SimCode.SimCode simCode; - output SimCodeVar.SimVar outSimVar; -algorithm - outSimVar := matchcontinue(inCref, simCode) - local - DAE.ComponentRef cref, badcref; - SimCodeVar.SimVar sv; - SimCode.HashTableCrefToSimVar crefToSimVarHT; - String errstr; - - case (cref, SimCode.SIMCODE(crefToSimVarHT = crefToSimVarHT) ) - equation - sv = get(cref, crefToSimVarHT); - then sv; - - case (_, _) - equation - //print("cref2simvar: " + ComponentReference.printComponentRefStr(inCref) + " not found!\n"); - badcref = ComponentReference.makeCrefIdent("ERROR_cref2simvar_failed", DAE.T_REAL_DEFAULT, {}); - /* Todo: This also generates an error for example itearation variables, so i commented out - "Template did not find the simulation variable for "+ ComponentReference.printComponentRefStr(cref) + ". "; - Error.addInternalError(errstr, sourceInfo());*/ - then - SimCodeVar.SIMVAR(badcref, BackendDAE.VARIABLE(), "", "", "", -2, NONE(), NONE(), NONE(), NONE(), false, DAE.T_REAL_DEFAULT, false, NONE(), SimCodeVar.NOALIAS(), DAE.emptyElementSource, SimCodeVar.INTERNAL(), NONE(), {}, false, true); - end matchcontinue; -end cref2simvar; - -public function isModelTooBigForCSharpInOneFile -"Used by C# template to determine if the generated code should be split into several files - to make Visual Studio responsive when the file is opened (C# compiler is OK, - but VS does not scale well for big C# files)." - input SimCode.SimCode simCode; - output Boolean outIsTooBig; -algorithm - outIsTooBig := match(simCode) - local - Integer numAlgVars; - - case (SimCode.SIMCODE(modelInfo = SimCode.MODELINFO(varInfo = SimCode.VARINFO(numAlgVars = numAlgVars)))) - equation - outIsTooBig = numAlgVars > 1000; - then outIsTooBig; - - end match; -end isModelTooBigForCSharpInOneFile; - -public function derComponentRef -"Used by templates to derrive a cref in a der(cref) expression. - Particularly, this function is called for the C# code generator, - while for C/C++, it is solved by prefixing the cref with '$P$DER' in daeExpCall() template. - The prefixing technique is not usable for C#, because there is no macroprocessor in C#. - TODO: all der(cref) expressions should be eliminated before the expressions enter templates - to pull this logic (and this function) out of templates." - input DAE.ComponentRef inCref; - output DAE.ComponentRef derCref; -algorithm - derCref := ComponentReference.crefPrefixDer(inCref); -end derComponentRef; - -public function hackArrayReverseToCref -"This is a hack transformation of an expanded array back to its cref. -It is used in daeExpArray() (for C# yet) to optimize the generated code. -TODO: This function should not exist! -Rather the array should not be let expanded when SimCode is entering templates. -" - input DAE.Exp inExp; - input SimCode.Context context; - output DAE.Exp outExp; -algorithm - outExp := matchcontinue (inExp, context) - local - list aRest; - DAE.ComponentRef cr; - DAE.Type aty; - DAE.Exp crefExp; - - case(DAE.ARRAY(ty=aty, scalar=true, array =(DAE.CREF(componentRef=cr) ::aRest)), _) - equation - failure(SimCode.FUNCTION_CONTEXT()=context); // only in the function context - failure(SimCode.PARALLEL_FUNCTION_CONTEXT()=context); // only in the function context - { DAE.INDEX(DAE.ICONST(1)) } = ComponentReference.crefLastSubs(cr); - cr = ComponentReference.crefStripLastSubs(cr); - true = isArrayExpansion(aRest, cr, 2); - crefExp = Expression.makeCrefExp(cr, aty); - then - crefExp; - - else inExp; - - end matchcontinue; -end hackArrayReverseToCref; - -protected function isArrayExpansion -"Helper funtion to hackArrayReverseToCref." - input list inArrayElems; - input DAE.ComponentRef inCref; - input Integer index; - output Boolean isExpanded; -algorithm - isExpanded := matchcontinue(inArrayElems, inCref, index) - local - list aRest; - Integer i; - DAE.ComponentRef cr; - case({}, _, _) then true; - case (DAE.CREF(componentRef=cr) :: aRest, _, _) - equation - { DAE.INDEX(DAE.ICONST(i)) } = ComponentReference.crefLastSubs(cr); - true = (i == index); - cr = ComponentReference.crefStripLastSubs(cr); - true = ComponentReference.crefEqualNoStringCompare(inCref, cr); - then isArrayExpansion(aRest, inCref, index+1); - else false; - end matchcontinue; -end isArrayExpansion; - -public function hackMatrixReverseToCref -"This is a hack transformation of an expanded matrix back to its cref. -It is used in daeExpMatrix() (for C# yet) to optimize the generated code. -TODO: This function should not exist! -Rather the matrix should not be let expanded when SimCode is entering templates -" - input DAE.Exp inExp; - input SimCode.Context context; - output DAE.Exp outExp; -algorithm - outExp := matchcontinue (inExp, context) - local - DAE.ComponentRef cr; - DAE.Type aty; - list> rows; - DAE.Exp crefExp; - - case(DAE.MATRIX(ty=aty, matrix = rows as (((DAE.CREF(componentRef=cr))::_)::_) ), _) - equation - failure(SimCode.FUNCTION_CONTEXT()=context); - failure(SimCode.PARALLEL_FUNCTION_CONTEXT()=context); // only in the function context - { DAE.INDEX(DAE.ICONST(1)), DAE.INDEX(DAE.ICONST(1)) } = ComponentReference.crefLastSubs(cr); - cr = ComponentReference.crefStripLastSubs(cr); - true = isMatrixExpansion(rows, cr, 1, 1); - crefExp = Expression.makeCrefExp(cr, aty); - then - crefExp; - - else inExp; - - end matchcontinue; -end hackMatrixReverseToCref; - -protected function isMatrixExpansion -"Helper funtion to hackMatrixReverseToCref." - input list> rows; - input DAE.ComponentRef inCref; - input Integer rowIndex; - input Integer colIndex; - output Boolean isExpanded; -algorithm - isExpanded := matchcontinue(rows, inCref, rowIndex, colIndex) - local - list> restRows; - list restElems; - Integer r, c; - DAE.ComponentRef cr; - case({}, _, _, _) then true; - case({} :: restRows, _, _, _) then isMatrixExpansion(restRows, inCref, rowIndex+1, 1); - case ( (DAE.CREF(componentRef=cr) :: restElems) :: restRows, _, _, _) - equation - { DAE.INDEX(DAE.ICONST(r)), DAE.INDEX(DAE.ICONST(c)) } = ComponentReference.crefLastSubs(cr); - true = (r == rowIndex) and (c == colIndex); - cr = ComponentReference.crefStripLastSubs(cr); - true = ComponentReference.crefEqualNoStringCompare(inCref, cr); - then isMatrixExpansion(restElems :: restRows, inCref, rowIndex, colIndex+1); - else false; - end matchcontinue; -end isMatrixExpansion; - -public function hackGetFirstExternalFunctionLib -"This is a hack to get the original library name given to an external function. -TODO: redesign OMC and Modelica specification so they are not so C/C++ centric." - input list libs; - output String outFirstLib; -algorithm - outFirstLib := matchcontinue (libs) - local - String lib; - - case _ - equation - lib = List.last(libs); - lib = System.stringReplace(lib, "-l", ""); - then - lib; - - else "NO_LIB"; - - end matchcontinue; -end hackGetFirstExternalFunctionLib; - -public function createAssertforSqrt - input DAE.Exp inExp; - output DAE.Exp outExp; -algorithm - outExp := - match (inExp) - case(_) - equation - // Simplify things like abs(exp) >= 0 to exp - (outExp, _) = ExpressionSimplify.simplify(DAE.RELATION(inExp, DAE.GREATEREQ(DAE.T_REAL_DEFAULT), DAE.RCONST(0.0), -1, NONE())); - then outExp; - end match; -end createAssertforSqrt; - -public function createDAEString - input String inString; - output DAE.Exp outExp; - annotation(__OpenModelica_EarlyInline = true); -algorithm - outExp := DAE.SCONST(inString); -end createDAEString; - public function appendLists input list inEqn1; input list inEqn2; @@ -483,743 +118,18 @@ end appendLists; protected function compareEqSystems input SimCode.SimEqSystem eq1; - input SimCode.SimEqSystem eq2; - output Boolean b; -algorithm - b := simEqSystemIndex(eq1) > simEqSystemIndex(eq2); -end compareEqSystems; - -public function sortEqSystems - input list eqs; - output list outEqs; -algorithm - outEqs := List.sort(eqs,compareEqSystems); -end sortEqSystems; - -/** end of TypeView published functions **/ - -// ============================================================================= -// section to generate SimCode from functions -// -// Finds the called functions in BackendDAE and transforms them to a list of -// libraries and a list of SimCode.Function uniontypes. -// ============================================================================= - -public function createFunctions - input Absyn.Program inProgram; - input DAE.DAElist inDAElist; - input BackendDAE.BackendDAE inBackendDAE; - input Absyn.Path inPath; - output list libs; - output list libPaths; - output list includes; - output list includeDirs; - output list recordDecls; - output list functions; - output BackendDAE.BackendDAE outBackendDAE; - output DAE.DAElist outDAE; - output tuple> literals; -algorithm - (libs,libPaths, includes, includeDirs, recordDecls, functions, outBackendDAE, outDAE, literals) := - matchcontinue (inProgram, inDAElist, inBackendDAE, inPath) - local - list libs2,libpaths2, includes2, includeDirs2; - list funcelems, part_func_elems, recFuncs; - DAE.DAElist dae; - BackendDAE.BackendDAE dlow; - DAE.FunctionTree functionTree; - Absyn.Path path; - list fns; - list lits; - - case (_, dae, dlow as BackendDAE.DAE(shared=BackendDAE.SHARED(functionTree=functionTree)), _) - equation - // get all the used functions from the function tree - funcelems = DAEUtil.getFunctionList(functionTree); - funcelems = setRecordVariability(funcelems,inBackendDAE); - funcelems = Inline.inlineCallsInFunctions(funcelems, (NONE(), {DAE.NORM_INLINE(), DAE.AFTER_INDEX_RED_INLINE()}), {}); - (funcelems, literals as (_, _, lits)) = simulationFindLiterals(dlow, funcelems); - (fns, recordDecls, includes2, includeDirs2, libs2,libpaths2) = elaborateFunctions(inProgram, funcelems, {}, lits, {}); // Do we need metarecords here as well? - then - (libs2, libpaths2,includes2, includeDirs2, recordDecls, fns, dlow, dae, literals); - else - equation - Error.addInternalError("Creation of Modelica functions failed.", sourceInfo()); - then - fail(); - end matchcontinue; -end createFunctions; - -protected function orderRecordDecls - input SimCode.RecordDeclaration decl1; - input SimCode.RecordDeclaration decl2; - output Boolean b; -algorithm - b := match (decl1,decl2) - local - Absyn.Path path1,path2; - case (SimCode.RECORD_DECL_DEF(path=path1),SimCode.RECORD_DECL_DEF(path=path2)) then Absyn.pathGe(path1,path2); - else true; - end match; -end orderRecordDecls; - -public function elaborateFunctions - input Absyn.Program program; - input list daeElements; - input list metarecordTypes; - input list literals; - input list includes; - output list functions; - output list extraRecordDecls; - output list outIncludes; - output list includeDirs; - output list libs; - output list libpaths; -protected - list fns; - list outRecordTypes; - HashTableStringToPath.HashTable ht; - list>> g; -algorithm - (extraRecordDecls, outRecordTypes) := elaborateRecordDeclarationsForMetarecords(literals, {}, {}); - (functions, outRecordTypes, extraRecordDecls, outIncludes, includeDirs, libs,libpaths) := elaborateFunctions2(program, daeElements, {}, outRecordTypes, extraRecordDecls, includes, {}, {},{}); - extraRecordDecls := List.unique(extraRecordDecls); - (extraRecordDecls, _) := elaborateRecordDeclarationsFromTypes(metarecordTypes, extraRecordDecls, outRecordTypes); - extraRecordDecls := List.sort(extraRecordDecls, orderRecordDecls); - ht := HashTableStringToPath.emptyHashTableSized(BaseHashTable.lowBucketSize); - (extraRecordDecls,_) := List.mapFold(extraRecordDecls, aliasRecordDeclarations, ht); - // Topological sort since we have no guarantees in the order of generated records - g := Graph.buildGraph(extraRecordDecls, getRecordDependencies, extraRecordDecls); - (extraRecordDecls, {}) := Graph.topologicalSort(g, isRecordDeclEqual); -end elaborateFunctions; - -protected function getRecordDependencies - input SimCode.RecordDeclaration decl; - input list allDecls; - output list dependencies; -algorithm - dependencies := match (decl,allDecls) - local - String name; - list vars; - list tys; - list> tyss; - case (SimCode.RECORD_DECL_FULL(aliasName=SOME(name)),_) - then List.select1(allDecls, isRecordDecl, name); - case (SimCode.RECORD_DECL_FULL(variables=vars),_) - equation - tys = List.map(vars, getVarType); - tyss = List.map1(tys, Types.getAllInnerTypesOfType, Util.anyReturnTrue); - tys = List.flatten(tyss); - dependencies = List.filterMap1(tys, getRecordDependenciesFromType, allDecls); - then List.unique(dependencies); - else {}; - end match; -end getRecordDependencies; - -protected function getVarType - input SimCode.Variable var; - output DAE.Type ty; -algorithm - ty := match var - case SimCode.VARIABLE(ty=ty) then ty; - else DAE.T_ANYTYPE_DEFAULT; - end match; -end getVarType; - -protected function getRecordDependenciesFromType - input DAE.Type ty; - input list allDecls; - output SimCode.RecordDeclaration decl; -protected - Absyn.Path path; - String name; -algorithm - DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path)) := ty; - name := Absyn.pathStringUnquoteReplaceDot(path, "_"); - decl := List.selectFirst1(allDecls, isRecordDecl, name); -end getRecordDependenciesFromType; - -protected function isRecordDecl - input SimCode.RecordDeclaration decl; - input String name; - output Boolean b; -algorithm - b := match (decl,name) - local - String name1; - case (SimCode.RECORD_DECL_FULL(name=name1),_) then stringEq(name,name1); - else false; - end match; -end isRecordDecl; - -protected function isRecordDeclEqual - input SimCode.RecordDeclaration decl1; - input SimCode.RecordDeclaration decl2; - output Boolean b; -algorithm - b := match (decl1,decl2) - local - String name1,name2; - Absyn.Path path1,path2; - case (SimCode.RECORD_DECL_FULL(name=name1),SimCode.RECORD_DECL_FULL(name=name2)) then stringEq(name1,name2); - case (SimCode.RECORD_DECL_DEF(path=path1),SimCode.RECORD_DECL_DEF(path=path2)) then Absyn.pathEqual(path1,path2); - else false; - end match; -end isRecordDeclEqual; - -protected function elaborateFunctions2 - input Absyn.Program program; - input list daeElements; - input list inFunctions; - input list inRecordTypes; - input list inDecls; - input list inIncludes; - input list inIncludeDirs; - input list inLibs; - input list inPaths; - output list outFunctions; - output list outRecordTypes; - output list outDecls; - output list outIncludes; - output list outIncludeDirs; - output list outLibs; - output list outLibsPaths; -algorithm - (outFunctions, outRecordTypes, outDecls, outIncludes, outIncludeDirs, outLibs,outLibsPaths) := - match (program, daeElements, inFunctions, inRecordTypes, inDecls, inIncludes, inIncludeDirs, inLibs,inPaths) - local - Boolean b; - list accfns, fns; - SimCode.Function fn; - list rt, rt_1, rt_2, includes, libs,libPaths; - DAE.Function fel; - list rest; - list decls; - String name; - list includeDirs; - Absyn.Path path; - - case (_, {}, accfns, rt, decls, includes, includeDirs, libs,libPaths) - then (listReverse(accfns), rt, decls, includes, includeDirs, libs,libPaths); - case (_, (DAE.FUNCTION( type_ = DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN_PTR()))) :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) - equation - // skip over builtin functions - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); - then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - case (_, (DAE.FUNCTION(partialPrefix = true) :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) - equation - // skip over partial functions - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); - then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - case (_, DAE.FUNCTION(functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(language="builtin"))::_)::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) - equation - // skip over builtin functions - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); - then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - - case (_, (fel as DAE.FUNCTION(functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="C"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) - equation - // skip over builtin functions - b = listMember(name, SCode.knownExternalCFunctions); - (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), rt, decls, includes, includeDirs, libs,libPaths); - then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - - case (_, (fel :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) - equation - (fn, rt_1, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, (fn :: accfns), rt_1, decls, includes, includeDirs, libs,libPaths); - then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - end match; -end elaborateFunctions2; - -/* Does the actual work of transforming a DAE.FUNCTION to a SimCode.Function. */ -protected function elaborateFunction - input Absyn.Program program; - input DAE.Function inElement; - input list inRecordTypes; - input list inRecordDecls; - input list inIncludes; - input list inIncludeDirs; - input list inLibs; - input list inLibPaths; - output SimCode.Function outFunction; - output list outRecordTypes; - output list outRecordDecls; - output list outIncludes; - output list outIncludeDirs; - output list outLibs; - output list outLibPaths; -algorithm - (outFunction, outRecordTypes, outRecordDecls, outIncludes, outIncludeDirs, outLibs,outLibPaths):= - matchcontinue (program, inElement, inRecordTypes, inRecordDecls, inIncludes, inIncludeDirs, inLibs,inLibPaths) - local - DAE.Function fn; - String extfnname, lang, str; - list algs, vars; // , bivars, invars, outvars; - list includes, libs, libPaths, fn_libs,fn_paths, fn_includes, fn_includeDirs, rt, rt_1; - Absyn.Path fpath; - list args; - DAE.Type restype, tp; - list extargs; - list simextargs; - SimCode.SimExtArg extReturn; - DAE.ExtArg extretarg; - Option ann; - DAE.ExternalDecl extdecl; - list outVars, inVars, biVars, funArgs, varDecls; - list recordDecls; - list bodyStmts; - list daeElts; - Absyn.Path name; - DAE.ElementSource source; - SourceInfo info; - Boolean dynamicLoad, hasIncludeAnnotation, hasLibraryAnnotation; - list includeDirs; - DAE.FunctionAttributes funAttrs; - list varlst; - DAE.VarKind kind; - SCode.Visibility visibility; - - // Modelica functions. - case (_, DAE.FUNCTION(path = fpath, source = source, visibility = visibility, - functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps - type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes=funAttrs), - partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) - equation - - DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_NON_PARALLEL()) = funAttrs; - - outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); - funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); - vars = List.filter(daeElts, isVarQ); - varDecls = List.map(vars, daeInOutSimVar); - algs = List.filterOnTrue(daeElts, DAEUtil.isAlgorithm); - bodyStmts = List.map(algs, elaborateStatement); - info = DAEUtil.getElementSourceFileInfo(source); - then - (SimCode.FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, visibility, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); - - - case (_, DAE.FUNCTION(path = fpath, source = source, - functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps - type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes=funAttrs), - partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) - equation - - DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_KERNEL_FUNCTION()) = funAttrs; - - outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); - funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); - vars = List.filter(daeElts, isVarNotInputNotOutput); - varDecls = List.map(vars, daeInOutSimVar); - algs = List.filterOnTrue(daeElts, DAEUtil.isAlgorithm); - bodyStmts = List.map(algs, elaborateStatement); - info = DAEUtil.getElementSourceFileInfo(source); - then - (SimCode.KERNEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); - - - case (_, DAE.FUNCTION(path = fpath, source = source, - functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps - type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes = funAttrs), - partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) - equation - - DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_PARALLEL_FUNCTION()) = funAttrs; - - outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); - funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); - vars = List.filter(daeElts, isVarQ); - varDecls = List.map(vars, daeInOutSimVar); - algs = List.filterOnTrue(daeElts, DAEUtil.isAlgorithm); - bodyStmts = List.map(algs, elaborateStatement); - info = DAEUtil.getElementSourceFileInfo(source); - then - (SimCode.PARALLEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); - - // External functions. - case (_, DAE.FUNCTION(path = fpath, source = source, visibility = visibility, - functions = DAE.FUNCTION_EXT(body = daeElts, externalDecl = extdecl)::_, // might be followed by derivative maps - type_ = (DAE.T_FUNCTION(funcArg = args))), rt, recordDecls, includes, includeDirs, libs,libPaths) - equation - DAE.EXTERNALDECL(name=extfnname, args=extargs, - returnArg=extretarg, language=lang, ann=ann) = extdecl; - // outvars = DAEUtil.getOutputVars(daeElts); - // invars = DAEUtil.getInputVars(daeElts); - // bivars = DAEUtil.getBidirVars(daeElts); - funArgs = List.map1(args, typesSimFunctionArg, NONE()); - outVars = List.map(DAEUtil.getOutputVars(daeElts), daeInOutSimVar); - inVars = List.map(DAEUtil.getInputVars(daeElts), daeInOutSimVar); - biVars = List.map(DAEUtil.getBidirVars(daeElts), daeInOutSimVar); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); - info = DAEUtil.getElementSourceFileInfo(source); - (fn_includes, fn_includeDirs, fn_libs, fn_paths,dynamicLoad) = generateExtFunctionIncludes(program, fpath, ann, info); - includes = List.union(fn_includes, includes); - includeDirs = List.union(fn_includeDirs, includeDirs); - libs = List.union(fn_libs, libs); - libPaths = List.union(fn_paths, libPaths); - simextargs = List.map(extargs, extArgsToSimExtArgs); - extReturn = extArgsToSimExtArgs(extretarg); - (simextargs, extReturn) = fixOutputIndex(outVars, simextargs, extReturn); - // make lang to-upper as we have FORTRAN 77 and Fortran 77 in the Modelica Library! - lang = System.toupper(lang); - then - (SimCode.EXTERNAL_FUNCTION(fpath, extfnname, funArgs, simextargs, extReturn, - inVars, outVars, biVars, fn_includes, fn_libs, lang, visibility, info, dynamicLoad), - rt_1, recordDecls, includes, includeDirs, libs,libPaths); - - // Record constructor. - case (_, DAE.RECORD_CONSTRUCTOR(source = source, type_ = DAE.T_FUNCTION(funcArg = args, funcResultType = restype as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(name))),kind=kind), rt, recordDecls, includes, includeDirs, libs,libPaths) - equation - funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarationsForRecord(restype, recordDecls, rt); - DAE.T_COMPLEX(varLst = varlst) = restype; - varlst = List.filterOnTrue(varlst, Types.isProtectedVar); - varDecls = List.map(varlst, typesVar); - info = DAEUtil.getElementSourceFileInfo(source); - then - (SimCode.RECORD_CONSTRUCTOR(name, funArgs, varDecls, SCode.PUBLIC(), info, kind), rt_1, recordDecls, includes, includeDirs, libs,libPaths); - - // failure - case (_, fn, _, _, _, _, _,_) - equation - Error.addInternalError("function elaborateFunction failed for function: \n" + DAEDump.dumpFunctionStr(fn), sourceInfo()); - then - fail(); - end matchcontinue; -end elaborateFunction; - -protected function typesSimFunctionArg -"Generates code from a function argument." - input DAE.FuncArg inFuncArg; - input Option binding; - output SimCode.Variable outVar; -algorithm - outVar := matchcontinue (inFuncArg, binding) - local - DAE.Type tty; - String name; - DAE.ComponentRef cref_; - DAE.Const const; - list args; - DAE.Type res_ty; - list var_args; - list tys; - DAE.VarKind kind; - DAE.VarParallelism prl; - - case (DAE.FUNCARG(name=name, ty=DAE.T_FUNCTION(funcArg = args, funcResultType = DAE.T_TUPLE(types = tys))), _) - equation - var_args = List.map1(args, typesSimFunctionArg, NONE()); - tys = List.map(tys, Types.simplifyType); - then - SimCode.FUNCTION_PTR(name, tys, var_args, binding); - - case (DAE.FUNCARG(name=name, ty=DAE.T_FUNCTION(funcArg = args, funcResultType = DAE.T_NORETCALL())), _) - equation - var_args = List.map1(args, typesSimFunctionArg, NONE()); - then - SimCode.FUNCTION_PTR(name, {}, var_args, binding); - - case (DAE.FUNCARG(name=name, ty=DAE.T_FUNCTION(funcArg = args, funcResultType = res_ty)), _) - equation - res_ty = Types.simplifyType(res_ty); - var_args = List.map1(args, typesSimFunctionArg, NONE()); - then - SimCode.FUNCTION_PTR(name, {res_ty}, var_args, binding); - - case (DAE.FUNCARG(name=name, ty=tty, par=prl, const=const), _) - equation - tty = Types.simplifyType(tty); - cref_ = ComponentReference.makeCrefIdent(name, tty, {}); - kind = DAEUtil.const2VarKind(const); - then - SimCode.VARIABLE(cref_, tty, binding, {}, prl, kind); - end matchcontinue; -end typesSimFunctionArg; - -protected function daeInOutSimVar - input DAE.Element inElement; - output SimCode.Variable outVar; -algorithm - outVar := matchcontinue(inElement) - local - String name; - DAE.Type daeType; - DAE.ComponentRef id; - DAE.VarKind kind; - DAE.VarParallelism prl; - list inst_dims; - list inst_dims_exp; - Option binding; - SimCode.Variable var; - case (DAE.VAR(componentRef = DAE.CREF_IDENT(ident=name), ty = daeType as DAE.T_FUNCTION(), parallelism = prl, binding = binding)) - equation - var = typesSimFunctionArg(DAE.FUNCARG(name, daeType, DAE.C_VAR(), prl, NONE()), binding); - then var; - - case (DAE.VAR(componentRef = id, - parallelism = prl, - ty = daeType, - binding = binding, - dims = inst_dims, - kind = kind - )) - equation - daeType = Types.simplifyType(daeType); - inst_dims_exp = List.map(inst_dims, Expression.dimensionSizeExpHandleUnkown); - then SimCode.VARIABLE(id, daeType, binding, inst_dims_exp, prl, kind); - else - equation - // TODO: ArrayEqn fails here - Error.addInternalError("function daeInOutSimVar failed\n", sourceInfo()); - then - fail(); - end matchcontinue; -end daeInOutSimVar; - -protected function extArgsToSimExtArgs - input DAE.ExtArg extArg; - output SimCode.SimExtArg simExtArg; -algorithm - simExtArg := - match (extArg) - local - DAE.ComponentRef componentRef; - DAE.Attributes attributes; - DAE.Type type_; - Boolean isInput; - Boolean isOutput; - Boolean isArray; - DAE.Exp exp_; - Integer outputIndex; - - case DAE.EXTARG(componentRef, attributes, type_) - equation - isInput = Types.isInputAttr(attributes); - isOutput = Types.isOutputAttr(attributes); - outputIndex = if isOutput then -1 else 0; // correct output index is added later by fixOutputIndex - isArray = Types.isArray(type_); - type_ = Types.simplifyType(type_); - then SimCode.SIMEXTARG(componentRef, isInput, outputIndex, isArray, false /*fixed later*/, type_); - - case DAE.EXTARGEXP(exp_, type_) - equation - type_ = Types.simplifyType(type_); - then SimCode.SIMEXTARGEXP(exp_, type_); - - case DAE.EXTARGSIZE(componentRef, attributes, type_, exp_) - equation - isInput = Types.isInputAttr(attributes); - isOutput = Types.isOutputAttr(attributes); - outputIndex = if isOutput then -1 else 0; // correct output index is added later by fixOutputIndex - type_ = Types.simplifyType(type_); - then SimCode.SIMEXTARGSIZE(componentRef, isInput, outputIndex, type_, exp_); - - case DAE.NOEXTARG() then SimCode.SIMNOEXTARG(); - end match; -end extArgsToSimExtArgs; - -protected function fixOutputIndex - input list outVars; - input list simExtArgsIn; - input SimCode.SimExtArg extReturnIn; - output list simExtArgsOut; - output SimCode.SimExtArg extReturnOut; -algorithm - (simExtArgsOut, extReturnOut) := match (outVars, simExtArgsIn, extReturnIn) - local - case (_, _, _) - equation - simExtArgsOut = List.map1(simExtArgsIn, assignOutputIndex, outVars); - extReturnOut = assignOutputIndex(extReturnIn, outVars); - then - (simExtArgsOut, extReturnOut); - end match; -end fixOutputIndex; - -protected function assignOutputIndex - input SimCode.SimExtArg simExtArgIn; - input list outVars; - output SimCode.SimExtArg simExtArgOut; -algorithm - simExtArgOut := - matchcontinue (simExtArgIn, outVars) - local - DAE.ComponentRef cref, fcref; - Boolean isInput; - Integer outputIndex; // > 0 if output - Boolean isArray, hasBinding; - DAE.Type type_; - DAE.Exp exp; - Integer newOutputIndex; - - case (SimCode.SIMEXTARG(cref, isInput, outputIndex, isArray, _, type_), _) - equation - true = outputIndex == -1; - fcref = ComponentReference.crefFirstCref(cref); - (newOutputIndex, hasBinding) = findIndexInList(fcref, outVars, 1); - then - SimCode.SIMEXTARG(cref, isInput, newOutputIndex, isArray, hasBinding, type_); - - case (SimCode.SIMEXTARGSIZE(cref, isInput, outputIndex, type_, exp), _) - equation - true = outputIndex == -1; - (newOutputIndex, _) = findIndexInList(cref, outVars, 1); - then - SimCode.SIMEXTARGSIZE(cref, isInput, newOutputIndex, type_, exp); - - else - simExtArgIn; - end matchcontinue; -end assignOutputIndex; - -protected function findIndexInList - input DAE.ComponentRef cref; - input list outVars; - input Integer inCurrentIndex; - output Integer crefIndexInOutVars; - output Boolean hasBinding; -algorithm - (crefIndexInOutVars, hasBinding) := - matchcontinue (cref, outVars, inCurrentIndex) - local - DAE.ComponentRef name; - list restOutVars; - Option v; - Integer currentIndex; - - case (_, {}, _) then (-1, false); - case (_, SimCode.VARIABLE(name=name, value=v) :: _, currentIndex) - equation - true = ComponentReference.crefEqualNoStringCompare(cref, name); - then (currentIndex, Util.isSome(v)); - case (_, _ :: restOutVars, currentIndex) - equation - currentIndex = currentIndex + 1; - (currentIndex, hasBinding) = findIndexInList(cref, restOutVars, currentIndex); - then (currentIndex, hasBinding); - end matchcontinue; -end findIndexInList; - -protected function elaborateStatement - input DAE.Element inElement; - output SimCode.Statement outStatement; -algorithm - (outStatement):= - matchcontinue (inElement) - local - list stmts; - case (DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(statementLst = stmts))) - then - SimCode.ALGORITHM(stmts); - else - equation - true = Flags.isSet(Flags.FAILTRACE); - Debug.trace("# SimCode.elaborateStatement failed\n"); - then - fail(); - end matchcontinue; -end elaborateStatement; - - -public function checkValidMainFunction -"Verifies that an in-function can be generated. -This is not the case if the input involves function-pointers." - input String name; - input SimCode.Function fn; -algorithm - _ := matchcontinue (name, fn) - local - list inVars; - case (_, SimCode.FUNCTION(functionArguments = inVars)) - equation - failure(_ = List.selectFirst(inVars, isFunctionPtr)); - then (); - case (_, SimCode.EXTERNAL_FUNCTION(inVars = inVars)) - equation - failure(_ = List.selectFirst(inVars, isFunctionPtr)); - then (); - else - equation - Error.addMessage(Error.GENERATECODE_INVARS_HAS_FUNCTION_PTR, {name}); - then fail(); - end matchcontinue; -end checkValidMainFunction; - -public function isBoxedFunction -"Verifies that an in-function can be generated. -This is not the case if the input involves function-pointers." - input SimCode.Function fn; - output Boolean b; -algorithm - b := matchcontinue fn - local - list inVars, outVars; - case (SimCode.FUNCTION(functionArguments = inVars, outVars = outVars)) - equation - List.map_0(inVars, isBoxedArg); - List.map_0(outVars, isBoxedArg); - then true; - case (SimCode.EXTERNAL_FUNCTION(inVars = inVars, outVars = outVars)) - equation - List.map_0(inVars, isBoxedArg); - List.map_0(outVars, isBoxedArg); - then true; - else false; - end matchcontinue; -end isBoxedFunction; - -protected function isFunctionPtr -"Checks if an input variable is a function pointer" - input SimCode.Variable var; - output Boolean b; -algorithm - b := match var - /* Yes, they are VARIABLE, not SimCode.FUNCTION_PTR. */ - case SimCode.FUNCTION_PTR() then true; - else false; - end match; -end isFunctionPtr; - -protected function isBoxedArg -"Checks if a variable is a boxed datatype" - input SimCode.Variable var; -algorithm - _ := match var - case SimCode.FUNCTION_PTR() then (); - case SimCode.VARIABLE(ty = DAE.T_METABOXED()) then (); - case SimCode.VARIABLE(ty = DAE.T_METATYPE()) then (); - case SimCode.VARIABLE(ty = DAE.T_STRING()) then (); - end match; -end isBoxedArg; - -// ============================================================================= -// section of literals translation SimCode -// -// ============================================================================= + input SimCode.SimEqSystem eq2; + output Boolean b; +algorithm + b := simEqSystemIndex(eq1) > simEqSystemIndex(eq2); +end compareEqSystems; -public function findLiterals - "Finds all literal expressions in functions" - input list fns; - output list ofns; - output list literals; +public function sortEqSystems + input list eqs; + output list outEqs; algorithm - (ofns, (_, _, literals)) := DAEUtil.traverseDAEFunctions( - fns, findLiteralsHelper, - (0, HashTableExpToIndex.emptyHashTableSized(BaseHashTable.bigBucketSize), {}), {}); - literals := listReverse(literals); -end findLiterals; + outEqs := List.sort(eqs,compareEqSystems); +end sortEqSystems; protected function simulationFindLiterals "Finds all literal expressions in the DAE" @@ -1229,247 +139,12 @@ protected function simulationFindLiterals output tuple> literals; algorithm (ofns, literals) := DAEUtil.traverseDAEFunctions( - fns, findLiteralsHelper, + fns, SimCodeFunctionUtil.findLiteralsHelper, (0, HashTableExpToIndex.emptyHashTableSized(BaseHashTable.bigBucketSize), {}), {}); // Broke things :( // ((i, ht, literals)) := BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(dae, findLiteralsHelper, (i, ht, literals)); end simulationFindLiterals; -protected function findLiteralsHelper - input DAE.Exp inExp; - input tuple> inTpl; - output DAE.Exp exp; - output tuple> tpl; -algorithm - exp := inExp; - tpl := inTpl; - (exp, tpl) := Expression.traverseExpBottomUp(exp, replaceLiteralExp, tpl); - (exp, tpl) := Expression.traverseExpTopDown(exp, replaceLiteralArrayExp, tpl); -end findLiteralsHelper; - -protected function replaceLiteralArrayExp - "The tuples contain: - * The expression to be replaced (or not) - * Index of next literal - * HashTable Exp->Index (Number of the literal) - * The list of literals - - Handles only array expressions (needs to be performed in a top-down fashion) - " - input DAE.Exp inExp; - input tuple> inTpl; - output DAE.Exp outExp; - output Boolean cont; - output tuple> outTpl; -algorithm - (outExp,cont,outTpl) := matchcontinue (inExp,inTpl) - local - DAE.Exp exp,exp2; - tuple> tpl; - case (DAE.ARRAY(), _) - equation - isLiteralArrayExp(inExp); - (exp2, tpl) = replaceLiteralExp2(inExp, inTpl); - then (exp2, false, tpl); - case (exp as DAE.ARRAY(), tpl) - equation - failure(isLiteralArrayExp(exp)); - then (exp, false, tpl); - case (exp as DAE.MATRIX(), _) - equation - isLiteralArrayExp(exp); - (exp2, tpl) = replaceLiteralExp2(inExp, inTpl); - then (exp2, false, tpl); - case (exp as DAE.MATRIX(), tpl) - equation - failure(isLiteralArrayExp(exp)); - then (exp, false, tpl); - else (inExp, true, inTpl); - end matchcontinue; -end replaceLiteralArrayExp; - -protected function replaceLiteralExp - "The tuples contain: - * The expression to be replaced (or not) - * Index of next literal - * HashTable Exp->Index (Number of the literal) - * The list of literals - " - input DAE.Exp inExp; - input tuple> inTpl; - output DAE.Exp outExp; - output tuple> outTpl; -algorithm - (outExp,outTpl) := matchcontinue (inExp,inTpl) - local - DAE.Exp exp; - String msg; - tuple> t; - list es; - case (exp, t) - equation - failure(isLiteralExp(exp)); - then (exp, t); - case (exp, t) - equation - isTrivialLiteralExp(exp); - then (exp, t); - case (DAE.LIST(valList=es), t) - equation - true = listLength(es) > 25; - (exp,t) = replaceLiteralExp2(inExp, t); - then (exp, t); // Too large list; causes performance issues to find all sublists... - case (exp, t) - equation - exp = listToCons(exp); - (exp, t) = Expression.traverseExpBottomUp(exp, replaceLiteralExp, t); - then (exp, t); // All sublists should also be added as literals... - case (exp, _) - equation - failure(_ = listToCons(exp)); - (exp,t) = replaceLiteralExp2(exp, inTpl); - then (exp, t); - case (exp, _) - equation - msg = "function replaceLiteralExp failed. Falling back to not replacing "+ExpressionDump.printExpStr(exp)+"."; - Error.addInternalError(msg, sourceInfo()); - then (inExp,inTpl); - end matchcontinue; -end replaceLiteralExp; - -protected function replaceLiteralExp2 - "The tuples contain: - * The expression to be replaced (or not) - * Index of next literal - * HashTable Exp->Index (Number of the literal) - * The list of literals - " - input DAE.Exp inExp; - input tuple> inTpl; - output DAE.Exp outExp; - output tuple> outTpl; -algorithm - (outExp,outTpl) := matchcontinue (inExp,inTpl) - local - DAE.Exp exp, nexp; - Integer i, ix; - list l; - DAE.Type et; - HashTableExpToIndex.HashTable ht; - case (exp, (i, ht, l)) - equation - ix = BaseHashTable.get(exp, ht); - nexp = DAE.SHARED_LITERAL(ix, exp); - then (nexp, (i, ht, l)); - case (exp, (i, ht, l)) - equation - ht = BaseHashTable.add((exp, i), ht); - nexp = DAE.SHARED_LITERAL(i, exp); - then (nexp, (i+1, ht, exp::l)); - end matchcontinue; -end replaceLiteralExp2; - -protected function listToCons -"Converts a DAE.LIST to a chain of DAE.CONS" - input DAE.Exp e; - output DAE.Exp o; -algorithm - o := match e - local - list es; - case DAE.LIST(es as _::_) then listToCons2(es); - end match; -end listToCons; - -protected function listToCons2 -"Converts a DAE.LIST to a chain of DAE.CONS" - input list ies; - output DAE.Exp o; -algorithm - o := match ies - local - DAE.Exp car, cdr; - list es; - case ({}) then DAE.LIST({}); - case (car::es) - equation - cdr = listToCons2(es); - then DAE.CONS(car, cdr); - end match; -end listToCons2; - -protected function isTrivialLiteralExp -"Succeeds if the expression should not be translated to a constant literal because it is too simple" - input DAE.Exp exp; -algorithm - _ := match exp - case DAE.BOX(DAE.SCONST(_)) then fail(); - case DAE.BOX(DAE.RCONST(_)) then fail(); - case DAE.BOX(_) then (); - case DAE.ICONST(_) then (); - case DAE.BCONST(_) then (); - case DAE.RCONST(_) then (); - case DAE.ENUM_LITERAL() then (); - case DAE.LIST(valList={}) then (); - case DAE.META_OPTION(NONE()) then (); - case DAE.SHARED_LITERAL() then (); - else fail(); - end match; -end isTrivialLiteralExp; - -protected function isLiteralArrayExp - input DAE.Exp iexp; -algorithm - _ := match iexp - local - DAE.Exp e1, e2, exp; - list expl; - list> expll; - - case DAE.SCONST(_) then (); - case DAE.ICONST(_) then (); - case DAE.RCONST(_) then (); - case DAE.BCONST(_) then (); - case DAE.ARRAY(array=expl) equation List.map_0(expl, isLiteralArrayExp); then (); - case DAE.MATRIX(matrix=expll) equation List.map_0(List.flatten(expll), isLiteralArrayExp); then (); - case DAE.ENUM_LITERAL() then (); - case DAE.META_OPTION(NONE()) then (); - case DAE.META_OPTION(SOME(exp)) equation isLiteralArrayExp(exp); then (); - case DAE.BOX(exp) equation isLiteralArrayExp(exp); then (); - case DAE.CONS(car = e1, cdr = e2) equation isLiteralArrayExp(e1); isLiteralArrayExp(e2); then (); - case DAE.LIST(valList = expl) equation List.map_0(expl, isLiteralArrayExp); then (); - case DAE.META_TUPLE(expl) equation List.map_0(expl, isLiteralArrayExp); then (); - case DAE.METARECORDCALL(args=expl) equation List.map_0(expl, isLiteralArrayExp); then (); - case DAE.SHARED_LITERAL() then (); - else fail(); - end match; -end isLiteralArrayExp; - -protected function isLiteralExp -"Returns if the expression may be replaced by a constant literal" - input DAE.Exp iexp; -algorithm - _ := match iexp - local - DAE.Exp e1, e2, exp; - list expl; - case DAE.SCONST(_) then (); - case DAE.ICONST(_) then (); - case DAE.RCONST(_) then (); - case DAE.BCONST(_) then (); - case DAE.ENUM_LITERAL() then (); - case DAE.META_OPTION(NONE()) then (); - case DAE.META_OPTION(SOME(exp)) equation isLiteralExp(exp); then (); - case DAE.BOX(exp) equation isLiteralExp(exp); then (); - case DAE.CONS(car = e1, cdr = e2) equation isLiteralExp(e1); isLiteralExp(e2); then (); - case DAE.LIST(valList = expl) equation List.map_0(expl, isLiteralExp); then (); - case DAE.META_TUPLE(expl) equation List.map_0(expl, isLiteralExp); then (); - case DAE.METARECORDCALL(args=expl) equation List.map_0(expl, isLiteralExp); then (); - case DAE.SHARED_LITERAL() then (); - else fail(); - end match; -end isLiteralExp; - // ============================================================================= // section to create SimCode from BackendDAE // @@ -1632,7 +307,7 @@ algorithm ((uniqueEqIndex, algorithmAndEquationAsserts)) = BackendDAEUtil.foldEqSystem(dlow, createAlgorithmAndEquationAsserts, (uniqueEqIndex, {})); discreteModelVars = BackendDAEUtil.foldEqSystem(dlow, extractDiscreteModelVars, {}); - makefileParams = createMakefileParams(includeDirs, libs, libPaths,false); + makefileParams = SimCodeFunctionUtil.createMakefileParams(includeDirs, libs, libPaths,false); (delayedExps, maxDelayedExpIndex) = extractDelayedExpressions(dlow); // append removed equation to all equations, since these are actually @@ -1782,7 +457,7 @@ algorithm SOME(backendMapping), modelStruct); - (simCode, (_, _, lits)) = traverseExpsSimCode(simCode, findLiteralsHelper, literals); + (simCode, (_, _, lits)) = traverseExpsSimCode(simCode, SimCodeFunctionUtil.findLiteralsHelper, literals); simCode = setSimCodeLiterals(simCode, listReverse(lits)); @@ -1809,6 +484,51 @@ algorithm end matchcontinue; end createSimCode; +public function createFunctions + input Absyn.Program inProgram; + input DAE.DAElist inDAElist; + input BackendDAE.BackendDAE inBackendDAE; + input Absyn.Path inPath; + output list libs; + output list libPaths; + output list includes; + output list includeDirs; + output list recordDecls; + output list functions; + output BackendDAE.BackendDAE outBackendDAE; + output DAE.DAElist outDAE; + output tuple> literals; +algorithm + (libs,libPaths, includes, includeDirs, recordDecls, functions, outBackendDAE, outDAE, literals) := + matchcontinue (inProgram, inDAElist, inBackendDAE, inPath) + local + list libs2,libpaths2, includes2, includeDirs2; + list funcelems, part_func_elems, recFuncs; + DAE.DAElist dae; + BackendDAE.BackendDAE dlow; + DAE.FunctionTree functionTree; + Absyn.Path path; + list fns; + list lits; + + case (_, dae, dlow as BackendDAE.DAE(shared=BackendDAE.SHARED(functionTree=functionTree)), _) + equation + // get all the used functions from the function tree + funcelems = DAEUtil.getFunctionList(functionTree); + funcelems = setRecordVariability(funcelems,inBackendDAE); + funcelems = Inline.inlineCallsInFunctions(funcelems, (NONE(), {DAE.NORM_INLINE(), DAE.AFTER_INDEX_RED_INLINE()}), {}); + (funcelems, literals as (_, _, lits)) = simulationFindLiterals(dlow, funcelems); + (fns, recordDecls, includes2, includeDirs2, libs2,libpaths2) = SimCodeFunctionUtil.elaborateFunctions(inProgram, funcelems, {}, lits, {}); // Do we need metarecords here as well? + then + (libs2, libpaths2,includes2, includeDirs2, recordDecls, fns, dlow, dae, literals); + else + equation + Error.addInternalError("Creation of Modelica functions failed.", sourceInfo()); + then + fail(); + end matchcontinue; +end createFunctions; + protected function collectPartitions input BackendDAE.EqSystem syst; input BackendDAE.Shared shared; @@ -5230,7 +3950,7 @@ protected function getSimVars2Crefs algorithm for cref in inCrefs loop try - outSimVars := get(cref, inSimVarHT)::outSimVars; + outSimVars := SimCodeFunctionUtil.get(cref, inSimVarHT)::outSimVars; else end try; end for; @@ -5614,239 +4334,6 @@ algorithm end match; end extractIdAndExpFromDelayExp; -public function createMakefileParams - input list includes; - input list libs; - input list libPaths; - input Boolean isFunction; - output SimCode.MakefileParams makefileParams; -protected - String omhome, ccompiler, cxxcompiler, linker, exeext, dllext, cflags, ldflags, rtlibs, platform, fopenmp,compileDir; -algorithm - ccompiler := if stringEq(Config.simCodeTarget(),"JavaScript") then "emcc" else - (if Flags.isSet(Flags.HPCOM) then System.getOMPCCompiler() else System.getCCompiler()); - cxxcompiler := if stringEq(Config.simCodeTarget(),"JavaScript") then "emcc" else System.getCXXCompiler(); - linker := if stringEq(Config.simCodeTarget(),"JavaScript") then "emcc" else System.getLinker(); - exeext := if stringEq(Config.simCodeTarget(),"JavaScript") then ".js" else System.getExeExt(); - dllext := System.getDllExt(); - omhome := Settings.getInstallationDirectoryPath(); - omhome := System.trim(omhome, "\""); // Remove any quotation marks from omhome. - cflags := System.getCFlags() + " " + - (if Flags.isSet(Flags.HPCOM) then "-fopenmp" else ""); - cflags := if stringEq(Config.simCodeTarget(),"JavaScript") then "-Os -Wno-warn-absolute-paths" else cflags; - ldflags := System.getLDFlags(); - rtlibs := if isFunction then System.getRTLibs() else System.getRTLibsSim(); - platform := System.modelicaPlatform(); - compileDir := System.pwd() + System.pathDelimiter(); - makefileParams := SimCode.MAKEFILE_PARAMS(ccompiler, cxxcompiler, linker, exeext, dllext, - omhome, cflags, ldflags, rtlibs, includes, libs,libPaths, platform,compileDir); -end createMakefileParams; - -protected function elaborateRecordDeclarationsFromTypes - input list inTypes; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; -algorithm - (outRecordDecls, outReturnTypes) := - match (inTypes, inAccRecordDecls, inReturnTypes) - local - list accRecDecls; - DAE.Type firstType; - list restTypes; - list returnTypes; - - case ({}, accRecDecls, _) - then (accRecDecls, inReturnTypes); - case (firstType :: restTypes, accRecDecls, _) - equation - (accRecDecls, returnTypes) = - elaborateRecordDeclarationsForRecord(firstType, accRecDecls, inReturnTypes); - (accRecDecls, returnTypes) = - elaborateRecordDeclarationsFromTypes(restTypes, accRecDecls, returnTypes); - then (accRecDecls, returnTypes); - end match; -end elaborateRecordDeclarationsFromTypes; - -protected function elaborateRecordDeclarations -"Translate all records used by varlist to structs." - input list inVars; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; -algorithm - (outRecordDecls, outReturnTypes) := - matchcontinue (inVars, inAccRecordDecls, inReturnTypes) - local - DAE.Element var; - list rest; - DAE.Type ft; - list rt, rt_1, rt_2; - list accRecDecls; - DAE.Algorithm algorithm_; - list expl; - - case ({}, accRecDecls, rt) then (accRecDecls, rt); - - case (((DAE.VAR(ty = ft)) :: rest), accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarationsForRecord(ft, accRecDecls, rt); - (accRecDecls, rt_2) = elaborateRecordDeclarations(rest, accRecDecls, rt_1); - then - (accRecDecls, rt_2); - - case ((DAE.ALGORITHM(algorithm_ = algorithm_) :: rest), accRecDecls, rt) - equation - true = Config.acceptMetaModelicaGrammar(); - ((_, expl)) = BackendDAEUtil.traverseAlgorithmExps(algorithm_, Expression.traverseSubexpressionsHelper, (matchMetarecordCalls, {})); - (accRecDecls, rt_2) = elaborateRecordDeclarationsForMetarecords(expl, accRecDecls, rt); - // TODO: ? what about rest ? , can be there something else after the ALGORITHM - (accRecDecls, rt_2) = elaborateRecordDeclarations(rest, accRecDecls, rt_2); - then - (accRecDecls, rt_2); - - case ((_ :: rest), accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarations(rest, accRecDecls, rt); - then - (accRecDecls, rt_1); - end matchcontinue; -end elaborateRecordDeclarations; - -protected function elaborateRecordDeclarationsForRecord -"Helper function to generateStructsForRecords." - input DAE.Type inRecordType; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; -algorithm - (outRecordDecls, outReturnTypes) := match (inRecordType, inAccRecordDecls, inReturnTypes) - local - Absyn.Path path, name; - list varlst; - String sname; - list rt, rt_1, rt_2, fieldNames; - list accRecDecls; - list vars; - Integer index; - SimCode.RecordDeclaration recDecl; - - case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(name), varLst = varlst, source = {_}), accRecDecls, rt) - equation - sname = Absyn.pathStringUnquoteReplaceDot(name, "_"); - if not listMember(sname, rt) then - vars = List.map(varlst, typesVarNoBinding); - vars = List.sort(vars,compareVariable); - rt_1 = sname :: rt; - (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(varlst, accRecDecls, rt_1); - recDecl = SimCode.RECORD_DECL_FULL(sname, NONE(), name, vars); - accRecDecls = List.appendElt(recDecl, accRecDecls); - else - rt_2 = rt; - end if; - then (accRecDecls, rt_2); - - case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)), accRecDecls, rt) - then (accRecDecls, rt); - - case (DAE.T_METARECORD(source = {Absyn.QUALIFIED(name="SourceInfo")}), accRecDecls, rt) - then (accRecDecls, rt); - - case (DAE.T_METARECORD( fields = varlst, source = {path}), accRecDecls, rt) - equation - sname = Absyn.pathStringUnquoteReplaceDot(path, "_"); - if not listMember(sname, rt) then - fieldNames = List.map(varlst, generateVarName); - accRecDecls = SimCode.RECORD_DECL_DEF(path, fieldNames) :: accRecDecls; - rt_1 = sname::rt; - (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(varlst, accRecDecls, rt_1); - else - rt_2 = rt; - end if; - then (accRecDecls, rt_2); - - case (_, accRecDecls, rt) - then (accRecDecls, rt); - - end match; -end elaborateRecordDeclarationsForRecord; - -protected function generateVarName - input DAE.Var inVar; - output String outName; -algorithm - outName := - match (inVar) - local - DAE.Ident name; - case DAE.TYPES_VAR(name = name) then name; - else "NULL"; - end match; -end generateVarName; - -protected function elaborateNestedRecordDeclarations -"Helper function to elaborateRecordDeclarations." - input list inRecordTypes; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; -algorithm - (outRecordDecls, outReturnTypes) := matchcontinue (inRecordTypes, inAccRecordDecls, inReturnTypes) - local - DAE.Type ty; - list rest; - list rt, rt_1, rt_2; - list accRecDecls; - case ({}, accRecDecls, rt) - then (accRecDecls, rt); - case (DAE.TYPES_VAR(ty = ty as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)))::rest, accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarationsForRecord(ty, accRecDecls, rt); - (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(rest, accRecDecls, rt_1); - then (accRecDecls, rt_2); - case (_::rest, accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateNestedRecordDeclarations(rest, accRecDecls, rt); - then (accRecDecls, rt_1); - end matchcontinue; -end elaborateNestedRecordDeclarations; - -protected function elaborateRecordDeclarationsForMetarecords - input list inExpl; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; -algorithm - (outRecordDecls, outReturnTypes) := match (inExpl, inAccRecordDecls, inReturnTypes) - local - list rt, rt_1, rt_2, fieldNames; - list rest; - String name; - Absyn.Path path; - list accRecDecls; - Boolean b; - - case ({}, accRecDecls, rt) then (accRecDecls, rt); - case (DAE.METARECORDCALL(path=path, fieldNames=fieldNames)::rest, accRecDecls, rt) - equation - name = Absyn.pathStringUnquoteReplaceDot(path, "_"); - b = listMember(name, rt); - accRecDecls = List.consOnTrue(not b, SimCode.RECORD_DECL_DEF(path, fieldNames), accRecDecls); - rt_1 = List.consOnTrue(not b, name, rt); - (accRecDecls, rt_2) = elaborateRecordDeclarationsForMetarecords(rest, accRecDecls, rt_1); - then (accRecDecls, rt_2); - case (_::rest, accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarationsForMetarecords(rest, accRecDecls, rt); - then (accRecDecls, rt_1); - end match; -end elaborateRecordDeclarationsForMetarecords; - protected function createExtObjInfo input BackendDAE.Shared shared; output SimCode.ExtObjInfo extObjInfo; @@ -8796,7 +7283,7 @@ algorithm size = numStateVars+numAlgVars+numIntAlgVars+numBoolAlgVars+numAlgAliasVars+numIntAliasVars+ numBoolAliasVars+numParams+numIntParams+numBoolParams+numOutVars+numInVars + numOptimizeConstraints + numOptimizeFinalConstraints; size = intMax(size,1000); - ht = emptyHashTableSized(size); + ht = SimCodeFunctionUtil.emptyHashTableSized(size); arraySimVars = HashTableCrILst.emptyHashTableSized(size); ht = List.fold(stateVars, addSimVarToHashTable, ht); //true = intLt(size, -1); @@ -8848,14 +7335,14 @@ algorithm case (sv as SimCodeVar.SIMVAR(name = cr, arrayCref = NONE()), _) equation //print("addSimVarToHashTable: handling variable '" + ComponentReference.printComponentRefStr(cr) + "'\n"); - outHT = add((cr, sv), inHT); + outHT = SimCodeFunctionUtil.add((cr, sv), inHT); then outHT; // add the whole array crefs to the hashtable, too case (sv as SimCodeVar.SIMVAR(name = cr, arrayCref = SOME(acr)), _) equation //print("addSimVarToHashTable: handling array variable '" + ComponentReference.printComponentRefStr(cr) + "'\n"); - outHT = add((acr, sv), inHT); - outHT = add((cr, sv), outHT); + outHT = SimCodeFunctionUtil.add((acr, sv), inHT); + outHT = SimCodeFunctionUtil.add((cr, sv), outHT); then outHT; else equation @@ -9037,324 +7524,75 @@ algorithm (e22, rhs); // not succeded to solve, return unsolved equation., catched later. - else (e1, e2); - end matchcontinue; -end solveTrivialArrayEquation; - -protected function solveTrivialArrayEquation2 -"author: Frenkel TUD - 2012-07 - helper for solveTrivialArrayEquation" - input DAE.Exp e1; - input DAE.Exp e2; - output DAE.Exp outE1; - output DAE.Exp outE2; -algorithm - (outE1, outE2) := match(e1, e2) - local - DAE.Exp lhs, rhs; - case(DAE.CREF(), _) - equation - (rhs, _) = ExpressionSimplify.simplify(Expression.negate(e2)); - then - (e1, rhs); - - case(DAE.UNARY(exp=lhs as DAE.CREF()), _) - equation - (rhs, _) = ExpressionSimplify.simplify(e2); - then - (lhs, rhs); - - end match; -end solveTrivialArrayEquation2; - -protected function getVectorizedCrefFromExp "author: PA - Returns the component ref v if expression is on form - {v{1}, v{2}, ...v{n}} for some n. - TODO: implement for 2D as well." - input DAE.Exp inExp; - output DAE.ComponentRef outComponentRef; -algorithm - outComponentRef := match (inExp) - local - list crefs, crefs_1; - DAE.ComponentRef cr; - list expl; - list> column; - - case (DAE.ARRAY(array = expl)) - equation - ((crefs as (cr :: _))) = List.map(expl, Expression.expCref); // Get all CRefs from exp1. - crefs_1 = List.map(crefs, ComponentReference.crefStripLastSubs); // Strip last subscripts - List.reduce(crefs_1, ComponentReference.crefEqualReturn); // Check if elements are equal, remove one - then - cr; - - case (DAE.MATRIX(matrix = column)) - equation - expl = List.flatten(column); - ((crefs as (cr :: _))) = List.map(expl, Expression.expCref); // Get all CRefs from exp1. - crefs_1 = List.map(crefs, ComponentReference.crefStripLastSubs); // Strip last subscripts - List.reduce(crefs_1, ComponentReference.crefEqualReturn); // Check if elements are equal, remove one - then - cr; - end match; -end getVectorizedCrefFromExp; - -protected function getCalledFunctionsInFunctions "Goes through the given DAE, finds the given functions and collects - the names of the functions called from within those functions" - input list paths; - input HashTableStringToPath.HashTable inHt; - input DAE.FunctionTree funcs; - output HashTableStringToPath.HashTable outHt; -algorithm - outHt := match (paths, inHt, funcs) - local - list rest; - Absyn.Path path; - HashTableStringToPath.HashTable ht; - - case ({}, ht, _) then ht; - case (path::rest, ht, _) - equation - ht = getCalledFunctionsInFunction2(path, Absyn.pathStringNoQual(path), ht, funcs); - ht = getCalledFunctionsInFunctions(rest, ht, funcs); - then ht; - end match; -end getCalledFunctionsInFunctions; - -public function getCalledFunctionsInFunction2 "Goes through the given DAE, finds the given function and collects - the names of the functions called from within those functions" - input Absyn.Path inPath; - input String pathstr; - input HashTableStringToPath.HashTable inHt "paths to not add"; - input DAE.FunctionTree funcs; - output HashTableStringToPath.HashTable outHt "paths to not add"; -algorithm - outHt := matchcontinue (inPath, pathstr, inHt, funcs) - local - String str; - Absyn.Path path; - DAE.Function funcelem; - list calledfuncs, varfuncs; - list els; - HashTableStringToPath.HashTable ht; - - case (_, _, ht, _) - equation - BaseHashTable.get(pathstr, ht); - then ht; - - case (path, _, ht, _) - equation - funcelem = DAEUtil.getNamedFunction(path, funcs); - els = DAEUtil.getFunctionElements(funcelem); - // SimCode.Function reference variables are filtered out - varfuncs = List.fold(els, DAEUtil.collectFunctionRefVarPaths, {}); - (_, (_, varfuncs)) = DAEUtil.traverseDAE2(els, Expression.traverseSubexpressionsHelper, (DAEUtil.collectValueblockFunctionRefVars, varfuncs)); - (_, (_, (calledfuncs, _))) = DAEUtil.traverseDAE2(els, Expression.traverseSubexpressionsHelper, (matchNonBuiltinCallsAndFnRefPaths, ({}, varfuncs))); - ht = BaseHashTable.add((pathstr, path), ht); - ht = addDestructor(funcelem, ht); - ht = getCalledFunctionsInFunctions(calledfuncs, ht, funcs); - then ht; - - case (path, _, _, _) - equation - failure(_ = DAEUtil.getNamedFunction(path, funcs)); - str = "function getCalledFunctionsInFunction2: Class " + pathstr + " not found in global scope."; - Error.addInternalError(str, sourceInfo()); - then - fail(); - end matchcontinue; -end getCalledFunctionsInFunction2; - -protected function addDestructor - input DAE.Function func; - input HashTableStringToPath.HashTable inHt; - output HashTableStringToPath.HashTable outHt; -algorithm - outHt := match (func,inHt) - local - Absyn.Path path; - String pathstr; - case (DAE.FUNCTION(type_=DAE.T_FUNCTION(funcResultType=DAE.T_COMPLEX(complexClassType=ClassInf.EXTERNAL_OBJ(path=path)))),_) - equation - path = Absyn.joinPaths(path,Absyn.IDENT("destructor")); - then addDestructor2(path,Absyn.pathStringNoQual(path),inHt); - else inHt; - end match; -end addDestructor; - -protected function addDestructor2 - input Absyn.Path path; - input String pathstr; - input HashTableStringToPath.HashTable inHt; - output HashTableStringToPath.HashTable ht = inHt; -algorithm - if not BaseHashTable.hasKey(pathstr, ht) then - BaseHashTable.add((pathstr, path), ht); - end if; -end addDestructor2; - -// ============================================================================= -// section for ??? -// -// ============================================================================= + else (e1, e2); + end matchcontinue; +end solveTrivialArrayEquation; -protected function isVarQ -"Succeeds if inElement is a variable or constant that is not input." - input DAE.Element inElement; +protected function solveTrivialArrayEquation2 +"author: Frenkel TUD - 2012-07 + helper for solveTrivialArrayEquation" + input DAE.Exp e1; + input DAE.Exp e2; + output DAE.Exp outE1; + output DAE.Exp outE2; algorithm - _ := match (inElement) + (outE1, outE2) := match(e1, e2) local - DAE.VarKind vk; - DAE.VarDirection vd; - case DAE.VAR(kind=vk, direction=vd) + DAE.Exp lhs, rhs; + case(DAE.CREF(), _) equation - isVarVarOrConstant(vk); - isDirectionNotInput(vd); - then (); - end match; -end isVarQ; + (rhs, _) = ExpressionSimplify.simplify(Expression.negate(e2)); + then + (e1, rhs); -/*mahge: kernel functions*/ -protected function isVarNotInputNotOutput -"Succeeds if inElement is a variable or constant that is not input or output. -needed in kernel functions since they shouldn't have output vars." - input DAE.Element inElement; -algorithm - _ := match (inElement) - local - DAE.VarKind vk; - DAE.VarDirection vd; - case DAE.VAR(kind=vk, direction=vd) + case(DAE.UNARY(exp=lhs as DAE.CREF()), _) equation - isVarVarOrConstant(vk); - isDirectionNotInputNotOutput(vd); - then (); - end match; -end isVarNotInputNotOutput; - -protected function isVarVarOrConstant - input DAE.VarKind inVarKind; -algorithm - _ := match (inVarKind) - case DAE.VARIABLE() then (); - case DAE.PARAM() then (); - case DAE.CONST() then (); - end match; -end isVarVarOrConstant; - -protected function isDirectionNotInput - input DAE.VarDirection inVarDirection; -algorithm - _ := match (inVarDirection) - case DAE.OUTPUT() then (); - case DAE.BIDIR() then (); - end match; -end isDirectionNotInput; + (rhs, _) = ExpressionSimplify.simplify(e2); + then + (lhs, rhs); -protected function isDirectionNotInputNotOutput - input DAE.VarDirection inVarDirection; -algorithm - _ := match (inVarDirection) - case DAE.BIDIR() then (); end match; -end isDirectionNotInputNotOutput; - -protected function filterNg "Sets the number of zero crossings to zero if events are disabled." - input Integer ng; - output Integer outInteger; -algorithm - outInteger := if useZerocrossing() then ng else 0; -end filterNg; - -protected function useZerocrossing - output Boolean res; -algorithm - res := Flags.isSet(Flags.EVENTS); -end useZerocrossing; +end solveTrivialArrayEquation2; -protected function getCrefFromExp "Assume input Exp is CREF and return the ComponentRef, fail otherwise." - input DAE.Exp e; - output Absyn.ComponentRef c; +protected function getVectorizedCrefFromExp "author: PA + Returns the component ref v if expression is on form + {v{1}, v{2}, ...v{n}} for some n. + TODO: implement for 2D as well." + input DAE.Exp inExp; + output DAE.ComponentRef outComponentRef; algorithm - c := match (e) + outComponentRef := match (inExp) local - DAE.ComponentRef crefe; - Absyn.ComponentRef crefa; + list crefs, crefs_1; + DAE.ComponentRef cr; + list expl; + list> column; - case(DAE.CREF(componentRef = crefe)) + case (DAE.ARRAY(array = expl)) equation - crefa = ComponentReference.unelabCref(crefe); + ((crefs as (cr :: _))) = List.map(expl, Expression.expCref); // Get all CRefs from exp1. + crefs_1 = List.map(crefs, ComponentReference.crefStripLastSubs); // Strip last subscripts + List.reduce(crefs_1, ComponentReference.crefEqualReturn); // Check if elements are equal, remove one then - crefa; + cr; - else + case (DAE.MATRIX(matrix = column)) equation - Error.addInternalError("function getCrefFromExp failed: input was not of type DAE.CREF", sourceInfo()); + expl = List.flatten(column); + ((crefs as (cr :: _))) = List.map(expl, Expression.expCref); // Get all CRefs from exp1. + crefs_1 = List.map(crefs, ComponentReference.crefStripLastSubs); // Strip last subscripts + List.reduce(crefs_1, ComponentReference.crefEqualReturn); // Check if elements are equal, remove one then - fail(); - end match; -end getCrefFromExp; - -protected function scodeParallelismToDAEParallelism - input SCode.Parallelism inParallelism; - output DAE.VarParallelism outParallelism; -algorithm - outParallelism := match(inParallelism) - case(SCode.PARGLOBAL()) then DAE.PARGLOBAL(); - case(SCode.PARLOCAL()) then DAE.PARLOCAL(); - case(SCode.NON_PARALLEL()) then DAE.NON_PARALLEL(); + cr; end match; -end scodeParallelismToDAEParallelism; +end getVectorizedCrefFromExp; -protected function typesVarNoBinding - input DAE.Var inTypesVar; - output SimCode.Variable outVar; -algorithm - outVar := match (inTypesVar) - local - String name; - DAE.Type ty; - DAE.ComponentRef cref_; - DAE.Attributes attr; - SCode.Parallelism scPrl; - DAE.VarParallelism prl; - - case (DAE.TYPES_VAR(name=name, attributes = attr, ty=ty)) - equation - ty = Types.simplifyType(ty); - cref_ = ComponentReference.makeCrefIdent(name, ty, {}); - DAE.ATTR(parallelism = scPrl) = attr; - prl = scodeParallelismToDAEParallelism(scPrl); - then SimCode.VARIABLE(cref_, ty, NONE(), {}, prl,DAE.VARIABLE()); - end match; -end typesVarNoBinding; +// ============================================================================= +// section for ??? +// +// ============================================================================= -protected function typesVar - input DAE.Var inTypesVar; - output SimCode.Variable outVar; -algorithm - outVar := match (inTypesVar) - local - String name; - DAE.Type ty; - DAE.ComponentRef cref_; - DAE.Attributes attr; - SCode.Parallelism scPrl; - DAE.VarParallelism prl; - DAE.Exp bindExp; - - case (DAE.TYPES_VAR(name=name, attributes = attr, ty=ty)) - equation - ty = Types.simplifyType(ty); - cref_ = ComponentReference.makeCrefIdent(name, ty, {}); - DAE.ATTR(parallelism = scPrl) = attr; - prl = scodeParallelismToDAEParallelism(scPrl); - bindExp = Types.getBindingExp(inTypesVar, Absyn.IDENT(name)); - then SimCode.VARIABLE(cref_, ty, SOME(bindExp), {}, prl, DAE.VARIABLE()); - end match; -end typesVar; +/*mahge: kernel functions*/ protected function dlowvarToSimvar input BackendDAE.Var dlowVar; @@ -9499,628 +7737,68 @@ end dlowvarToSimvar; // str = "Initial value of unknown type: " + ExpressionDump.printExpStr(exp); // Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, info); // then (); -// end match; -// end checkInitVal; - -protected function getCausality - input BackendDAE.Var dlowVar; - input BackendDAE.Variables inVars; - output SimCodeVar.Causality caus; -algorithm - caus := matchcontinue (dlowVar, inVars) - local - DAE.ComponentRef cr; - BackendDAE.Variables knvars; - case (BackendDAE.VAR(varName = cr, varDirection = DAE.OUTPUT()), _) then SimCodeVar.OUTPUT(); - case (BackendDAE.VAR(varName = cr, varDirection = DAE.INPUT()), knvars) - equation - (_, _) = BackendVariable.getVar(cr, knvars); - then SimCodeVar.INPUT(); - else SimCodeVar.INTERNAL(); - end matchcontinue; -end getCausality; - -protected function traversingdlowvarToSimvarFold - input BackendDAE.Var v; - input tuple, BackendDAE.Variables> inTpl; - output tuple, BackendDAE.Variables> outTpl; -algorithm - (_, outTpl) := traversingdlowvarToSimvar(v, inTpl); -end traversingdlowvarToSimvarFold; - -protected function traversingdlowvarToSimvar - input BackendDAE.Var inVar; - input tuple, BackendDAE.Variables> inTpl; - output BackendDAE.Var outVar; - output tuple, BackendDAE.Variables> outTpl; -algorithm - (outVar,outTpl) := match (inVar,inTpl) - local - BackendDAE.Var v; - list sv_lst; - SimCodeVar.SimVar sv; - BackendDAE.Variables vars; - case (v, (sv_lst, vars)) - equation - sv = dlowvarToSimvar(v, NONE(), vars); - then (v, (sv::sv_lst, vars)); - else (inVar,inTpl); - end match; -end traversingdlowvarToSimvar; - -protected function subsToScalar "scalar expression." - input list inExpSubscriptLst; - output Boolean outBoolean; -algorithm - outBoolean := match (inExpSubscriptLst) - local - Boolean b; - list r; - case {} then true; - case (DAE.SLICE() :: _) then false; - case (DAE.WHOLEDIM() :: _) then false; - case (DAE.INDEX() :: r) - equation - b = subsToScalar(r); - then - b; - end match; -end subsToScalar; - -public function getMatchingExpsList - input list inExps; - input MatchFn inFn; - output list outExpLst; - partial function MatchFn - input DAE.Exp inExp; - input list inExps; - output DAE.Exp outExp; - output list outExps; - end MatchFn; -algorithm - (_, outExpLst) := Expression.traverseExpList(inExps, inFn, {}); -end getMatchingExpsList; - -protected function matchNonBuiltinCallsAndFnRefPaths "The extra argument is a tuple; the second list is the list of variable - names to filter out (so we don't add function references variables)" - input DAE.Exp inExp; - input tuple, list> itpl; - output DAE.Exp outExp; - output tuple, list> otpl; -algorithm - (outExp,otpl) := matchcontinue (inExp,itpl) - local - Absyn.Path path; - list acc, filter; - case (DAE.CALL(path = path, attr = DAE.CALL_ATTR(builtin = false)), (acc, filter)) - equation - path = Absyn.makeNotFullyQualified(path); - false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); - then (inExp, (path::acc, filter)); - case (DAE.REDUCTION(reductionInfo = DAE.REDUCTIONINFO(path = path)), (acc, filter)) - equation - false = List.isMemberOnTrue(path, {Absyn.IDENT("list"),Absyn.IDENT("listReverse"),Absyn.IDENT("array"),Absyn.IDENT("min"),Absyn.IDENT("max"),Absyn.IDENT("sum"),Absyn.IDENT("product")}, Absyn.pathEqual); - false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); - then (inExp, (path::acc, filter)); - case (DAE.PARTEVALFUNCTION(path = path), (acc, filter)) - equation - path = Absyn.makeNotFullyQualified(path); - false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); - then (inExp, (path::acc, filter)); - case (DAE.CREF(ty = DAE.T_FUNCTION_REFERENCE_FUNC(builtin = false)), (acc, filter)) - equation - path = Absyn.crefToPath(getCrefFromExp(inExp)); - false = List.isMemberOnTrue(path, filter, Absyn.pathEqual); - then (inExp, (path::acc, filter)); - else (inExp,itpl); - end matchcontinue; -end matchNonBuiltinCallsAndFnRefPaths; - -protected function matchMetarecordCalls "Used together with getMatchingExps" - input DAE.Exp e; - input list acc; - output DAE.Exp outExp; - output list outExps; -algorithm - (outExp,outExps) := matchcontinue (e,acc) - local - Integer index; - case (DAE.METARECORDCALL(index = index), _) - equation - outExps = List.consOnTrue(-1 <> index, e, acc); - then (e, outExps); - else (e,acc); - end matchcontinue; -end matchMetarecordCalls; - -protected function generateExtFunctionIncludes "by investigating the annotation of an external function." - input Absyn.Program program; - input Absyn.Path path; - input Option inAbsynAnnotationOption; - input SourceInfo info; - output list includes; - output list includeDirs; - output list libs; - output list paths; - output Boolean dynamcLoad; -algorithm - (includes, includeDirs, libs,paths, dynamcLoad):= - match (program, path, inAbsynAnnotationOption) - local - SCode.Mod mod; - Boolean b; - String target; - Option odir, resources; - list libNames, fullLibNames, dirs; - - case (_, _, SOME(SCode.ANNOTATION(mod))) - algorithm - b := generateExtFunctionDynamicLoad(mod); - target := Flags.getConfigString(Flags.TARGET); - (libs, libNames) := generateExtFunctionIncludesLibstr(target,mod); - includes := generateExtFunctionIncludesIncludestr(mod); - (libs, dirs, resources) := generateExtFunctionLibraryDirectoryFlags(program, path, mod, libs); - for name in if Flags.isSet(Flags.CHECK_EXT_LIBS) then libNames else {} loop - if target=="msvc" or System.os()=="Windows_NT" then - fullLibNames := {name + System.getDllExt(), "lib" + name + ".a", "lib" + name + ".lib"}; - else - fullLibNames := {"lib" + name + ".a", "lib" + name + System.getDllExt()}; - end if; - lookForExtFunctionLibrary(fullLibNames, dirs, name, resources, path, info); - end for; - paths := generateExtFunctionLibraryDirectoryPaths(program, path, mod); - includeDirs := generateExtFunctionIncludeDirectoryFlags(program, path, mod, includes); - then - (includes, includeDirs, libs,paths, b); - case (_, _, NONE()) then ({}, {}, {},{}, false); - end match; -end generateExtFunctionIncludes; - -protected function lookForExtFunctionLibrary - input list names; - input list dirs; - input String name; - input Option resources; - input Absyn.Path path; - input SourceInfo info; -algorithm - if not max(System.regularFileExists(d+"/"+n) for d in dirs, n in names) then - _ := match resources - local - String resourcesStr, tmpdir, cmd, pwd, contents, found; - Integer status; - Boolean didFind; - case SOME(resourcesStr) - algorithm - if System.directoryExists(resourcesStr) then - didFind := false; - for dir in list(dir for dir guard System.regularFileExists(resourcesStr + "/BuildProjects/" + dir + "/autogen.sh") in System.subDirectories(resourcesStr + "/BuildProjects")) loop - tmpdir := System.createTemporaryDirectory(Settings.getTempDirectoryPath() + "/omc_compile_" + name + "_"); - Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Created directory " + tmpdir}, info); - cmd := "cp -a \"" + resourcesStr + "\"/* \"" + tmpdir + "\""; - Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {cmd}, info); - System.systemCall(cmd); - pwd := System.pwd(); - if 0==System.cd(tmpdir + "/BuildProjects/" + dir) then - Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Changed directory to " + System.pwd()}, info); - // TODO: Add $(host) - cmd := "sh ./autogen.sh && ./configure --libdir='"+userCompiledBinariesDirectory(path)+"' && make && make install"; - status := System.systemCall(cmd, "log"); - contents := System.readFile("log"); - if status <> 0 then - Error.addSourceMessage(Error.COMPILER_WARNING, {"Failed to run "+cmd+": " + contents}, info); - else - Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Succeeded with compilation and installation of the library using:\ncommand: "+cmd+"\n" + contents}, info); - if not max(System.regularFileExists(d+"/"+n) for d in dirs, n in names) then - Error.addSourceMessage(Error.EXT_LIBRARY_NOT_FOUND_DESPITE_COMPILATION_SUCCESS, {cmd, System.pwd()}, info); - else - found := listHead(list(x for x guard System.regularFileExists(x) in List.flatten(list(d+"/"+n for d in dirs, n in names)))); - Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Compiled "+found+" by running build project " + resourcesStr + "/BuildProjects/" + dir}, info); - didFind := true; - end if; - end if; - else - Error.addSourceMessage(Error.COMPILER_WARNING, {"Failed to change directory to " + tmpdir + "/BuildProjects/" + dir}, info); - end if; - System.cd(pwd); - System.removeDirectory(tmpdir); - Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"Removed directory " + tmpdir}, info); - if didFind then - break; - end if; - end for; - end if; - then (); - else (); - end match; - if not max(System.regularFileExists(d+"/"+n) for d in dirs, n in names) then - // suppress this warning if we're running the testsuite - if not Config.getRunningTestsuite() then - Error.addSourceMessage(Error.EXT_LIBRARY_NOT_FOUND, {name, sum("\n " + d + "/" + n for d in dirs, n in names)}, info); - end if; - end if; - end if; -end lookForExtFunctionLibrary; - -protected function generateExtFunctionIncludeDirectoryFlags - "Process LibraryDirectory and IncludeDirectory" - input Absyn.Program program; - input Absyn.Path path; - input SCode.Mod inMod; - input list includes; - output list outDirs; -algorithm - outDirs := matchcontinue (program, path, inMod, includes) - local - String str,istr; - case (_, _, _, {}) then {}; - case (_, _, _, _) - equation - SCode.MOD(binding = SOME(Absyn.STRING(str))) = - Mod.getUnelabedSubMod(inMod, "IncludeDirectory"); - str = CevalScript.getFullPathFromUri(program, str, false); - istr = "\"-I"+str+"\""; - then if System.directoryExists(str) then {istr} else {}; - case (_, _, _, _) - equation - str = "modelica://" + Absyn.pathFirstIdent(path) + "/Resources/Include"; - str = CevalScript.getFullPathFromUri(program, str, false); - istr = "\"-I"+str+"\""; - then if System.directoryExists(str) then {istr} else {}; - // Read SourceInfo instead? - else {}; - end matchcontinue; -end generateExtFunctionIncludeDirectoryFlags; - -protected function generateExtFunctionLibraryDirectoryFlags - "Process LibraryDirectory and IncludeDirectory" - input Absyn.Program program; - input Absyn.Path path; - input SCode.Mod inMod; - input list inLibs; - output list outLibs; - output list installDirs; - output Option resources; -algorithm - (outLibs, installDirs, resources) := matchcontinue (program, path, inMod, inLibs) - local - String str, str1, str2, str3, platform1, platform2, target, dir, resourcesStr; - list libs, libs2; - Boolean isLinux; - case (_, _, _, {}) then ({}, {}, NONE()); - case (_, _, _, libs) - algorithm - str := matchcontinue inMod - case _ - equation - SCode.MOD(binding = SOME(Absyn.STRING(str))) = Mod.getUnelabedSubMod(inMod, "LibraryDirectory"); - then str; - else "modelica://" + Absyn.pathFirstIdent(path) + "/Resources/Library"; - end matchcontinue; - str := CevalScript.getFullPathFromUri(program, str, false); - resourcesStr := CevalScript.getFullPathFromUri(program, "modelica://" + Absyn.pathFirstIdent(path) + "/Resources", false); - platform1 := str + "/" + System.openModelicaPlatform(); - platform2 := str + "/" + System.modelicaPlatform(); - isLinux := stringEq("linux",System.os()); - target := Flags.getConfigString(Flags.TARGET); - // please, take care about ordering these libraries, the most specific should have the highest priority - libs2 := str::platform2::platform1::(Settings.getHomeDir(false)+"/.openmodelica/binaries/"+Absyn.pathFirstIdent(path))::(Settings.getInstallationDirectoryPath() + "/lib/" + System.getTriple() + "/omc")::(Settings.getInstallationDirectoryPath() + "/lib/")::{}; - libs := List.fold2(libs2, generateExtFunctionLibraryDirectoryFlags2, isLinux, target, libs); - then (libs, listReverse(libs2), SOME(resourcesStr)); - else (inLibs, {}, NONE()); - end matchcontinue; -end generateExtFunctionLibraryDirectoryFlags; - -protected function generateExtFunctionLibraryDirectoryFlags2 - input String dir; - input Boolean isLinux; - input String target; - input list inLibs; - output list libs; -algorithm - libs := if isLinux then "-Wl,-rpath=\"" + dir + "\""::inLibs else inLibs; - libs := (if target=="msvc" then "/LIBPATH:\"" + dir + "\"" else "\"-L" + dir + "\"")::libs; -end generateExtFunctionLibraryDirectoryFlags2; - -protected function userCompiledBinariesDirectory - input Absyn.Path path; - output String str = Settings.getHomeDir(false)+"/.openmodelica/binaries/"+Absyn.pathFirstIdent(path); -end userCompiledBinariesDirectory; - -protected function generateExtFunctionLibraryDirectoryPaths - "Process LibraryDirectory and IncludeDirectory" - input Absyn.Program program; - input Absyn.Path path; - input SCode.Mod inMod; - output list outLibs; -algorithm - outLibs := matchcontinue (program, path, inMod) - local - String str, str1, str2, str3, platform1, platform2,target; - list libs; - Boolean isLinux; - case (_, _, _) - equation - SCode.MOD(binding = SOME(Absyn.STRING(str))) = - Mod.getUnelabedSubMod(inMod, "LibraryDirectory"); - str = CevalScript.getFullPathFromUri(program, str, false); - platform1 = System.openModelicaPlatform(); - platform2 = System.modelicaPlatform(); - isLinux = stringEq("linux",System.os()); - // please, take care about ordering these libraries, the most specific should go first (in reverse here) - libs = generateExtFunctionLibraryDirectoryPaths2(true, str, isLinux, {} ); - libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform2,""), str + "/" + platform2, isLinux, libs); - libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform1,""), str + "/" + platform1, isLinux, libs); - then libs; - case (_, _, _) - equation - str = "modelica://" + Absyn.pathFirstIdent(path) + "/Resources/Library"; - str = CevalScript.getFullPathFromUri(program, str, false); - platform1 = System.openModelicaPlatform(); - platform2 = System.modelicaPlatform(); - isLinux = stringEq("linux",System.os()); - // please, take care about ordering these libraries, the most specific should go first (in reverse here) - libs = generateExtFunctionLibraryDirectoryPaths2(true, str, isLinux, {} ); - libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform2,""), str + "/" + platform2, isLinux, libs); - libs = generateExtFunctionLibraryDirectoryPaths2(not stringEq(platform1,""), str + "/" + platform1, isLinux, libs); - then libs; - else {}; - end matchcontinue; -end generateExtFunctionLibraryDirectoryPaths; - - -protected function generateExtFunctionLibraryDirectoryPaths2 - input Boolean add; - input String dir; - input Boolean isLinux; - input list inLibs; - output list libs; -algorithm - libs := match (add,dir,isLinux,inLibs) - local - Boolean b; - case (true,_,_,libs) - equation - b = System.directoryExists(dir); - libs = List.consOnTrue(b, dir , libs); - then libs; - else inLibs; - end match; -end generateExtFunctionLibraryDirectoryPaths2; - - -protected function getLibraryStringInMSVCFormat -"Takes an Absyn.STRING describing a library and outputs a list -of strings corresponding to it. -Note: Normally only outputs a single string, but Lapack on MinGW is special." - input Absyn.Exp exp; - output list strs; - output list names; -algorithm - (strs,names) := matchcontinue exp - local - String str; - - // seems lapack can show on Lapack form or lapack (different case) (MLS revision 6155) - // Lapack on MinGW/Windows is linked against f2c - case Absyn.STRING(str) guard str=="Lapack" or str=="lapack" - then ({"lapack_win32_MT.lib", "f2c.lib"}, {}); - - // omcruntime on windows needs linking with mico2313 and wsock and then some :) - case Absyn.STRING("omcruntime") - equation - true = "Windows_NT" == System.os(); - strs = {"f2c.lib", "initialization.lib", "libexpat.lib", "math-support.lib", "meta.lib", "ModelicaExternalC.lib", "results.lib", "simulation.lib", "solver.lib", "sundials_kinsol.lib", "sundials_nvecserial.lib", "util.lib", "lapack_win32_MT.lib"}; - then - (strs, {}); - - // Wonder if there may be issues if we have duplicates in the Corba libs - // and the other libs. Some other developer will probably swear over this - // hack some day, but at least I get an early weekend. - case Absyn.STRING("OpenModelicaCorba") - equation - str = System.getCorbaLibs(); - then ({str},{}); - - case Absyn.STRING("fmilib") - then ({"fmilib.lib","shlwapi.lib"},{}); - - // If the string starts with a -, it's probably -l or -L gcc flags - case Absyn.STRING(str) - equation - true = "-" == stringGetStringChar(str, 1); - then ({str},{}); - - case Absyn.STRING(str) - equation - str = str + ".lib"; - then ({str},{}); - - else - equation - Error.addInternalError("Failed to process Library annotation for external function", sourceInfo()); - then fail(); - end matchcontinue; -end getLibraryStringInMSVCFormat; - -protected function getLibraryStringInGccFormat -"Takes an Absyn.STRING describing a library and outputs a list -of strings corresponding to it. -Note: Normally only outputs a single string, but Lapack on MinGW is special." - input Absyn.Exp exp; - output list strs; - output list names; -algorithm - (strs,names) := matchcontinue exp - local - String str, fopenmp; - - // Lapack is always included - case Absyn.STRING("lapack") then ({},{}); - case Absyn.STRING("Lapack") then ({},{}); - - case Absyn.STRING(str as "omcruntime") - equation - if "Windows_NT" == System.os() then - // omcruntime on windows needs linking with mico2313 and wsock and then some :) - str = "-l" + str; - strs = str :: "-lintl" :: "-liconv" :: "-lexpat" :: "-lsqlite3" :: "-llpsolve55" :: "-lmico2313" :: "-lws2_32" :: "-lregex" :: {}; - else - strs = System.getRuntimeLibs(); - end if; - then (strs,{}); - - // Wonder if there may be issues if we have duplicates in the Corba libs - // and the other libs. Some other developer will probably swear over this - // hack some day, but at least I get an early weekend. - case Absyn.STRING("OpenModelicaCorba") - equation - str = System.getCorbaLibs(); - then ({str},{}); - - case Absyn.STRING("fmilib") - then (if System.os()=="Windows_NT" then {"-lfmilib","-lshlwapi"} else {"-lfmilib"},{}); - - case Absyn.STRING(str) - equation - // If the string is a file, return it as it is - // If the string starts with a -, it's probably -l or -L gcc flags - if System.regularFileExists(str) or "-" == stringGetStringChar(str, 1) then - strs = {str}; - names = {}; - else - strs = {"-l" + str}; - names = {str}; - end if; - - then (strs,names); - - else - equation - Error.addInternalError("Failed to process Library annotation for external function", sourceInfo()); - then fail(); - end matchcontinue; -end getLibraryStringInGccFormat; +// end match; +// end checkInitVal; -protected function generateExtFunctionIncludesLibstr - input String target; - input SCode.Mod inMod; - output list outStringLst; - output list names; +protected function getCausality + input BackendDAE.Var dlowVar; + input BackendDAE.Variables inVars; + output SimCodeVar.Causality caus; algorithm - (outStringLst, names) := matchcontinue (target,inMod) + caus := matchcontinue (dlowVar, inVars) local - list arr; - list libs; - list> libsList, namesList; - Absyn.Exp exp; - case ("msvc",_) - equation - SCode.MOD(binding = SOME(Absyn.ARRAY(arr))) = - Mod.getUnelabedSubMod(inMod, "Library"); - (libsList, namesList) = List.map_2(arr, getLibraryStringInMSVCFormat); - then - (List.flatten(libsList), List.flatten(namesList)); - case ("msvc",_) - equation - SCode.MOD(binding = SOME(exp)) = - Mod.getUnelabedSubMod(inMod, "Library"); - (libs,names) = getLibraryStringInMSVCFormat(exp); - then - (libs,names); - case (_,_) - equation - SCode.MOD(binding = SOME(Absyn.ARRAY(arr))) = - Mod.getUnelabedSubMod(inMod, "Library"); - (libsList, namesList) = List.map_2(arr, getLibraryStringInGccFormat); - then - (List.flatten(libsList), List.flatten(namesList)); - case (_,_) + DAE.ComponentRef cr; + BackendDAE.Variables knvars; + case (BackendDAE.VAR(varName = cr, varDirection = DAE.OUTPUT()), _) then SimCodeVar.OUTPUT(); + case (BackendDAE.VAR(varName = cr, varDirection = DAE.INPUT()), knvars) equation - SCode.MOD(binding = SOME(exp)) = - Mod.getUnelabedSubMod(inMod, "Library"); - (libs,names) = getLibraryStringInGccFormat(exp); - then - (libs,names); - else ({},{}); + (_, _) = BackendVariable.getVar(cr, knvars); + then SimCodeVar.INPUT(); + else SimCodeVar.INTERNAL(); end matchcontinue; -end generateExtFunctionIncludesLibstr; +end getCausality; -protected function generateExtFunctionIncludesIncludestr - input SCode.Mod inMod; - output list includes; +protected function traversingdlowvarToSimvarFold + input BackendDAE.Var v; + input tuple, BackendDAE.Variables> inTpl; + output tuple, BackendDAE.Variables> outTpl; algorithm - includes := matchcontinue (inMod) - local - String inc, inc_1; - Integer lineNumberStart; - String str,fileName; - case (_) - equation - SCode.MOD(binding = SOME(Absyn.STRING(inc)), info = SOURCEINFO(fileName=fileName,lineNumberStart=lineNumberStart)) = - Mod.getUnelabedSubMod(inMod, "Include"); - str = "#line "+intString(lineNumberStart)+" \""+fileName+"\""; - inc_1 = System.unescapedString(inc); - includes = if Config.acceptMetaModelicaGrammar() or Flags.isSet(Flags.GEN_DEBUG_SYMBOLS) then {str,inc_1} else {inc_1}; - then includes; - else {}; - end matchcontinue; -end generateExtFunctionIncludesIncludestr; + (_, outTpl) := traversingdlowvarToSimvar(v, inTpl); +end traversingdlowvarToSimvarFold; -protected function generateExtFunctionDynamicLoad - input SCode.Mod inMod; - output Boolean outDynamicLoad; +protected function traversingdlowvarToSimvar + input BackendDAE.Var inVar; + input tuple, BackendDAE.Variables> inTpl; + output BackendDAE.Var outVar; + output tuple, BackendDAE.Variables> outTpl; algorithm - outDynamicLoad:= matchcontinue (inMod) + (outVar,outTpl) := match (inVar,inTpl) local - Boolean b; - case (_) + BackendDAE.Var v; + list sv_lst; + SimCodeVar.SimVar sv; + BackendDAE.Variables vars; + case (v, (sv_lst, vars)) equation - SCode.MOD(binding = SOME((Absyn.BOOL(b)))) = - Mod.getUnelabedSubMod(inMod, "DynamicLoad"); - then - b; - else false; - end matchcontinue; -end generateExtFunctionDynamicLoad; - -public function getImplicitRecordConstructors - "If a record instance is sent to a function we need to generate code for the - record constructor even if it's not explicitly called, because the constructor - is used by the generated code. This function checks the arguments of a - function for these implicit record constructor calls and returns a list of all - record constructors that are used." - input list inExpLst; + sv = dlowvarToSimvar(v, NONE(), vars); + then (v, (sv::sv_lst, vars)); + else (inVar,inTpl); + end match; +end traversingdlowvarToSimvar; + +public function getMatchingExpsList + input list inExps; + input MatchFn inFn; output list outExpLst; + partial function MatchFn + input DAE.Exp inExp; + input list inExps; + output DAE.Exp outExp; + output list outExps; + end MatchFn; algorithm - outExpLst := matchcontinue(inExpLst) - local - DAE.ComponentRef cref; - DAE.Type record_type; - Absyn.Path record_path; - list rest_expr; - DAE.Exp record_cref; - case ({}) then {}; - // A record component reference. - case (DAE.CREF( - componentRef = cref, - ty = (DAE.T_COMPLEX( - complexClassType = ClassInf.RECORD(path = record_path)))) :: rest_expr) - equation - // Make sure it has no subscripts, i.e. it's a component reference for - // an entire record instance. - {} = ComponentReference.crefLastSubs(cref); - // Build a DAE.CREF from the record path. - cref = ComponentReference.pathToCref(record_path); - record_cref = Expression.crefExp(cref); - rest_expr = getImplicitRecordConstructors(rest_expr); - then record_cref :: rest_expr; - case (_ :: rest_expr) - equation - rest_expr = getImplicitRecordConstructors(rest_expr); - then rest_expr; - end matchcontinue; -end getImplicitRecordConstructors; + (_, outExpLst) := Expression.traverseExpList(inExps, inFn, {}); +end getMatchingExpsList; protected function addDivExpErrorMsgtoExp "author: Frenkel TUD 2010-02, Adds the error msg to Expression.Div." input DAE.Exp inExp; @@ -10513,554 +8191,6 @@ algorithm end matchcontinue; end getNominalValue; - -/****** HashTable ComponentRef -> SimCodeVar.SimVar ******/ -/* a workaround to enable "cross public import" */ - - -/* HashTable instance specific code */ - -protected function keyEqual - input SimCode.Key key1; - input SimCode.Key key2; - output Boolean res; -algorithm - res := ComponentReference.crefEqualNoStringCompare(key1, key2); -end keyEqual; - -/* end of HashTable instance specific code */ - - -/* - public function cloneHashTable " - Author BZ 2008-06 - Make a stand-alone-copy of hashtable. - " - input HashTableCrefToSimVar inHash; - output HashTableCrefToSimVar outHash; - algorithm outHash := matchcontinue(inHash) - local - array>> arg1, arg1_2; - Integer arg3, arg4, arg3_2, arg4_2, arg21, arg21_2, arg22, arg22_2; - array>> arg23, arg23_2; - case(HASHTABLE(arg1, VALUE_ARRAY(arg21, arg22, arg23), arg3, arg4)) - equation - arg1_2 = arrayCopy(arg1); - arg21_2 = arg21; - arg22_2 = arg22; - arg23_2 = arrayCopy(arg23); - arg3_2 = arg3; - arg4_2 = arg4; - then - HASHTABLE(arg1_2, VALUE_ARRAY(arg21_2, arg22_2, arg23_2), arg3_2, arg4_2); - end matchcontinue; - end cloneHashTable; - - public function nullHashTable " - author: PA - - Returns an empty HashTable. - Using the bucketsize 100 and array size 10. - " - output HashTableCrefToSimVar hashTable; - array>> arr; - list>> lst; - array>> emptyarr; - algorithm - arr := fill({}, 0); - emptyarr := listArray({}); - hashTable := HASHTABLE(arr, VALUE_ARRAY(0, 0, emptyarr), 0, 0); - end nullHashTable; - */ - -protected function emptyHashTableSized " - author: PA - Returns an empty HashTable. - Using the bucketsize 100 and array size 10." - input Integer size; - output SimCode.HashTableCrefToSimVar hashTable; -protected - array>> arr; - list>> lst; - array>> emptyarr; - Integer szArr; -algorithm - arr := arrayCreate(size, {}); - emptyarr := arrayCreate(size, NONE()); - szArr:=realInt(realMul(intReal(size), 0.6)); - hashTable := SimCode.HASHTABLE(arr, SimCode.VALUE_ARRAY(0, szArr, emptyarr), size, 0); -end emptyHashTableSized; - -/* - public function isEmpty "Returns true if hashtable is empty" - input HashTableCrefToSimVar hashTable; - output Boolean res; - algorithm - res := matchcontinue(hashTable) - case(HASHTABLE(_, _, _, 0)) then true; - case(_) then false; - end matchcontinue; - end isEmpty; - */ - -public function add " - author: PA - - Add a Key-Value tuple to hashtable. - If the Key-Value tuple already exists, the function updates the Value. -" - input tuple entry; - input SimCode.HashTableCrefToSimVar hashTable; - output SimCode.HashTableCrefToSimVar outHashTable; -algorithm - outHashTable := matchcontinue (entry, hashTable) - local - Integer indx, newpos, n, n_1, bsize, indx_1; - SimCode.ValueArray varr_1, varr; - list> indexes; - array>> hashvec_1, hashvec; - tuple v, newv; - SimCode.Key key; - SimCode.Value value; - /* Adding when not existing previously */ - case ((v as (key, _)), (SimCode.HASHTABLE(hashvec, varr, bsize, _))) - equation - failure((_) = get(key, hashTable)); - indx = ComponentReference.hashComponentRefMod(key,bsize); - newpos = valueArrayLength(varr); - varr_1 = valueArrayAdd(varr, v); - indexes = hashvec[indx + 1]; - hashvec_1 = arrayUpdate(hashvec, indx + 1, ((key, newpos) :: indexes)); - n_1 = valueArrayLength(varr_1); - then SimCode.HASHTABLE(hashvec_1, varr_1, bsize, n_1); - - /* adding when already present => Updating value */ - case ((newv as (key, _)), (SimCode.HASHTABLE(hashvec, varr, bsize, n))) - equation - (_, indx) = get1(key, hashTable); - // print("adding when present, indx =" );print(intString(indx));print("\n"); - varr_1 = valueArraySetnth(varr, indx, newv); - then SimCode.HASHTABLE(hashvec, varr_1, bsize, n); - case (_, _) - equation - print("- HashTableCrefToSimVar.add failed\n"); - then - fail(); - end matchcontinue; -end add; -/* - public function anyKeyInHashTable "Returns true if any of the keys are present in the hashtable. Stops and returns true upon first occurence" - input list keys; - input HashTableCrefToSimVar ht; - output Boolean res; - algorithm - res := matchcontinue(keys, ht) - local Key key; - case({}, ht) then false; - case(key::keys, ht) equation - _ = get(key, ht); - then true; - case(_::keys, ht) then anyKeyInHashTable(keys, ht); - end matchcontinue; - end anyKeyInHashTable; - - public function addListNoUpd "adds several keys with the same value, using addNuUpdCheck. Can be used to use HashTable as a Set" - input list keys; - input Value v; - input HashTableCrefToSimVar ht; - output HashTableCrefToSimVar outHt; - algorithm - ht := matchcontinue(keys, v, ht) - local Key key; - case ({}, v, ht) then ht; - case(key::keys, v, ht) equation - ht = addNoUpdCheck((key, v), ht); - ht = addListNoUpd(keys, v, ht); - then ht; - end matchcontinue; - end addListNoUpd; - */ -public function addNoUpdCheck " - author: PA - - Add a Key-Value tuple to hashtable. - If the Key-Value tuple already exists, the function updates the Value. -" - input tuple entry; - input SimCode.HashTableCrefToSimVar hashTable; - output SimCode.HashTableCrefToSimVar outHashTable; -algorithm - outHashTable := matchcontinue (entry, hashTable) - local - Integer hval, indx, newpos, n, n_1, bsize, indx_1; - SimCode.ValueArray varr_1, varr; - list> indexes; - array>> hashvec_1, hashvec; - String name_str; - tuple v, newv; - SimCode.Key key; - SimCode.Value value; - - // adding when not existing previously - case ((v as (key, _)), SimCode.HASHTABLE(hashvec, varr, bsize, _)) - equation - indx = ComponentReference.hashComponentRefMod(key,bsize); - newpos = valueArrayLength(varr); - varr_1 = valueArrayAdd(varr, v); - indexes = hashvec[indx + 1]; - hashvec_1 = arrayUpdate(hashvec, indx + 1, ((key, newpos) :: indexes)); - n_1 = valueArrayLength(varr_1); - then SimCode.HASHTABLE(hashvec_1, varr_1, bsize, n_1); - - // failure - else - equation - print("- HashTableCrefToSimVar.addNoUpdCheck failed\n"); - then - fail(); - end matchcontinue; -end addNoUpdCheck; -/* - public function delete " - author: PA - - delete the Value associatied with Key from the HashTable. - Note: This function does not delete from the index table, only from the ValueArray. - This means that a lot of deletions will not make the HashTable more compact, it will still contain - a lot of incices information. - " - input Key key; - input HashTableCrefToSimVar hashTable; - output HashTableCrefToSimVar outHahsTable; - algorithm - outVariables:= - matchcontinue (key, hashTable) - local - Integer hval, indx, newpos, n, n_1, bsize, indx_1; - ValueArray varr_1, varr; - list> indexes; - array>> hashvec_1, hashvec; - String name_str; - tuple v, newv; - Value value; - // * adding when already present => Updating value * / - case (key, (hashTable as HASHTABLE(hashvec, varr, bsize, n))) - equation - (_, indx) = get1(key, hashTable); - indx_1 = indx - 1; - varr_1 = valueArrayClearnth(varr, indx); - then HASHTABLE(hashvec, varr_1, bsize, n); - case (_, hashTable) - equation - print("-HashTableCrefToSimVar.delete failed\n"); - print("content:"); dumpHashTable(hashTable); - then - fail(); - end matchcontinue; - end delete; - */ - -public function get " -author: PA - - Returns a Value given a Key and a HashTable. -" - input SimCode.Key key; - input SimCode.HashTableCrefToSimVar hashTable; - output SimCode.Value value; -algorithm - (value, _):= get1(key, hashTable); -end get; - -protected function get1 "help function to get" - input SimCode.Key key; - input SimCode.HashTableCrefToSimVar hashTable; - output SimCode.Value value; - output Integer indx; -algorithm - (value, indx):= - match (key, hashTable) - local - Integer bsize, n; - list> indexes; - SimCode.Value v; - array>> hashvec; - SimCode.ValueArray varr; - SimCode.Key k; - case (_, (SimCode.HASHTABLE(hashvec, varr, bsize, _))) - equation - indx = ComponentReference.hashComponentRefMod(key,bsize); - indexes = hashvec[indx + 1]; - indx = get2(key, indexes); - (k, v) = valueArrayNth(varr, indx); - true = keyEqual(k, key); - then - (v, indx); - end match; -end get1; - -protected function get2 " - author: PA - - Helper function to get -" - input SimCode.Key key; - input list> keyIndices; - output Integer index; -algorithm - index := - matchcontinue (key, keyIndices) - local - SimCode.Key key2; - list> xs; - case (_, ((key2, index) :: _)) - equation - true = keyEqual(key, key2); - then - index; - case (_, (_ :: xs)) - equation - index = get2(key, xs); - then - index; - end matchcontinue; -end get2; -/* - public function hashTableValueList "return the Value entries as a list of Values" - input HashTableCrefToSimVar hashTable; - output list valLst; - algorithm - valLst := List.map(hashTableList(hashTable), Util.tuple22); - end hashTableValueList; - - public function hashTableKeyList "return the Key entries as a list of Keys" - input HashTableCrefToSimVar hashTable; - output list valLst; - algorithm - valLst := List.map(hashTableList(hashTable), Util.tuple21); - end hashTableKeyList; - - public function hashTableList "returns the entries in the hashTable as a list of tuple" - input HashTableCrefToSimVar hashTable; - output list> tplLst; - algorithm - tplLst := matchcontinue(hashTable) - local ValueArray varr; - case(HASHTABLE(valueArr = varr)) equation - tplLst = valueArrayList(varr); - then tplLst; - end matchcontinue; - end hashTableList; - - public function valueArrayList " - author: PA - Transforms a ValueArray to a tuple list - " - input ValueArray valueArray; - output list> tplLst; - algorithm - tplLst := - matchcontinue (valueArray) - local - array>> arr; - tuple elt; - Integer lastpos, n, size; - list> lst; - case (VALUE_ARRAY(numberOfElements = 0, valueArray = arr)) then {}; - case (VALUE_ARRAY(numberOfElements = 1, valueArray = arr)) - equation - SOME(elt) = arr[0 + 1]; - then - {elt}; - case (VALUE_ARRAY(numberOfElements = n, arrSize = size, valueArray = arr)) - equation - lastpos = n - 1; - lst = valueArrayList2(arr, 0, lastpos); - then - lst; - end matchcontinue; - end valueArrayList; - - protected function valueArrayList2 "Helper function to valueArrayList" - input array>> inVarOptionArray1; - input Integer inInteger2; - input Integer inInteger3; - output list> outVarLst; - algorithm - outVarLst:= - matchcontinue (inVarOptionArray1, inInteger2, inInteger3) - local - tuple v; - array>> arr; - Integer pos, lastpos, pos_1; - list> res; - case (arr, pos, lastpos) - equation - (pos == lastpos) = true; - SOME(v) = arr[pos + 1]; - then - {v}; - case (arr, pos, lastpos) - equation - pos_1 = pos + 1; - SOME(v) = arr[pos + 1]; - res = valueArrayList2(arr, pos_1, lastpos); - then - (v :: res); - case (arr, pos, lastpos) - equation - pos_1 = pos + 1; - NONE = arr[pos + 1]; - res = valueArrayList2(arr, pos_1, lastpos); - then - (res); - end matchcontinue; - end valueArrayList2; - */ -public function valueArrayLength " - author: PA - - Returns the number of elements in the ValueArray -" - input SimCode.ValueArray valueArray; - output Integer size; -algorithm - size := match (valueArray) - case (SimCode.VALUE_ARRAY(numberOfElements = size)) then size; - end match; -end valueArrayLength; - -public function valueArrayAdd "author: PA - Adds an entry last to the ValueArray, increasing array size - if no space left by factor 1.4 -" - input SimCode.ValueArray valueArray; - input tuple entry; - output SimCode.ValueArray outValueArray; -algorithm - outValueArray:= - matchcontinue (valueArray, entry) - local - Integer n_1, n, size, expandsize, expandsize_1, newsize; - array>> arr_1, arr, arr_2; - Real rsize, rexpandsize; - case (SimCode.VALUE_ARRAY(numberOfElements = n, arrSize = size, valueArray = arr), _) - equation - (n < size) = true "Have space to add array elt."; - n_1 = n + 1; - arr_1 = arrayUpdate(arr, n + 1, SOME(entry)); - then - SimCode.VALUE_ARRAY(n_1, size, arr_1); - - case (SimCode.VALUE_ARRAY(numberOfElements = n, arrSize = size, valueArray = arr), _) - equation - (n < size) = false "Do NOT have splace to add array elt. Expand with factor 1.4"; - rsize = intReal(size); - rexpandsize = rsize * 0.4; - expandsize = realInt(rexpandsize); - expandsize_1 = intMax(expandsize, 1); - newsize = expandsize_1 + size; - arr_1 = Array.expand(expandsize_1, arr, NONE()); - n_1 = n + 1; - arr_2 = arrayUpdate(arr_1, n + 1, SOME(entry)); - then - SimCode.VALUE_ARRAY(n_1, newsize, arr_2); - case (_, _) - equation - print("-HashTableCrefToSimVar.valueArrayAdd failed\n"); - then - fail(); - end matchcontinue; -end valueArrayAdd; - -public function valueArraySetnth "author: PA - Set the n:th variable in the ValueArray to value. -" - input SimCode.ValueArray valueArray; - input Integer pos; - input tuple entry; - output SimCode.ValueArray outValueArray; -algorithm - outValueArray:= - matchcontinue (valueArray, pos, entry) - local - array>> arr_1, arr; - Integer n, size; - case (SimCode.VALUE_ARRAY(n, size, arr), _, _) - equation - (pos < size) = true; - arr_1 = arrayUpdate(arr, pos + 1, SOME(entry)); - then - SimCode.VALUE_ARRAY(n, size, arr_1); - case (_, _, _) - equation - print("-HashTableCrefToSimVar.valueArraySetnth failed\n"); - then - fail(); - end matchcontinue; -end valueArraySetnth; -/* - public function valueArrayClearnth " - author: PA - Clears the n:th variable in the ValueArray (set to NONE). - " - input ValueArray valueArray; - input Integer pos; - output ValueArray outValueArray; - algorithm - outValueArray:= - matchcontinue (valueArray, pos) - local - array>> arr_1, arr; - Integer n, size; - case (VALUE_ARRAY(n, size, arr), pos) - equation - (pos < size) = true; - arr_1 = arrayUpdate(arr, pos + 1, NONE); - then - VALUE_ARRAY(n, size, arr_1); - case (_, _) - equation - print("-HashTableCrefToSimVar.valueArrayClearnth failed\n"); - then - fail(); - end matchcontinue; - end valueArrayClearnth; - */ -public function valueArrayNth "author: PA - - Retrieve the n:th Vale from ValueArray, index from 0..n-1. - " - input SimCode.ValueArray valueArray; - input Integer pos; - output SimCode.Key key; - output SimCode.Value value; -algorithm - (key, value) := - matchcontinue (valueArray, pos) - local - SimCode.Key k; - SimCode.Value v; - Integer n; - array>> arr; - case (SimCode.VALUE_ARRAY(numberOfElements = n, valueArray = arr), _) - equation - (pos < n) = true; - SOME((k, v)) = arr[pos + 1]; - then - (k, v); - case (SimCode.VALUE_ARRAY(numberOfElements = n, valueArray = arr), _) - equation - (pos < n) = true; - NONE() = arr[pos + 1]; - then - fail(); - end matchcontinue; -end valueArrayNth; - - -/***** end of HashTable ComponentRef -> SimCodeVar.SimVar *******/ - public function functionInfo input SimCode.Function fn; output SourceInfo info; @@ -11121,27 +8251,6 @@ algorithm end match; end simEqSystemIndex; -function twodigit - input Integer i; - output String outS; -algorithm - outS := - matchcontinue (i) - local String s; - case _ - equation - (i < 10) = true; - s = intString(i); - s = stringAppend("0", s); - then - s; - else intString(i); - end matchcontinue; -end twodigit; - - - - /**************************************/ /************* for index ***************/ @@ -11591,20 +8700,6 @@ algorithm result := index1 > index2; end compareVarIndexGt; -public function varIndex - input SimCodeVar.SimVar var; - output Integer index; -algorithm - SimCodeVar.SIMVAR(index=index) := var; -end varIndex; - -public function varName - input SimCodeVar.SimVar var; - output DAE.ComponentRef name; -algorithm - SimCodeVar.SIMVAR(name=name) := var; -end varName; - public function countDynamicExternalFunctions input list inFncLst; output Integer outDynLoadFuncs; @@ -12750,16 +9845,6 @@ algorithm tpl := (eqs, i); end eqSystemWCET; -public function isParallelFunctionContext - input SimCode.Context context; - output Boolean outBool; -algorithm - outBool := match(context) - case (SimCode.PARALLEL_FUNCTION_CONTEXT()) then true; - else false; - end match; -end isParallelFunctionContext; - protected function getProtected input Option attr; output Boolean b; @@ -13204,64 +10289,6 @@ algorithm oMapping := arrayUpdate(iMapping,simVarIdx,SOME(simVar)); end createAllSCVarMapping1; - -protected function aliasRecordDeclarations - input SimCode.RecordDeclaration inDecl; - input HashTableStringToPath.HashTable inHt; - output SimCode.RecordDeclaration decl; - output HashTableStringToPath.HashTable ht; -algorithm - (decl,ht) := match (inDecl,inHt) - local - list vars; - Absyn.Path name; - String str,sname; - Option alias; - case (SimCode.RECORD_DECL_FULL(sname, _, name, vars),_) - equation - str = stringDelimitList(List.map(vars, variableString), "\n"); - (alias,ht) = aliasRecordDeclarations2(str, name, inHt); - then (SimCode.RECORD_DECL_FULL(sname, alias, name, vars),ht); - else (inDecl,inHt); - end match; -end aliasRecordDeclarations; - -protected function aliasRecordDeclarations2 - input String str; - input Absyn.Path path; - input HashTableStringToPath.HashTable inHt; - output Option alias; - output HashTableStringToPath.HashTable ht; -algorithm - (alias,ht) := matchcontinue (str,path,inHt) - local - String aliasStr; - case (_,_,_) - equation - aliasStr = Absyn.pathStringUnquoteReplaceDot(BaseHashTable.get(str, inHt),"_"); - then (SOME(aliasStr),inHt); - else - equation - ht = BaseHashTable.add((str,path),inHt); - then (NONE(),ht); - end matchcontinue; -end aliasRecordDeclarations2; - -protected function variableString - input SimCode.Variable var; - output String str; -algorithm - str := match var - local - DAE.ComponentRef name; - DAE.Type ty; - case SimCode.VARIABLE(name=name, ty=ty) - then Types.unparseType(ty) + " " + ComponentReference.printComponentRefStr(name); - case SimCode.FUNCTION_PTR(name=str) - then "modelica_fnptr " + str; - end match; -end variableString; - public function getEnumerationTypes input SimCodeVar.SimVars inVars; output list outVars; @@ -13378,24 +10405,6 @@ algorithm end match; end enumerationTypeExists; -protected function variableName - input SimCode.Variable v; - output String s; -algorithm - s := match v - case SimCode.VARIABLE(name=DAE.CREF_IDENT(ident=s)) then s; - case SimCode.FUNCTION_PTR(name=s) then s; - end match; -end variableName; - -protected function compareVariable - input SimCode.Variable v1; - input SimCode.Variable v2; - output Boolean b; -algorithm - b := stringCompare(variableName(v1),variableName(v2)) > 0; -end compareVariable; - public function equationIndexEqual input SimCode.SimEqSystem eq1; input SimCode.SimEqSystem eq2; @@ -13603,7 +10612,7 @@ algorithm vars = BackendVariable.equationSystemsVarsLst(eqs,{}); crefs = List.map(vars,BackendVariable.varCref); bVarIdcs = List.intRange(listLength(crefs)); - simVars = List.map1(crefs,get,ht); + simVars = List.map1(crefs,SimCodeFunctionUtil.get,ht); simVarIdcs = List.map2(simVars,getSimVarIndex,varInfo,allVars); varMapping = makeVarMapTuple(simVarIdcs,bVarIdcs,{}); List.fold1(simVars, fillSimVarMapping, simVarMapping, 1); @@ -14050,7 +11059,7 @@ algorithm case(SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(vars=simVars,residual=residual))) equation crefs2 = List.flatten(List.map(residual,getSimEqSystemCrefsLHS)); - crefs = List.map(simVars,varName); + crefs = list(SimCodeFunctionUtil.varName(v) for v in simVars); crefs = listAppend(crefs,crefs2); then crefs; case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(crefs=crefs))) @@ -14058,8 +11067,8 @@ algorithm then crefs; case(SimCode.SES_MIXED(discVars=simVars)) equation - crefs = List.map(simVars,varName); - then crefs; + crefs = list(SimCodeFunctionUtil.varName(v) for v in simVars); + then crefs; case(SimCode.SES_WHEN(left=cref)) equation then {cref}; @@ -15003,95 +12012,6 @@ algorithm end match; end getVariableIndex; -public function generateSubPalceholders - input DAE.ComponentRef cr; - output String outdef; -protected - list dims; - Integer nrdims; - list idxstrlst; -algorithm - dims := ComponentReference.crefDims(cr); - nrdims := listLength(dims); - idxstrlst := List.map(List.intRange(nrdims),intString); - outdef := stringDelimitList(List.threadMap(List.fill("i_", nrdims), idxstrlst, stringAppend), ","); -end generateSubPalceholders; - -public function execStat - "Prints an execution stat on the format: - *** %name% -> time: %time%, memory %memory% - Where you provide name, and time is the time since the last call using this - index (the clock is reset after each call). The memory is the total memory - consumed by the compiler at this point in time. - " - input String name; -algorithm - execStat2(Flags.isSet(Flags.EXEC_STAT),name); -end execStat; - -protected function execStat2 - input Boolean cond; - input String name; -algorithm - _ := match (cond,name) - local - Real t,total,used,allocated; - String timeStr,totalTimeStr,gcStr; - case (false,_) then (); - else - equation - t = System.realtimeTock(ClockIndexes.RT_CLOCK_EXECSTAT); - total = System.realtimeTock(ClockIndexes.RT_CLOCK_EXECSTAT_CUMULATIVE); - gcStr = GC.profStatsStr(GC.getProfStats(), head=""); - timeStr = System.snprintff("%.4g",20,t); - totalTimeStr = System.snprintff("%.4g",20,total); - if Flags.isSet(Flags.GC_PROF) then - Error.addMessage(Error.EXEC_STAT_GC,{name,timeStr,totalTimeStr,gcStr}); - else - Error.addMessage(Error.EXEC_STAT,{name,timeStr,totalTimeStr}); - end if; - System.realtimeTick(ClockIndexes.RT_CLOCK_EXECSTAT); - then (); - end match; -end execStat2; - -public - -function codegenResetTryThrowIndex -algorithm - setGlobalRoot(Global.codegenTryThrowIndex, {}); -end codegenResetTryThrowIndex; - -function codegenPushTryThrowIndex - input Integer i; -protected - list lst; -algorithm - lst := getGlobalRoot(Global.codegenTryThrowIndex); - setGlobalRoot(Global.codegenTryThrowIndex, i::lst); -end codegenPushTryThrowIndex; - -function codegenPopTryThrowIndex -protected - list lst; -algorithm - lst := getGlobalRoot(Global.codegenTryThrowIndex); - _::lst := lst; - setGlobalRoot(Global.codegenTryThrowIndex, lst); -end codegenPopTryThrowIndex; - -function codegenPeekTryThrowIndex - output Integer i; -protected - list lst; -algorithm - lst := getGlobalRoot(Global.codegenTryThrowIndex); - i := match lst - case i::_ then i; - else -1; - end match; -end codegenPeekTryThrowIndex; - protected function getHighestDerivation"computes the highest derivative among all states. this includes derivatives of derivatives as well author: waurich TUD 2015-05" input BackendDAE.BackendDAE inDAE; diff --git a/Compiler/Stubs/BackendDAECreate.mo b/Compiler/Stubs/BackendDAECreate.mo new file mode 100644 index 00000000000..ee0e5911796 --- /dev/null +++ b/Compiler/Stubs/BackendDAECreate.mo @@ -0,0 +1,16 @@ +encapsulated package BackendDAECreate + +import BackendDAE; + +function lower + input A a; + input B b; + input C c; + input D d; + output BackendDAE.BackendDAE outBackendDAE; +algorithm + assert(false, getInstanceName()); +end lower; + +annotation(__OpenModelica_Interface="backend"); +end BackendDAECreate; diff --git a/Compiler/Stubs/BackendDAEOptimize.mo b/Compiler/Stubs/BackendDAEOptimize.mo new file mode 100644 index 00000000000..2b2af4155d6 --- /dev/null +++ b/Compiler/Stubs/BackendDAEOptimize.mo @@ -0,0 +1,11 @@ +encapsulated package BackendDAEOptimize + +function applyRewriteRulesBackend + input T inDAE; + output T outDAE; +algorithm + assert(false, getInstanceName()); +end applyRewriteRulesBackend; + +annotation(__OpenModelica_Interface="backend"); +end BackendDAEOptimize; diff --git a/Compiler/Stubs/BackendDAETransform.mo b/Compiler/Stubs/BackendDAETransform.mo new file mode 100644 index 00000000000..4a21db32ec2 --- /dev/null +++ b/Compiler/Stubs/BackendDAETransform.mo @@ -0,0 +1,3 @@ +encapsulated package BackendDAETransform +annotation(__OpenModelica_Interface="backend"); +end BackendDAETransform; diff --git a/Compiler/Stubs/BackendDAEUtil.mo b/Compiler/Stubs/BackendDAEUtil.mo new file mode 100644 index 00000000000..80388db77bc --- /dev/null +++ b/Compiler/Stubs/BackendDAEUtil.mo @@ -0,0 +1,54 @@ +encapsulated package BackendDAEUtil + +import BackendDAE; + +function getSolvedSystem + input A inDAE; + input String fileNamePrefix; + input Option> strPreOptModules = NONE(); + input Option strmatchingAlgorithm = NONE(); + input Option strdaeHandler = NONE(); + input Option> strPostOptModules = NONE(); + output A outSODE; +algorithm + assert(false, getInstanceName()); +end getSolvedSystem; + +function preOptimizeBackendDAE + input T inDAE; + input Option> strPreOptModules; + output T outDAE; +algorithm + assert(false, getInstanceName()); +end preOptimizeBackendDAE; + +function transformBackendDAE + input A inDAE; + input Option inMatchingOptions; + input Option strmatchingAlgorithm; + input Option strindexReductionMethod; + output A outDAE; +algorithm + assert(false, getInstanceName()); +end transformBackendDAE; + +function getIncidenceMatrixfromOption + input BackendDAE.EqSystem inSyst; + input BackendDAE.IndexType inIndxType; + input Option inFunctionTree; + output BackendDAE.EqSystem outSyst; + output BackendDAE.IncidenceMatrix outM; + output BackendDAE.IncidenceMatrix outMT; +algorithm + assert(false, getInstanceName()); +end getIncidenceMatrixfromOption; + +function getAllVarLst + input BackendDAE.BackendDAE dae; + output list varLst; +algorithm + assert(false, getInstanceName()); +end getAllVarLst; + +annotation(__OpenModelica_Interface="backend"); +end BackendDAEUtil; diff --git a/Compiler/Stubs/BackendDump.mo b/Compiler/Stubs/BackendDump.mo new file mode 100644 index 00000000000..7234fc0e298 --- /dev/null +++ b/Compiler/Stubs/BackendDump.mo @@ -0,0 +1,11 @@ +encapsulated package BackendDump + +function dumpJacobianStr + input A a; + output String outString; +algorithm + assert(false, getInstanceName()); +end dumpJacobianStr; + +annotation(__OpenModelica_Interface="backend"); +end BackendDump; diff --git a/Compiler/Stubs/BackendEquation.mo b/Compiler/Stubs/BackendEquation.mo new file mode 100644 index 00000000000..5839e59ea75 --- /dev/null +++ b/Compiler/Stubs/BackendEquation.mo @@ -0,0 +1,13 @@ +encapsulated package BackendEquation + +import BackendDAE; + +function getEqnsFromEqSystem + input BackendDAE.EqSystem inEqSystem; + output BackendDAE.EquationArray outOrderedEqs; +algorithm + assert(false, getInstanceName()); +end getEqnsFromEqSystem; + +annotation(__OpenModelica_Interface="backend"); +end BackendEquation; diff --git a/Compiler/Stubs/BackendQSS.mo b/Compiler/Stubs/BackendQSS.mo new file mode 100644 index 00000000000..1553cfffdc4 --- /dev/null +++ b/Compiler/Stubs/BackendQSS.mo @@ -0,0 +1,3 @@ +encapsulated package BackendQSS +annotation(__OpenModelica_Interface="backend"); +end BackendQSS; diff --git a/Compiler/Stubs/BackendVarTransform.mo b/Compiler/Stubs/BackendVarTransform.mo new file mode 100644 index 00000000000..c7ab989964b --- /dev/null +++ b/Compiler/Stubs/BackendVarTransform.mo @@ -0,0 +1,3 @@ +encapsulated package BackendVarTransform +annotation(__OpenModelica_Interface="backend"); +end BackendVarTransform; diff --git a/Compiler/Stubs/BackendVariable.mo b/Compiler/Stubs/BackendVariable.mo new file mode 100644 index 00000000000..a115ea3d52e --- /dev/null +++ b/Compiler/Stubs/BackendVariable.mo @@ -0,0 +1,37 @@ +encapsulated package BackendVariable + +import BackendDAE; + +function getVar + input A cr; + input B inVariables; + output list outVarLst; + output list outIntegerLst; +algorithm + assert(false, getInstanceName()); +end getVar; + +function daeVars + input BackendDAE.EqSystem syst; + output BackendDAE.Variables vars; +algorithm + assert(false, getInstanceName()); +end daeVars; + +function varEqual + input A inVar1; + input A inVar2; + output Boolean outBoolean; +algorithm + assert(false, getInstanceName()); +end varEqual; + +function isStateVar + input A inVar; + output Boolean outBoolean; +algorithm + assert(false, getInstanceName()); +end isStateVar; + +annotation(__OpenModelica_Interface="backend"); +end BackendVariable; diff --git a/Compiler/Stubs/BlockCallRewrite.mo b/Compiler/Stubs/BlockCallRewrite.mo new file mode 100644 index 00000000000..6384e692f59 --- /dev/null +++ b/Compiler/Stubs/BlockCallRewrite.mo @@ -0,0 +1,11 @@ +encapsulated package BlockCallRewrite + +function rewriteBlockCall + input A a,b; + output A c; +algorithm + assert(false, getInstanceName()); +end rewriteBlockCall; + +annotation(__OpenModelica_Interface="backend"); +end BlockCallRewrite; diff --git a/Compiler/Stubs/CodegenFMU.mo b/Compiler/Stubs/CodegenFMU.mo new file mode 100644 index 00000000000..13a8489ba00 --- /dev/null +++ b/Compiler/Stubs/CodegenFMU.mo @@ -0,0 +1,12 @@ +encapsulated package CodegenFMU + +function importFMUModelica + input A in_txt; + input B in_a_fmi; + output A out_txt; +algorithm + assert(false, getInstanceName()); +end importFMUModelica; + +annotation(__OpenModelica_Interface="backend"); +end CodegenFMU; diff --git a/Compiler/Stubs/DAEQuery.mo b/Compiler/Stubs/DAEQuery.mo new file mode 100644 index 00000000000..4aaea84ee32 --- /dev/null +++ b/Compiler/Stubs/DAEQuery.mo @@ -0,0 +1,13 @@ +encapsulated package DAEQuery + +function writeIncidenceMatrix + input T dlow; + input String fileNamePrefix; + input String flatModelicaStr; + output String fileName; +algorithm + assert(false, getInstanceName()); +end writeIncidenceMatrix; + +annotation(__OpenModelica_Interface="backend"); +end DAEQuery; diff --git a/Compiler/Stubs/DiffAlgorithm.mo b/Compiler/Stubs/DiffAlgorithm.mo new file mode 100644 index 00000000000..61ba3952e69 --- /dev/null +++ b/Compiler/Stubs/DiffAlgorithm.mo @@ -0,0 +1,39 @@ +encapsulated package DiffAlgorithm + +type Diff = Integer; + +function diff + input list seq1; + input list seq2; + input F equals; + output list>> out; +algorithm + assert(false, getInstanceName()); +end diff; + +function printActual + input A seq; + input B toString; + output String res; +algorithm + assert(false, getInstanceName()); +end printActual; + +function printDiffTerminalColor + input A seq; + input B toString; + output String res; +algorithm + assert(false, getInstanceName()); +end printDiffTerminalColor; + +function printDiffXml + input A seq; + input B toString; + output String res; +algorithm + assert(false, getInstanceName()); +end printDiffXml; + +annotation(__OpenModelica_Interface="util"); +end DiffAlgorithm; diff --git a/Compiler/Stubs/Differentiate.mo b/Compiler/Stubs/Differentiate.mo new file mode 100644 index 00000000000..8059595e793 --- /dev/null +++ b/Compiler/Stubs/Differentiate.mo @@ -0,0 +1,3 @@ +encapsulated package Differentiate +annotation(__OpenModelica_Interface="backend"); +end Differentiate; diff --git a/Compiler/Stubs/ExpressionSolve.mo b/Compiler/Stubs/ExpressionSolve.mo new file mode 100644 index 00000000000..3eb59f44775 --- /dev/null +++ b/Compiler/Stubs/ExpressionSolve.mo @@ -0,0 +1,3 @@ +encapsulated package ExpressionSolve +annotation(__OpenModelica_Interface="backend"); +end ExpressionSolve; diff --git a/Compiler/Stubs/Figaro.mo b/Compiler/Stubs/Figaro.mo new file mode 100644 index 00000000000..c3c69e99963 --- /dev/null +++ b/Compiler/Stubs/Figaro.mo @@ -0,0 +1,12 @@ +encapsulated package Figaro + +function run + input A inProgram; + input B inPath; + input String a,b,c,d,e; +algorithm + assert(false, getInstanceName()); +end run; + +annotation(__OpenModelica_Interface="backend"); +end Figaro; diff --git a/Compiler/Stubs/FindZeroCrossings.mo b/Compiler/Stubs/FindZeroCrossings.mo new file mode 100644 index 00000000000..170de170e51 --- /dev/null +++ b/Compiler/Stubs/FindZeroCrossings.mo @@ -0,0 +1,11 @@ +encapsulated package FindZeroCrossings + +function findZeroCrossings + input T inDAE; + output T outDAE; +algorithm + assert(false, getInstanceName()); +end findZeroCrossings; + +annotation(__OpenModelica_Interface="backend"); +end FindZeroCrossings; diff --git a/Compiler/Stubs/HpcOmSimCodeMain.mo b/Compiler/Stubs/HpcOmSimCodeMain.mo new file mode 100644 index 00000000000..d295b2c12a6 --- /dev/null +++ b/Compiler/Stubs/HpcOmSimCodeMain.mo @@ -0,0 +1,20 @@ +encapsulated package HpcOmSimCodeMain + +function getSimCodeEqByIndexAndMapping + input array> iSimEqIdxSimEqMapping; //All SimEqSystems + input Integer iIdx; //The index of the required system + output T oSimEqSystem; +algorithm + assert(false, getInstanceName()); +end getSimCodeEqByIndexAndMapping; + +function getSimCodeEqByIndex + input list iEqs; + input Integer iIdx; + output T oEq; +algorithm + assert(false, getInstanceName()); +end getSimCodeEqByIndex; + +annotation(__OpenModelica_Interface="backend"); +end HpcOmSimCodeMain; diff --git a/Compiler/Stubs/HpcOmTaskGraph.mo b/Compiler/Stubs/HpcOmTaskGraph.mo new file mode 100644 index 00000000000..4776fcbdce9 --- /dev/null +++ b/Compiler/Stubs/HpcOmTaskGraph.mo @@ -0,0 +1,3 @@ +encapsulated package HpcOmTaskGraph +annotation(__OpenModelica_Interface="backend"); +end HpcOmTaskGraph; diff --git a/Compiler/Stubs/Initialization.mo b/Compiler/Stubs/Initialization.mo new file mode 100644 index 00000000000..98820afd84d --- /dev/null +++ b/Compiler/Stubs/Initialization.mo @@ -0,0 +1,3 @@ +encapsulated package Initialization +annotation(__OpenModelica_Interface="backend"); +end Initialization; diff --git a/Compiler/Stubs/LexerModelicaDiff.mo b/Compiler/Stubs/LexerModelicaDiff.mo new file mode 100644 index 00000000000..aff2be9f2c3 --- /dev/null +++ b/Compiler/Stubs/LexerModelicaDiff.mo @@ -0,0 +1,36 @@ +encapsulated package LexerModelicaDiff + +type Token=Integer; +type TokenId=Integer; + +function scanString + input String fileSource; + output list tokens; +algorithm + assert(false, getInstanceName()); +end scanString; + +function tokenContent + input A token; + output String contents; +algorithm + assert(false, getInstanceName()); +end tokenContent; + +function modelicaDiffTokenEq + input T a,b; + output Boolean o; +algorithm + assert(false, getInstanceName()); +end modelicaDiffTokenEq; + +function filterModelicaDiff + input A diffs; + input Boolean removeWhitespace=true; + output A odiffs; +algorithm + assert(false, getInstanceName()); +end filterModelicaDiff; + +annotation(__OpenModelica_Interface="backend"); +end LexerModelicaDiff; diff --git a/Compiler/Stubs/OpenTURNS.mo b/Compiler/Stubs/OpenTURNS.mo new file mode 100644 index 00000000000..324bb611d30 --- /dev/null +++ b/Compiler/Stubs/OpenTURNS.mo @@ -0,0 +1,25 @@ +encapsulated package OpenTURNS + +function runPythonScript + input String inStrPythonScriptFile; + output String outStrLogFile; +algorithm + assert(false, getInstanceName()); +end runPythonScript; + +function generateOpenTURNSInterface + input A a; + input B b; + input C c; + input D d; + input E e; + input F f; + input G g; + input String h; + output String i; +algorithm + assert(false, getInstanceName()); +end generateOpenTURNSInterface; + +annotation(__OpenModelica_Interface="backend"); +end OpenTURNS; diff --git a/Compiler/Stubs/Refactor.mo b/Compiler/Stubs/Refactor.mo new file mode 100644 index 00000000000..380878089d3 --- /dev/null +++ b/Compiler/Stubs/Refactor.mo @@ -0,0 +1,12 @@ +encapsulated package Refactor + +function refactorGraphicalAnnotation + input A wholeAST; + input B classToRefactor; + output B changedClass; +algorithm + assert(false, getInstanceName()); +end refactorGraphicalAnnotation; + +annotation(__OpenModelica_Interface="backend"); +end Refactor; diff --git a/Compiler/Stubs/RewriteRules.mo b/Compiler/Stubs/RewriteRules.mo new file mode 100644 index 00000000000..bd741d9040d --- /dev/null +++ b/Compiler/Stubs/RewriteRules.mo @@ -0,0 +1,28 @@ +encapsulated package RewriteRules + +function rewriteFrontEnd + input A inExp; + output A outExp = inExp; + output Boolean isChanged = false; +end rewriteFrontEnd; + +function noRewriteRulesFrontEnd + output Boolean noRules = true; +end noRewriteRulesFrontEnd; + +function noRewriteRulesBackEnd + output Boolean noRules = true; +end noRewriteRulesBackEnd; + +function loadRules +algorithm + assert(false, getInstanceName()); +end loadRules; + +function clearRules +algorithm + assert(false, getInstanceName()); +end clearRules; + +annotation(__OpenModelica_Interface="frontend"); +end RewriteRules; diff --git a/Compiler/Stubs/SimCodeDump.mo b/Compiler/Stubs/SimCodeDump.mo new file mode 100644 index 00000000000..95b1f2c8e41 --- /dev/null +++ b/Compiler/Stubs/SimCodeDump.mo @@ -0,0 +1,3 @@ +encapsulated package SimCodeDump +annotation(__OpenModelica_Interface="backend"); +end SimCodeDump; diff --git a/Compiler/Stubs/SimCodeMain.mo b/Compiler/Stubs/SimCodeMain.mo new file mode 100644 index 00000000000..c55ec62bed9 --- /dev/null +++ b/Compiler/Stubs/SimCodeMain.mo @@ -0,0 +1,99 @@ +encapsulated package SimCodeMain + +import BackendDAE; +import SimCode; +import Values; + +function createSimulationSettings + input Real startTime; + input Real stopTime; + input Integer inumberOfIntervals; + input Real tolerance; + input String method; + input String options; + input String outputFormat; + input String variableFilter; + input String cflags; + output SimCode.SimulationSettings simSettings; +algorithm + assert(false, getInstanceName()); +end createSimulationSettings; + +function generateModelCode + input T inBackendDAE; + input A p; + input B dae; + input C className; + input String filenamePrefix; + input D simSettingsOpt; + input E args; + output T outIndexedBackendDAE; + output list libs; + output String fileDir; + output Real timeSimCode; + output Real timeTemplates; +algorithm + assert(false, getInstanceName()); +end generateModelCode; + +function translateModelXML + input A inCache; + input B inEnv; + input C className; + input D inInteractiveSymbolTable; + input String inFileNamePrefix; + input Boolean addDummy; + input Option inSimSettingsOpt; + output A outCache; + output Values.Value outValue; + output D outInteractiveSymbolTable; + output BackendDAE.BackendDAE outBackendDAE; + output list outStringLst; + output String outFileDir; + output list> resultValues; +algorithm + assert(false, getInstanceName()); +end translateModelXML; + +function translateModel + input A inCache; + input B inEnv; + input C className; + input D inInteractiveSymbolTable; + input String inFileNamePrefix; + input Boolean addDummy; + input Option inSimSettingsOpt; + input F args; + output A outCache; + output D outInteractiveSymbolTable; + output BackendDAE.BackendDAE outBackendDAE; + output list outStringLst; + output String outFileDir; + output list> resultValues; +algorithm + assert(false, getInstanceName()); +end translateModel; + +function translateModelFMU + input A inCache; + input B inEnv; + input C className; + input D inInteractiveSymbolTable; + input String inFMUVersion; + input String inFMUType; + input String inFileNamePrefix; + input Boolean addDummy; + input Option inSimSettingsOpt; + output A outCache; + output Values.Value outValue; + output D outInteractiveSymbolTable; + output BackendDAE.BackendDAE outBackendDAE; + output list outStringLst; + output String outFileDir; + output list> resultValues; +algorithm + assert(false, getInstanceName()); +end translateModelFMU; + +annotation(__OpenModelica_Interface="backend"); +end SimCodeMain; diff --git a/Compiler/Stubs/SimCodeUtil.mo b/Compiler/Stubs/SimCodeUtil.mo new file mode 100644 index 00000000000..866fdd07dc4 --- /dev/null +++ b/Compiler/Stubs/SimCodeUtil.mo @@ -0,0 +1,20 @@ +encapsulated package SimCodeUtil + +import SimCode; + +function sortEqSystems + input T eqs; + output T outEqs; +algorithm + assert(false, getInstanceName()); +end sortEqSystems; + +public function eqInfo + input T eq; + output SourceInfo info; +algorithm + assert(false, getInstanceName()); +end eqInfo; + +annotation(__OpenModelica_Interface="backend"); +end SimCodeUtil; diff --git a/Compiler/Stubs/SymbolicJacobian.mo b/Compiler/Stubs/SymbolicJacobian.mo new file mode 100644 index 00000000000..bc552b8f812 --- /dev/null +++ b/Compiler/Stubs/SymbolicJacobian.mo @@ -0,0 +1,18 @@ +encapsulated package SymbolicJacobian + +import BackendDAE; + +function calculateJacobian + input BackendDAE.Variables inVariables; + input BackendDAE.EquationArray inEquationArray; + input BackendDAE.IncidenceMatrix inIncidenceMatrix; + input Boolean differentiateIfExp; + input BackendDAE.Shared iShared; + output Option>> outTplIntegerIntegerEquationLstOption; + output BackendDAE.Shared oShared; +algorithm + assert(false, getInstanceName()); +end calculateJacobian; + +annotation(__OpenModelica_Interface="backend"); +end SymbolicJacobian; diff --git a/Compiler/Stubs/TaskSystemDump.mo b/Compiler/Stubs/TaskSystemDump.mo new file mode 100644 index 00000000000..661cfb5a3b6 --- /dev/null +++ b/Compiler/Stubs/TaskSystemDump.mo @@ -0,0 +1,3 @@ +encapsulated package TaskSystemDump +annotation(__OpenModelica_Interface="backend"); +end TaskSystemDump; diff --git a/Compiler/Stubs/Uncertainties.mo b/Compiler/Stubs/Uncertainties.mo new file mode 100644 index 00000000000..4d9abf365c1 --- /dev/null +++ b/Compiler/Stubs/Uncertainties.mo @@ -0,0 +1,20 @@ +encapsulated package Uncertainties + +import Values; + +function modelEquationsUC + input A inCache; + input B inEnv; + input C className; + input D inInteractiveSymbolTable; + input String outputFileIn; + input Boolean dumpSteps; + output A outCache; + output Values.Value outValue; + output D outInteractiveSymbolTable; +algorithm + assert(false, getInstanceName()); +end modelEquationsUC; + +annotation(__OpenModelica_Interface="backend"); +end Uncertainties; diff --git a/Compiler/Stubs/Vectorization.mo b/Compiler/Stubs/Vectorization.mo new file mode 100644 index 00000000000..a437b87e208 --- /dev/null +++ b/Compiler/Stubs/Vectorization.mo @@ -0,0 +1,3 @@ +encapsulated package Vectorization +annotation(__OpenModelica_Interface="backend"); +end Vectorization; diff --git a/Compiler/Stubs/VisualXML.mo b/Compiler/Stubs/VisualXML.mo new file mode 100644 index 00000000000..07eddd35625 --- /dev/null +++ b/Compiler/Stubs/VisualXML.mo @@ -0,0 +1,3 @@ +encapsulated package VisualXML +annotation(__OpenModelica_Interface="backend"); +end VisualXML; diff --git a/Compiler/Stubs/XMLDump.mo b/Compiler/Stubs/XMLDump.mo new file mode 100644 index 00000000000..cc26c9c72c3 --- /dev/null +++ b/Compiler/Stubs/XMLDump.mo @@ -0,0 +1,15 @@ +encapsulated package XMLDump + +function dumpBackendDAE + input T inBackendDAE; + input Boolean addOriginalIncidenceMatrix; + input Boolean addSolvingInfo; + input Boolean addMathMLCode; + input Boolean dumpResiduals; + input Boolean dumpSolvedEquations; +algorithm + assert(false, getInstanceName()); +end dumpBackendDAE; + +annotation(__OpenModelica_Interface="backend"); +end XMLDump; diff --git a/Compiler/Template/CodegenC.tpl b/Compiler/Template/CodegenC.tpl index ee0cf607b81..fdb2fc0ab91 100644 --- a/Compiler/Template/CodegenC.tpl +++ b/Compiler/Template/CodegenC.tpl @@ -48,7 +48,6 @@ package CodegenC import interface SimCodeTV; import CodegenUtil.*; - /* public */ template translateModel(SimCode simCode, String guid) "Generates C code and Makefile for compiling and running a simulation of a Modelica model. @@ -1095,7 +1094,7 @@ template crefMacroSubsAtEndParNew(ComponentRef cr) let nosubfullpath = contextCref(crefStripSubs(cr),contextSimulationNonDiscrete, &auxFunction) let totnrdims = listLength(crefDims(cr)) let dimstr = crefDims(cr) |> dim => dimension(dim) ;separator=", " - let substr = SimCodeUtil.generateSubPalceholders(cr) + let substr = generateSubPalceholders(cr) let &subsDimThread = buffer "" /*BUFD*/ << #define <%nosubfullpath%>_index(<%substr%>) (&<%fullpath%>)[calc_base_index_dims_subs(<%totnrdims%>, <%dimstr%>, <%substr%>)] @@ -1109,7 +1108,7 @@ template crefMacroSubsAtEndVarNew(ComponentRef cr) let nosubfullpath = contextCref(crefStripSubs(cr),contextSimulationNonDiscrete, &auxFunction) let totnrdims = listLength(crefDims(cr)) let dimstr = crefDims(cr) |> dim => dimension(dim) ;separator=", " - let substr = SimCodeUtil.generateSubPalceholders(cr) + let substr = generateSubPalceholders(cr) let &subsDimThread = buffer "" /*BUFD*/ << #define <%nosubfullpath%>_index(<%substr%>) (&<%fullpath%>)[calc_base_index_dims_subs(<%totnrdims%>, <%dimstr%>, <%substr%>)] @@ -6599,7 +6598,7 @@ template funArgBox(String outName, String varName, String condition, Type ty, Te let &varUnbox += if condition then 'if (<%condition%>) { <%outName%> = <%constructor%>; }<%\n%>' else '<%outName%> = <%constructor%>;<%\n%>' outName else // Some types don't need to be boxed, since they're already boxed. - let &varUnbox += '/* skip box <%varName%>; <%unparseType(ty)%> */' + let &varUnbox += '/* skip box <%varName%>; <%unparseType(ty)%> */<%\n%>' varName end funArgBox; @@ -9607,7 +9606,7 @@ template daeExpCallTuple(Exp call, Text additionalOutputs /* arguments 2..N */, let closure = '(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(<%name%>), 2)))' let argStrPointer = ('threadData, <%closure%>' + (expLst |> exp => (", " + daeExp(exp, context, &preExp, &varDecls, &auxFunction)))) //'<%name%>(<%argStr%><%additionalOutputs%>)' - '/*Closure?*/<%closure%> ? (<%typeCast1%> <%func%>) (<%argStrPointer%><%additionalOutputs%>) : (<%typeCast2%> <%func%>) (<%argStr%><%additionalOutputs%>)' + '<%closure%> ? (<%typeCast1%> <%func%>) (<%argStrPointer%><%additionalOutputs%>) : (<%typeCast2%> <%func%>) (<%argStr%><%additionalOutputs%>)' else let name = '<% if attr.builtin then "" else "omc_" %><%underscorePath(path)%>' '<%name%>(<%argStr%><%additionalOutputs%>)' @@ -10393,7 +10392,7 @@ match exp case exp as UNBOX(__) then let ty = expTypeShort(exp.ty) let res = daeExp(exp.exp,context,&preExp,&varDecls, &auxFunction) - 'mmc_unbox_<%ty%>(<%res%>) /* DAE.UNBOX <%unparseType(exp.ty) %> */' + 'mmc_unbox_<%ty%>(<%res%>)' end daeExpUnbox; template daeExpSharedLiteral(Exp exp) diff --git a/Compiler/Template/CodegenCSharp.tpl b/Compiler/Template/CodegenCSharp.tpl index 1ea9c94278b..c07dec259d9 100644 --- a/Compiler/Template/CodegenCSharp.tpl +++ b/Compiler/Template/CodegenCSharp.tpl @@ -17,7 +17,7 @@ end translateModel; template wrapIntoExtraFileIfModelTooBig(Text txtCode, String fileNamePostfix, SimCode simCode) ::= match simCode case SIMCODE(modelInfo = MODELINFO(__)) then - if SimCodeUtil.isModelTooBigForCSharpInOneFile(simCode) then + if isModelTooBigForCSharpInOneFile(simCode) then let wrappedCode = << // Simulation code for <%dotPath(modelInfo.name)%> generated by the OpenModelica Compiler. diff --git a/Compiler/Template/CodegenCpp.tpl b/Compiler/Template/CodegenCpp.tpl index 712c76d1a4d..8ea63f1ca95 100644 --- a/Compiler/Template/CodegenCpp.tpl +++ b/Compiler/Template/CodegenCpp.tpl @@ -1217,7 +1217,7 @@ case SIMCODE(modelInfo=MODELINFO(__)) then template createAssignArray(DAE.ComponentRef sourceOrTargetArrayCref, String sourceArrayName, String targetArrayName, SimCode simCode ,Text& extraFuncs,Text& extraFuncsDecl,Text extraFuncsNamespace, Boolean useFlatArrayNotationSource, Boolean useFlatArrayNotationTarget, String dimsArrayName) ::= - match SimCodeUtil.cref2simvar(sourceOrTargetArrayCref, simCode) + match cref2simvar(sourceOrTargetArrayCref, simCode) case v as SIMVAR(numArrayElement=num) then '<%targetArrayName%>.assign(<%sourceArrayName%>);' end createAssignArray; diff --git a/Compiler/Template/CodegenCppHpcom.tpl b/Compiler/Template/CodegenCppHpcom.tpl index 863c36915ab..631835950e3 100644 --- a/Compiler/Template/CodegenCppHpcom.tpl +++ b/Compiler/Template/CodegenCppHpcom.tpl @@ -7,6 +7,7 @@ package CodegenCppHpcom +import interface SimCodeBackendTV; import interface SimCodeTV; import CodegenUtil.*; import CodegenCpp.*; //unqualified import, no need the CodegenC is optional when calling a template; or mandatory when the same named template exists in this package (name hiding) @@ -121,7 +122,7 @@ template generateAdditionalIncludesForParallelCode(SimCode simCode, Text& extraF << #include #include - #include + #include #include #include #if TBB_INTERFACE_VERSION >= 8000 @@ -219,26 +220,26 @@ template generateAdditionalStructHeaders(Schedule odeSchedule) #if TBB_INTERFACE_VERSION >= 8000 struct TbbArenaFunctor { - tbb::flow::graph * g; - tbb::flow::broadcast_node * sn; - - TbbArenaFunctor( ) - { - g = NULL; - sn = NULL; - } - - TbbArenaFunctor( tbb::flow::graph & in_g , tbb::flow::broadcast_node & in_sn ) - { - g = &in_g; - sn = &in_sn; - } - - void operator()() - { - sn->try_put( tbb::flow::continue_msg() ); - g->wait_for_all(); - } + tbb::flow::graph * g; + tbb::flow::broadcast_node * sn; + + TbbArenaFunctor( ) + { + g = NULL; + sn = NULL; + } + + TbbArenaFunctor( tbb::flow::graph & in_g , tbb::flow::broadcast_node & in_sn ) + { + g = &in_g; + sn = &in_sn; + } + + void operator()() + { + sn->try_put( tbb::flow::continue_msg() ); + g->wait_for_all(); + } }; #endif @@ -537,17 +538,17 @@ match(iType) case "openmp" then << for(unsigned i=0;i<<%numComms%>;++i) - omp_init_lock(&<%lockName%>_[i]); + omp_init_lock(&<%lockName%>_[i]); >> case "pthreads" then << for(unsigned i=0;i<<%numComms%>;++i) - <%lockName%>_[i] = new alignedLock(); + <%lockName%>_[i] = new alignedLock(); >> case "pthreads_spin" then << for(unsigned i=0;i<<%numComms%>;++i) - <%lockName%>_[i] = new alignedSpinlock(); + <%lockName%>_[i] = new alignedSpinlock(); >> else << @@ -561,13 +562,13 @@ template assignArrayLocks(Integer numComms, String lockName, String iType) case ("openmp") then << for(unsigned i=0;i<<%numComms%>;++i) - omp_set_lock(&<%lockName%>_[i]); + omp_set_lock(&<%lockName%>_[i]); >> case ("pthreads") case ("pthreads_spin") then << for(unsigned i=0;i<<%numComms%>;++i) - <%lockName%>_[i]->lock(); + <%lockName%>_[i]->lock(); >> else @@ -604,7 +605,7 @@ match(iType) case "openmp" then << for(unsigned i=0;i<<%numComms%>;++i) - omp_destroy_lock(&<%lockName%>_[i]); + omp_destroy_lock(&<%lockName%>_[i]); >> case "pthreads" case "pthreads_spin" then @@ -919,7 +920,7 @@ template generateParallelEvaluate(list allEquationsPlusWhen, Absyn. { //Start #if TBB_INTERFACE_VERSION >= 8000 - _tbbArena.execute(_tbbArenaFunctor); + _tbbArena.execute(_tbbArenaFunctor); #else _tbbStartNode.try_put(tbb::flow::continue_msg()); _tbbGraph.wait_for_all(); @@ -1282,8 +1283,8 @@ template generateThreadFunc(list allEquationsPlusWhen, list t if(_terminateThreads) return; - if(_evaluateODE) - { + if(_evaluateODE) + { <%taskEqsOde%> } else diff --git a/Compiler/Template/CodegenQSS.tpl b/Compiler/Template/CodegenQSS.tpl index 20e0fbf99d2..d8cf4811ac7 100644 --- a/Compiler/Template/CodegenQSS.tpl +++ b/Compiler/Template/CodegenQSS.tpl @@ -51,6 +51,7 @@ package CodegenQSS import interface SimCodeTV; +import interface SimCodeQSSTV; import CodegenUtil.*; import CodegenC.*; diff --git a/Compiler/Template/Makefile.common b/Compiler/Template/Makefile.common index 70a00920270..e4ee8ab04e9 100644 --- a/Compiler/Template/Makefile.common +++ b/Compiler/Template/Makefile.common @@ -77,7 +77,7 @@ SimCodeDump.mo : SimCodeDump.tpl SimCodeTV.mo CodegenUtil.tpl SCodeDumpTpl.tpl $(OMC) $< > $@.log || (cat $@.log && false) @echo " " -CodegenQSS.mo : CodegenQSS.tpl SimCodeTV.mo CodegenC.tpl CodegenUtil.tpl +CodegenQSS.mo : CodegenQSS.tpl SimCodeTV.mo SimCodeQSSTV.mo CodegenC.tpl CodegenUtil.tpl @echo " ** CodegenQSS template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) @echo " " @@ -87,7 +87,7 @@ CodegenCpp.mo : CodegenCpp.tpl SimCodeTV.mo CodegenUtil.tpl CodegenCppInit.tpl $(OMC) $< > $@.log || (cat $@.log && false) @echo " " -CodegenCppHpcom.mo : CodegenCppHpcom.tpl SimCodeTV.mo CodegenCpp.tpl CodegenUtil.tpl +CodegenCppHpcom.mo : CodegenCppHpcom.tpl SimCodeTV.mo SimCodeBackendTV.mo CodegenCpp.tpl CodegenUtil.tpl @echo " ** CodegenCppHpcom template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) @echo " " @@ -107,7 +107,7 @@ ExpressionDumpTpl.mo : ExpressionDumpTpl.tpl ExpressionDumpTV.mo DAEDumpTpl.tpl $(OMC) $< > $@.log || (cat $@.log && false) @echo " " -GraphvizDump.mo : GraphvizDump.tpl +GraphvizDump.mo : GraphvizDump.tpl SimCodeTV.mo SimCodeBackendTV.mo @echo " ** GraphvizDump template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) @echo " " @@ -151,7 +151,7 @@ GenerateAPIFunctionsTpl.mo : GenerateAPIFunctionsTpl.tpl SimCodeTV.mo @echo " ** GenerateAPIFunctionsTpl template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) @echo " " - + VisualXMLTpl.mo : VisualXMLTpl.tpl VisualXMLTplTV.mo @echo " ** VisualXMLTpl template compilation ** " $(OMC) $< > $@.log || (cat $@.log && false) diff --git a/Compiler/Template/SimCodeBackendTV.mo b/Compiler/Template/SimCodeBackendTV.mo new file mode 100644 index 00000000000..c6926928741 --- /dev/null +++ b/Compiler/Template/SimCodeBackendTV.mo @@ -0,0 +1,21 @@ +interface package SimCodeBackendTV + +package BackendVariable + + function isStateVar + input BackendDAE.Var inVar; + output Boolean outBoolean; + end isStateVar; + +end BackendVariable; + +package HpcOmScheduler + function convertFixedLevelScheduleToTaskLists + input HpcOmSimCode.Schedule iOdeSchedule; + input HpcOmSimCode.Schedule iDaeSchedule; + input Integer iNumOfThreads; + output array>,list>>> oThreadLevelTasks; + end convertFixedLevelScheduleToTaskLists; +end HpcOmScheduler; + +end SimCodeBackendTV; diff --git a/Compiler/Template/SimCodeQSSTV.mo b/Compiler/Template/SimCodeQSSTV.mo new file mode 100644 index 00000000000..8971f30cce1 --- /dev/null +++ b/Compiler/Template/SimCodeQSSTV.mo @@ -0,0 +1,145 @@ +interface package SimCodeQSSTV + +package BackendQSS + uniontype QSSinfo "- equation indices in static blocks and DEVS structure" + record QSSINFO + list> stateVarIndex; + list stateVars; + list discreteAlgVars; + list algVars; + BackendDAE.EqSystems eqs; + list zcs; + Integer zc_offset; + end QSSINFO; + end QSSinfo; + + function getStateIndexList + input QSSinfo qssInfo; + output list> refs; + end getStateIndexList; + + function getStates + input QSSinfo qssInfo; + output list refs; + end getStates; + + function getDisc + input QSSinfo qssInfo; + output list refs; + end getDisc; + function replaceVars + input DAE.Exp exp; + input list states; + input list disc; + input list algs; + output DAE.Exp expout; + end replaceVars; + + function replaceCref + input DAE.ComponentRef cr; + input list states; + input list disc; + input list algs; + output String out; + end replaceCref; + + function getAlgs + input QSSinfo qssInfo; + output list refs; + end getAlgs; + + function negate + input DAE.Exp exp; + output DAE.Exp exp_out; + end negate; + + function getEqs + input QSSinfo qssInfo; + output BackendDAE.EquationArray eqs; + end getEqs; + + function generateHandler + input BackendDAE.EquationArray eqs; + input list handlers; + input list states; + input list disc; + input list algs; + input DAE.Exp condition; + input Boolean v; + input list zc_exps; + input Integer offset; + output String out; + end generateHandler; + + + function getRHSVars + input list beqs; + input list vars; + input list> simJac; + input list states; + input list disc; + input list algs; + output list out; + end getRHSVars; + + function getDiscRHSVars + input list beqs; + input list vars; + input list> simJac; + input list states; + input list disc; + input list algs; + output list out; + end getDiscRHSVars; + + + function generateDInit + input list disc; + //input list sample; + input SimCodeVar.SimVars vars; + input Integer acc; + input Integer total; + input Integer nWhenClause; + output String out; + end generateDInit; + + function generateExtraParams + input SimCode.SimEqSystem eq; + input SimCodeVar.SimVars vars; + output String s; + end generateExtraParams; + + function generateInitialParamEquations + input SimCode.SimEqSystem eq; + output String t; + end generateInitialParamEquations; + + function replaceVarsInputs + input DAE.Exp exp; + input list inp; + output DAE.Exp exp_out; + end replaceVarsInputs; + + function simpleWhens + input list i; + output list o; + end simpleWhens; + + function sampleWhens + input list i; + output list o; + end sampleWhens; + + function getZCOffset + input QSSinfo qssInfo; + output Integer o; + end getZCOffset; + + function getZCExps + input QSSinfo qssInfo; + output list exps; + end getZCExps; + +end BackendQSS; + +end SimCodeQSSTV; diff --git a/Compiler/Template/SimCodeTV.mo b/Compiler/Template/SimCodeTV.mo index 18250e489d6..1b9d6d724f7 100644 --- a/Compiler/Template/SimCodeTV.mo +++ b/Compiler/Template/SimCodeTV.mo @@ -731,11 +731,110 @@ package SimCode end SimCode; package SimCodeUtil + function appendLists + input list inEqn1; + input list inEqn2; + output list outEqn; + end appendLists; - function elementVars - input list ld; - output list vars; - end elementVars; + function functionInfo + input SimCode.Function fn; + output builtin.SourceInfo info; + end functionInfo; + + function countDynamicExternalFunctions + input list inFncLst; + output Integer outDynLoadFuncs; + end countDynamicExternalFunctions; + + function eqInfo + input SimCode.SimEqSystem eq; + output builtin.SourceInfo info; + end eqInfo; + + function dimsToAllIndexes + input DAE.Dimensions inDims; + output list> outIndexes; + end dimsToAllIndexes; + + function sortEqSystems + input list eqs; + output list outEqs; + end sortEqSystems; + + function getEnumerationTypes + input SimCodeVar.SimVars inVars; + output list outVars; + end getEnumerationTypes; + + function getFMIModelStructure + input SimCode.SimCode simCode; + input list jacobianMatrixes; + output SimCode.FmiModelStructure outFmiModelStructure; + end getFMIModelStructure; + + function getStateSimVarIndexFromIndex + input list inStateVars; + input Integer inIndex; + output Integer outVariableIndex; + end getStateSimVarIndexFromIndex; + + function getVariableIndex + input SimCodeVar.SimVar inVar; + output Integer outVariableIndex; + end getVariableIndex; + + function getMaxSimEqSystemIndex + input SimCode.SimCode simCode; + output Integer idxOut; + end getMaxSimEqSystemIndex; + + function translateSparsePatterSimVarInts + input list>> sparsePattern; + input SimCode.SimCode simCode; + output list>> outSparsePattern; + end translateSparsePatterSimVarInts; + + function translateColorsSimVarInts + input list> inColors; + input SimCode.SimCode simCode; + output list> outColors; + end translateColorsSimVarInts; + + function getDaeEqsNotPartOfOdeSystem + input SimCode.SimCode iSimCode; + output list oEqs; + end getDaeEqsNotPartOfOdeSystem; + + function getVarIndexListByMapping + input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; + input DAE.ComponentRef iVarName; + input String iIndexForUndefinedReferences; + output list oVarIndexList; + end getVarIndexListByMapping; + + function isVarIndexListConsecutive + input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; + input DAE.ComponentRef iVarName; + output Boolean oIsConsecutive; + end isVarIndexListConsecutive; +end SimCodeUtil; + +package SimCodeFunctionUtil + function varName + input SimCodeVar.SimVar var; + output DAE.ComponentRef cr; + end varName; + + function isParallelFunctionContext + input SimCode.Context context; + output Boolean s; + end isParallelFunctionContext; + + function createDAEString + input String inString; + output DAE.Exp outExp; + end createDAEString; function crefSubIsScalar input DAE.ComponentRef cref; @@ -753,24 +852,6 @@ package SimCodeUtil output Boolean isScalar; end crefIsScalar; - function buildCrefExpFromAsub - input DAE.Exp cref; - input list subs; - output DAE.Exp cRefOut; - end buildCrefExpFromAsub; - - function incrementInt - input Integer inInt; - input Integer increment; - output Integer outInt; - end incrementInt; - - function decrementInt - input Integer inInt; - input Integer decrement; - output Integer outInt; - end decrementInt; - function isProtected input SimCodeVar.SimVar simVar; output Boolean isProtected; @@ -830,110 +911,33 @@ package SimCodeUtil output DAE.Exp outExp; end createAssertforSqrt; - function appendLists - input list inEqn1; - input list inEqn2; - output list outEqn; - end appendLists; - - function createDAEString - input String inString; - output DAE.Exp outExp; - end createDAEString; + function elementVars + input list ld; + output list vars; + end elementVars; function isBoxedFunction input SimCode.Function fn; output Boolean b; end isBoxedFunction; - function functionInfo - input SimCode.Function fn; - output builtin.SourceInfo info; - end functionInfo; - - function twodigit - input Integer i; - output String s; - end twodigit; - - function countDynamicExternalFunctions - input list inFncLst; - output Integer outDynLoadFuncs; - end countDynamicExternalFunctions; - - function eqInfo - input SimCode.SimEqSystem eq; - output builtin.SourceInfo info; - end eqInfo; - - function varName - input SimCodeVar.SimVar var; - output DAE.ComponentRef cr; - end varName; - - function dimsToAllIndexes - input DAE.Dimensions inDims; - output list> outIndexes; - end dimsToAllIndexes; - - function sortEqSystems - input list eqs; - output list outEqs; - end sortEqSystems; - - function isParallelFunctionContext - input SimCode.Context context; - output Boolean s; - end isParallelFunctionContext; - - function getEnumerationTypes - input SimCodeVar.SimVars inVars; - output list outVars; - end getEnumerationTypes; - - function getFMIModelStructure - input SimCode.SimCode simCode; - input list jacobianMatrixes; - output SimCode.FmiModelStructure outFmiModelStructure; - end getFMIModelStructure; - - function getStateSimVarIndexFromIndex - input list inStateVars; - input Integer inIndex; - output Integer outVariableIndex; - end getStateSimVarIndexFromIndex; - - function getVariableIndex - input SimCodeVar.SimVar inVar; - output Integer outVariableIndex; - end getVariableIndex; - - function getMaxSimEqSystemIndex - input SimCode.SimCode simCode; - output Integer idxOut; - end getMaxSimEqSystemIndex; - - function translateSparsePatterSimVarInts - input list>> sparsePattern; - input SimCode.SimCode simCode; - output list>> outSparsePattern; - end translateSparsePatterSimVarInts; - - function translateColorsSimVarInts - input list> inColors; - input SimCode.SimCode simCode; - output list> outColors; - end translateColorsSimVarInts; + function incrementInt + input Integer inInt; + input Integer increment; + output Integer outInt; + end incrementInt; - function generateSubPalceholders - input DAE.ComponentRef cr; - output String outdef; - end generateSubPalceholders; + function decrementInt + input Integer inInt; + input Integer decrement; + output Integer outInt; + end decrementInt; - function getDaeEqsNotPartOfOdeSystem - input SimCode.SimCode iSimCode; - output list oEqs; - end getDaeEqsNotPartOfOdeSystem; + function buildCrefExpFromAsub + input DAE.Exp cref; + input list subs; + output DAE.Exp cRefOut; + end buildCrefExpFromAsub; function codegenResetTryThrowIndex end codegenResetTryThrowIndex; @@ -949,20 +953,17 @@ package SimCodeUtil output Integer i; end codegenPeekTryThrowIndex; - function getVarIndexListByMapping - input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; - input DAE.ComponentRef iVarName; - input String iIndexForUndefinedReferences; - output list oVarIndexList; - end getVarIndexListByMapping; + function twodigit + input Integer i; + output String s; + end twodigit; - function isVarIndexListConsecutive - input HashTableCrIListArray.HashTable iVarToArrayIndexMapping; - input DAE.ComponentRef iVarName; - output Boolean oIsConsecutive; - end isVarIndexListConsecutive; -end SimCodeUtil; + function generateSubPalceholders + input DAE.ComponentRef cr; + output String outdef; + end generateSubPalceholders; +end SimCodeFunctionUtil; package BackendDAE @@ -3126,167 +3127,6 @@ package ValuesUtil end valueExp; end ValuesUtil; -package BackendQSS - uniontype QSSinfo "- equation indices in static blocks and DEVS structure" - record QSSINFO - list> stateVarIndex; - list stateVars; - list discreteAlgVars; - list algVars; - BackendDAE.EqSystems eqs; - list zcs; - Integer zc_offset; - end QSSINFO; - end QSSinfo; - - function getStateIndexList - input QSSinfo qssInfo; - output list> refs; - end getStateIndexList; - - function getStates - input QSSinfo qssInfo; - output list refs; - end getStates; - - function getDisc - input QSSinfo qssInfo; - output list refs; - end getDisc; - function replaceVars - input DAE.Exp exp; - input list states; - input list disc; - input list algs; - output DAE.Exp expout; - end replaceVars; - - function replaceCref - input DAE.ComponentRef cr; - input list states; - input list disc; - input list algs; - output String out; - end replaceCref; - - function getAlgs - input QSSinfo qssInfo; - output list refs; - end getAlgs; - - function negate - input DAE.Exp exp; - output DAE.Exp exp_out; - end negate; - - function getEqs - input QSSinfo qssInfo; - output BackendDAE.EquationArray eqs; - end getEqs; - - function generateHandler - input BackendDAE.EquationArray eqs; - input list handlers; - input list states; - input list disc; - input list algs; - input DAE.Exp condition; - input Boolean v; - input list zc_exps; - input Integer offset; - output String out; - end generateHandler; - - - function getRHSVars - input list beqs; - input list vars; - input list> simJac; - input list states; - input list disc; - input list algs; - output list out; - end getRHSVars; - - function getDiscRHSVars - input list beqs; - input list vars; - input list> simJac; - input list states; - input list disc; - input list algs; - output list out; - end getDiscRHSVars; - - - function generateDInit - input list disc; - //input list sample; - input SimCodeVar.SimVars vars; - input Integer acc; - input Integer total; - input Integer nWhenClause; - output String out; - end generateDInit; - - function generateExtraParams - input SimCode.SimEqSystem eq; - input SimCodeVar.SimVars vars; - output String s; - end generateExtraParams; - - function generateInitialParamEquations - input SimCode.SimEqSystem eq; - output String t; - end generateInitialParamEquations; - - function replaceVarsInputs - input DAE.Exp exp; - input list inp; - output DAE.Exp exp_out; - end replaceVarsInputs; - - function simpleWhens - input list i; - output list o; - end simpleWhens; - - function sampleWhens - input list i; - output list o; - end sampleWhens; - - function getZCOffset - input QSSinfo qssInfo; - output Integer o; - end getZCOffset; - - function getZCExps - input QSSinfo qssInfo; - output list exps; - end getZCExps; - -end BackendQSS; - -package BackendVariable - function varCref - input BackendDAE.Var inVar; - output DAE.ComponentRef outComponentRef; - end varCref; - - function isStateVar - input BackendDAE.Var inVar; - output Boolean outBoolean; - end isStateVar; - - function varIndex - input BackendDAE.Var inVar; - output Integer outInteger; - end varIndex; - - -end BackendVariable; - package DAEDump function ppStmtStr @@ -3602,15 +3442,6 @@ package HpcOmSimCode end MemoryMap; end HpcOmSimCode; -package HpcOmScheduler - function convertFixedLevelScheduleToTaskLists - input HpcOmSimCode.Schedule iOdeSchedule; - input HpcOmSimCode.Schedule iDaeSchedule; - input Integer iNumOfThreads; - output array>,list>>> oThreadLevelTasks; - end convertFixedLevelScheduleToTaskLists; -end HpcOmScheduler; - package HashTableCrIListArray type Key = DAE.ComponentRef; type Value = tuple, array>; diff --git a/Compiler/Util/Error.mo b/Compiler/Util/Error.mo index cb4f3335b52..a564bd0c46e 100644 --- a/Compiler/Util/Error.mo +++ b/Compiler/Util/Error.mo @@ -688,6 +688,8 @@ public constant Message EXT_LIBRARY_NOT_FOUND = MESSAGE(282, TRANSLATION(), WARN Util.gettext("Could not find library %s in either of:%s")); public constant Message EXT_LIBRARY_NOT_FOUND_DESPITE_COMPILATION_SUCCESS = MESSAGE(258, TRANSLATION(), WARNING(), Util.gettext("Could not find library %s despite compilation command %s in directory %s returning success.")); +public constant Message GENERATE_SEPARATE_CODE_DEPENDENCIES_FAILED_UNKNOWN_PACKAGE = MESSAGE(283, SCRIPTING(), ERROR(), + Util.gettext("Failed to get dependencies for package %s. %s contains an import to non-existing package %s.")); public constant Message UNBOUND_PARAMETER_WITH_START_VALUE_WARNING = MESSAGE(499, TRANSLATION(), WARNING(), Util.gettext("Parameter %s has no value, and is fixed during initialization (fixed=true), using available start value (start=%s) as default value.")); diff --git a/Compiler/boot/LoadCompilerSources.mos b/Compiler/boot/LoadCompilerSources.mos index 7b0a42c4dde..7bc0a242913 100644 --- a/Compiler/boot/LoadCompilerSources.mos +++ b/Compiler/boot/LoadCompilerSources.mos @@ -3,7 +3,7 @@ // "FrontEnd"; if true then /* Suppress output */ setCommandLineOptions("+g=MetaModelica"); - files := { + alwaysfiles := { // "../Util/MessagePack.mo", // TODO: Add once we bootstrapped omc, maybe "../Util/File.mo", "../FrontEnd/Absyn.mo", @@ -117,121 +117,40 @@ if true then /* Suppress output */ "../FFrontEnd/FTraverse.mo", "../FFrontEnd/FVisit.mo", - // "BackEnd"; + // "BackEnd"; "../BackEnd/BackendDAE.mo", - "../BackEnd/BackendDAEFunc.mo", - "../BackEnd/BackendDAECreate.mo", - "../BackEnd/BackendDAEEXT.mo", - "../BackEnd/BackendDAEOptimize.mo", - "../BackEnd/BackendDAETransform.mo", - "../BackEnd/BackendDAEUtil.mo", - "../BackEnd/BackendDump.mo", - "../BackEnd/BackendEquation.mo", - "../BackEnd/BackendInline.mo", - "../BackEnd/BackendQSS.mo", - "../BackEnd/BackendVariable.mo", - "../BackEnd/BackendVarTransform.mo", - "../BackEnd/BinaryTree.mo", - "../BackEnd/BinaryTreeInt.mo", - "../BackEnd/Causalize.mo", - "../BackEnd/CommonSubExpression.mo", - "../BackEnd/DAEQuery.mo", - "../BackEnd/Differentiate.mo", - "../BackEnd/DumpGraphML.mo", - "../BackEnd/DumpHTML.mo", - "../BackEnd/DynamicOptimization.mo", - "../BackEnd/EvaluateFunctions.mo", - "../BackEnd/EvaluateParameter.mo", - "../BackEnd/ExpressionSolve.mo", - "../BackEnd/FindZeroCrossings.mo", - "../BackEnd/HpcOmBenchmark.mo", - "../BackEnd/HpcOmBenchmarkExt.mo", - "../BackEnd/HpcOmEqSystems.mo", - "../BackEnd/HpcOmMemory.mo", - "../BackEnd/HpcOmScheduler.mo", - "../BackEnd/HpcOmSchedulerExt.mo", - "../BackEnd/HpcOmTaskGraph.mo", - "../BackEnd/IndexReduction.mo", - "../BackEnd/InlineArrayEquations.mo", - "../BackEnd/Initialization.mo", - "../BackEnd/Matching.mo", - "../BackEnd/MathematicaDump.mo", - "../BackEnd/OnRelaxation.mo", - "../BackEnd/OpenTURNS.mo", - "../BackEnd/RemoveSimpleEquations.mo", - "../BackEnd/ResolveLoops.mo", - "../BackEnd/Sorting.mo", - "../BackEnd/SymbolicJacobian.mo", - "../BackEnd/SynchronousFeatures.mo", - "../BackEnd/StateMachineFeatures.mo", - "../BackEnd/HashTableSM.mo", - "../BackEnd/Tearing.mo", - "../BackEnd/Uncertainties.mo", - "../BackEnd/UnitCheck.mo", - "../BackEnd/Unit.mo", - "../BackEnd/Vectorization.mo", - "../BackEnd/XMLDump.mo", - "../Lexers/LexerModelicaDiff.mo", - - // "SimCode"; + // "SimCode"; "../SimCode/HpcOmSimCode.mo", - "../SimCode/HpcOmSimCodeMain.mo", - "../SimCode/SerializeModelInfo.mo", "../SimCode/SimCode.mo", - "../SimCode/SimCodeMain.mo", - "../SimCode/SimCodeUtil.mo", + "../SimCode/SimCodeFunction.mo", + "../SimCode/SimCodeFunctionUtil.mo", "../SimCode/SimCodeVar.mo", - // "Script"; + // "Script"; "../Script/CevalScript.mo", "../Script/GlobalScript.mo", "../Script/GlobalScriptDump.mo", "../Script/GlobalScriptUtil.mo", "../Script/StaticScript.mo", "../Script/Interactive.mo", - "../Script/Refactor.mo", - "../Script/RewriteRules.mo", - "../Script/Figaro.mo", - "../Script/BlockCallRewrite.mo", - "../Script/OpenModelicaScriptingAPI.mo", - // "Template"; + // "Template"; "../Template/AbsynDumpTpl.mo", - "../Template/CodegenAdevs.mo", "../Template/CodegenC.mo", - "../Template/CodegenCpp.mo", - "../Template/CodegenCppHpcom.mo", - "../Template/CodegenFMU.mo", - "../Template/CodegenFMU1.mo", - "../Template/CodegenFMU2.mo", - "../Template/CodegenFMUCommon.mo", - "../Template/CodegenFMUCpp.mo", - "../Template/CodegenCppInit.mo", - "../Template/CodegenCSharp.mo", - "../Template/CodegenJava.mo", - "../Template/CodegenJS.mo", - "../Template/CodegenModelica.mo", - "../Template/CodegenQSS.mo", - "../Template/CodegenSparseFMI.mo", "../Template/CodegenUtil.mo", - "../Template/CodegenXML.mo", "../Template/DAEDumpTpl.mo", "../Template/ExpressionDumpTpl.mo", "../Template/GenerateAPIFunctionsTpl.mo", - "../Template/GraphvizDump.mo", "../Template/GraphMLDumpTpl.mo", "../Template/NFInstDumpTpl.mo", "../Template/SCodeDumpTpl.mo", - "../Template/SimCodeDump.mo", - "../Template/TaskSystemDump.mo", "../Template/TplAbsyn.mo", "../Template/TplCodegen.mo", "../Template/TplMain.mo", "../Template/Tpl.mo", "../Template/TplParser.mo", "../Template/Unparsing.mo", - "../Template/VisualXMLTpl.mo", // "Global"; "../Global/Global.mo", @@ -250,7 +169,6 @@ if true then /* Suppress output */ "../Util/Corba.mo", // "../Util/Database.mo", "../Util/Debug.mo", - "../Util/DiffAlgorithm.mo", "../Util/DynLoad.mo", "../Util/ErrorExt.mo", "../Util/Error.mo", @@ -272,7 +190,6 @@ if true then /* Suppress output */ "../Util/HashTableCrILst.mo", "../Util/HashTableCrIListArray.mo", "../Util/HashTableCrToExp.mo", - "../Util/HashTableCrToCrEqLst.mo", "../Util/HashTableExpToExp.mo", "../Util/HashTableCrIntToExp.mo", "../Util/HashTableExpToIndexExp.mo", @@ -282,9 +199,6 @@ if true then /* Suppress output */ //"../Util/HashTablePathToFunction.mo", "../Util/HashTableStringToPath.mo", "../Util/HashTableStringToProgram.mo", - "../Util/HashTableStringToUnit.mo", - "../Util/HashTableCrToUnit.mo", - "../Util/HashTableUnitToString.mo", "../Util/IOStreamExt.mo", "../Util/IOStream.mo", "../Util/Lapack.mo", @@ -300,13 +214,150 @@ if true then /* Suppress output */ "../Util/System.mo", "../Util/Util.mo", "../Util/VarTransform.mo", - "../Util/VisualXML.mo", - "../Util/Serializer.mo" + "../Util/Serializer.mo" + }; + backendfiles := if OpenModelica.Scripting.getEnvironmentVar("OPENMODELICA_BACKEND_STUBS")<>"" then + { + "../Stubs/BackendDump.mo", + "../Stubs/BackendDAECreate.mo", + "../Stubs/BackendDAEOptimize.mo", + "../Stubs/BackendEquation.mo", + "../Stubs/BackendDAETransform.mo", + "../Stubs/BackendQSS.mo", + "../Stubs/BackendVariable.mo", + "../Stubs/BackendVarTransform.mo", + "../Stubs/Differentiate.mo", + "../Stubs/ExpressionSolve.mo", + "../Stubs/Initialization.mo", + "../Stubs/SimCodeDump.mo", + "../Stubs/BackendDAEUtil.mo", + "../Stubs/DAEQuery.mo", + "../Stubs/FindZeroCrossings.mo", + "../Stubs/SymbolicJacobian.mo", + "../Stubs/Vectorization.mo", + "../Stubs/CodegenFMU.mo", + "../Stubs/HpcOmTaskGraph.mo", + "../Stubs/Figaro.mo", + "../Stubs/RewriteRules.mo", + "../Stubs/BlockCallRewrite.mo", + "../Stubs/Refactor.mo", + "../Stubs/SimCodeMain.mo", + "../Stubs/SimCodeUtil.mo", + "../Stubs/TaskSystemDump.mo", + "../Stubs/OpenTURNS.mo", + "../Stubs/Uncertainties.mo", + "../Stubs/XMLDump.mo", + "../Stubs/VisualXML.mo", + "../Stubs/LexerModelicaDiff.mo", + "../Stubs/DiffAlgorithm.mo", + "../Stubs/HpcOmSimCodeMain.mo" + } + else { + "../BackEnd/BackendDAEFunc.mo", + "../BackEnd/BackendDAECreate.mo", + "../BackEnd/BackendDAEEXT.mo", + "../BackEnd/BackendDAEOptimize.mo", + "../BackEnd/BackendDAETransform.mo", + "../BackEnd/BackendDAEUtil.mo", + "../BackEnd/BackendDump.mo", + "../BackEnd/BackendEquation.mo", + "../BackEnd/BackendInline.mo", + "../BackEnd/BackendQSS.mo", + "../BackEnd/BackendVariable.mo", + "../BackEnd/BackendVarTransform.mo", + "../BackEnd/BinaryTree.mo", + "../BackEnd/BinaryTreeInt.mo", + "../BackEnd/Causalize.mo", + "../BackEnd/CommonSubExpression.mo", + "../BackEnd/DAEQuery.mo", + "../BackEnd/Differentiate.mo", + "../BackEnd/DumpGraphML.mo", + "../BackEnd/DumpHTML.mo", + "../BackEnd/DynamicOptimization.mo", + "../BackEnd/EvaluateFunctions.mo", + "../BackEnd/EvaluateParameter.mo", + "../BackEnd/ExpressionSolve.mo", + "../BackEnd/FindZeroCrossings.mo", + "../BackEnd/HpcOmBenchmark.mo", + "../BackEnd/HpcOmBenchmarkExt.mo", + "../BackEnd/HpcOmEqSystems.mo", + "../BackEnd/HpcOmMemory.mo", + "../BackEnd/HpcOmScheduler.mo", + "../BackEnd/HpcOmSchedulerExt.mo", + "../BackEnd/HpcOmTaskGraph.mo", + "../BackEnd/IndexReduction.mo", + "../BackEnd/InlineArrayEquations.mo", + "../BackEnd/Initialization.mo", + "../BackEnd/Matching.mo", + "../BackEnd/MathematicaDump.mo", + "../BackEnd/OnRelaxation.mo", + "../BackEnd/OpenTURNS.mo", + "../BackEnd/RemoveSimpleEquations.mo", + "../BackEnd/ResolveLoops.mo", + "../BackEnd/Sorting.mo", + "../BackEnd/SymbolicJacobian.mo", + "../BackEnd/SynchronousFeatures.mo", + "../BackEnd/StateMachineFeatures.mo", + "../BackEnd/HashTableSM.mo", + "../BackEnd/Tearing.mo", + "../BackEnd/Uncertainties.mo", + "../BackEnd/UnitCheck.mo", + "../BackEnd/Unit.mo", + "../BackEnd/Vectorization.mo", + "../BackEnd/XMLDump.mo", + + "../Lexers/LexerModelicaDiff.mo", + + "../Script/Refactor.mo", + "../Script/RewriteRules.mo", + "../Script/Figaro.mo", + "../Script/BlockCallRewrite.mo", + "../Script/OpenModelicaScriptingAPI.mo", + + "../SimCode/HpcOmSimCodeMain.mo", + "../SimCode/SerializeModelInfo.mo", + "../SimCode/SimCodeMain.mo", + "../SimCode/SimCodeUtil.mo", + + "../Template/CodegenAdevs.mo", + "../Template/CodegenCpp.mo", + "../Template/CodegenCppHpcom.mo", + "../Template/CodegenCppInit.mo", + "../Template/CodegenCSharp.mo", + "../Template/CodegenFMU.mo", + "../Template/CodegenFMU1.mo", + "../Template/CodegenFMU2.mo", + "../Template/CodegenFMUCommon.mo", + "../Template/CodegenFMUCpp.mo", + "../Template/CodegenJava.mo", + "../Template/CodegenJS.mo", + "../Template/CodegenModelica.mo", + "../Template/CodegenSparseFMI.mo", + "../Template/CodegenQSS.mo", + "../Template/CodegenXML.mo", + "../Template/GraphvizDump.mo", + "../Template/SimCodeDump.mo", + "../Template/TaskSystemDump.mo", + "../Template/VisualXMLTpl.mo", + + "../Util/DiffAlgorithm.mo", + "../Util/HashTableCrToCrEqLst.mo", + "../Util/HashTableCrToUnit.mo", + "../Util/HashTableStringToUnit.mo", + "../Util/HashTableUnitToString.mo", + "../Util/VisualXML.mo" + }; + files := cat(1, alwaysfiles, backendfiles); LoadCompilerSourcesRes:= OpenModelica.Scripting.loadFiles(files,numThreads=min(5,OpenModelica.Scripting.numProcessors())); if not LoadCompilerSourcesRes then print("Failed to load compiler sources:\n"); print(getErrorString()); + for f in files loop + if not OpenModelica.Scripting.regularFileExists(f) then + print("File does not exist: " + f + "\n"); + end if; + end for; exit(1); end if; end if; diff --git a/Compiler/boot/MakeDepends.mos b/Compiler/boot/MakeDepends.mos index d4a63cbc62a..1786bc31c6f 100644 --- a/Compiler/boot/MakeDepends.mos +++ b/Compiler/boot/MakeDepends.mos @@ -5,263 +5,3 @@ if not generateSeparateCodeDependenciesMakefile("Makefile.depends",directory="$( exit(1); end if; exit(0); -/* -frontEndFiles := { - "Absyn", - "Algorithm", - "Builtin", - "CevalFunction", - "Ceval", - "CheckModel", - "ClassInf", - "ClassLoader", - "ComponentReference", - "ConnectionGraph", - "Connect", - "ConnectUtil", - "Constants", - "DAEDump", - "DAE", - "DAEUtil", - "DumpGraphviz", - "Dump", - "ExpressionDump", - "Expression", - "ExpressionSimplify", - "ExpressionSimplifyTypes", - "Graphviz", - "Inline", - "InnerOuter", - "Inst", - "InstVar", - "InstDAE", - "InstFunction", - "InstBinding", - "InstUtil", - "InstExtends", - "InstSection", - "InstTypes", - "Lookup", - "MetaUtil", - "MMath", - "Mod", - "OperatorOverloading", - "Parser", - "ParserExt", - "Patternm", - "Prefix", - "PrefixUtil", - "SCode", - "SCodeDump", - "SCodeUtil", - "Static", - "SCodeSimplify", - "NFBuiltin", - "NFConnect2", - "NFConnectCheck", - "NFConnectEquations", - "NFConnectUtil2", - "NFConnectionSets", - "NFEnv", - "NFEnvAvlTree", - "NFEnvExtends", - "NFExpandableConnectors", - "NFInst", - "NFInstDump", - "NFInstFlatten", - "NFInstPrefix", - "NFInstSymbolTable", - "NFInstTypes", - "NFInstTypesOld", - "NFInstUtil", - "NFLookup", - "NFMod", - "NFRedeclare", - "NFSCodeDependency", - "NFSCodeEnv", - "NFSCodeExpand", - "NFSCodeFlattenImports", - "NFSCodeFlatten", - "NFSCodeFlattenRedeclare", - "NFSCodeLookup", - "NFSCodeMod", - "NFSCodeCheck", - "NFTypeCheck", - "NFTyping", - "Types", - "UnitAbsynBuilder", - "UnitAbsyn", - "UnitChecker", - "UnitParserExt", - "Values", - "ValuesUtil", - "FBuiltin", - "FCore", - "FExpand", - "FGraph", - "FGraphBuild", - "FGraphBuildEnv", - "FGraphDump", - "FGraphStream", - "FInst", - "FLookup", - "FMod", - "FNode", - "FResolve", - "FTraverse", - "FVisit" -}; -backEndFiles := { - "SerializeModelInfo", // TODO: Add once we bootstrapped omc - "BackendDAE", - "BackendDAEFunc", - "BackendDAECreate", - "BackendDAEEXT", - "BackendDAEOptimize", - "BackendDAETransform", - "BackendDAEUtil", - "BackendDump", - "BackendEquation", - "BackendQSS", - "BackendVariable", - "BackendVarTransform", - "BinaryTree", - "BinaryTreeInt", - "Causalize", - "DAEQuery", - "Differentiate", - "DumpHTML", - "DynamicOptimization", - "EvaluateFunctions", - "EvaluateParameter", - "ExpressionSolve", - "FindZeroCrossings", - "HpcOmBenchmark", - "HpcOmBenchmarkExt", - "HpcOmEqSystems", - "HpcOmMemory", - "HpcOmScheduler", - "HpcOmSchedulerExt", - "HpcOmTaskGraph", - "IndexReduction", - "InlineArrayEquations", - "Initialization", - "Matching", - "MathematicaDump", - "OnRelaxation", - "OpenTURNS", - "RemoveSimpleEquations", - "ResolveLoops", - "SynchronousFeatures", - "Tearing", - "Uncertainties", - "UnitCheck", - "XMLDump", - "HpcOmSimCode", - "HpcOmSimCodeMain", - "SimCode", - "SimCodeMain", - "SimCodeUtil", - "SimCodeVar", - "AbsynDumpTpl", - "CodegenAdevs", - "CodegenC", - "CodegenCpp", - "CodegenCppHpcom", - "CodegenFMU", - "CodegenFMUCpp", - "CodegenCSharp", - "CodegenJava", - "CodegenJS", - "CodegenModelica", - "CodegenQSS", - "CodegenSparseFMI", - "CodegenUtil", - "CodegenXML", - "DAEDumpTpl", - "ExpressionDumpTpl", - "GraphvizDump", - "GraphMLDumpTpl", - "NFInstDumpTpl", - "SCodeDumpTpl", - "SimCodeDump", - "TaskSystemDump", - "TplAbsyn", - "TplCodegen", - "TplMain", - "Tpl", - "TplParser", - "Unparsing" -}; -utilFiles := { - "File", - "CevalScript", - "GlobalScript", - "StaticScript", - "Interactive", - "Refactor", - "RewriteRules", - "Figaro", - "BlockCallRewrite", - "Global", - "Main", - "AvlTreeString", - "BaseHashTable", - "BaseHashSet", - "Config", - "Corba", - "Debug", - "DynLoad", - "ErrorExt", - "Error", - "Flags", - "FMI", - "FMIExt", - "Graph", - "GraphML", - "GraphStream", - "GraphStreamExt", - "HashSet", - "HashSetString", - "HashTable2", - "HashTable3", - "HashTable4", - "HashTable5", - "HashTableCG", - "HashTableCrILst", - "HashTableCrIListArray", - "HashTableExpToExp", - "HashTableCrIntToExp", - "HashTableCrToExpSourceTpl", - "HashTable", - "HashTableExpToIndex", - "HashTablePathToFunction", - "HashTableStringToPath", - "IOStreamExt", - "IOStream", - "Lapack", - "List", - "ModelicaExternalC", - "Print", - "PriorityQueue", - "Settings", - "SimulationResults", - "TaskGraphResults", - "Socket", - "System", - "Util", - "VarTransform" -}; -packages := {typeNameString(cl) for cl in getClassNames(sort=true)}; -strs := sortStrings(cat(1, frontEndFiles, backEndFiles, utilFiles)); -if size(packages,1) <> size(strs,1) then - print("Could not determine if front-end packages call allowed packages since the number of packages differ"); - exit(1); -end if; -if not min(p==s threaded for p in packages, s in strs) then - print("Could not determine if front-end packages call allowed packages since the names of packages differ"); - exit (1); -end if; -getErrorString(); -checkFrontEndBackEndInterface(frontEndFiles=frontEndFiles,backendFiles=backendFiles,utilFiles=utilFiles); -*/ diff --git a/Compiler/boot/Makefile.common b/Compiler/boot/Makefile.common index 7d7100885dd..2699a738f20 100644 --- a/Compiler/boot/Makefile.common +++ b/Compiler/boot/Makefile.common @@ -42,12 +42,16 @@ bootstrap-from-tarball: $(PATCHES) # Patch _main.c to avoid a new tarball $(PATCH_SOURCES) cd build && for x in ../patches/*.patch; do patch -i "$$x" "`basename $$x | $(SED) 's/\([.][0-9]*\)\?[.]patch/.c/'`" || exit 1; done + # We have not compiled OpenModelicaScriptingAPI.mo yet + touch build/OpenModelicaScriptingAPI.h $(MAKE) -f $(defaultMakefileTarget) install INCLUDESOURCES=1 OMC=.omc @echo "Bootstrapping phase 1/3 completed" $(MAKE) -f $(defaultMakefileTarget) clean OMC=$(BOOTSTRAP_OMC) - $(MAKE) -f $(defaultMakefileTarget) generate-files-in-steps OMC=$(BOOTSTRAP_OMC) + OPENMODELICA_BACKEND_STUBS=1 $(MAKE) -f $(defaultMakefileTarget) generate-files-in-steps OMC=$(BOOTSTRAP_OMC) # Patch _main.c to avoid a new tarball $(PATCH_SOURCES) + # We have not compiled OpenModelicaScriptingAPI.mo yet + touch build/OpenModelicaScriptingAPI.h $(MAKE) -f $(defaultMakefileTarget) install INCLUDESOURCES=1 OMC=$(BOOTSTRAP_OMC) @echo "Bootstrapping phase 2/3 completed" $(MAKE) -f $(defaultMakefileTarget) clean OMC=$(BOOTSTRAP_OMC) @@ -58,12 +62,14 @@ bootstrap-from-tarball: $(PATCHES) bootstrap-from-compiled: make-separate -make-bootstrap-tarball: - rm -rf $(GEN_DIR) - $(MAKE) -f $(defaultMakefileTarget) generate-files-in-steps +make-bootstrap-tarball: clean + test ! -f Makefile.sources || rm Makefile.sources + test ! -f Makefile.depends || rm Makefile.depends + OPENMODELICA_BACKEND_STUBS=1 $(MAKE) -f $(defaultMakefileTarget) generate-files-in-steps rm -rf $(GEN_DIR)/*.mo $(GEN_DIR)/tmp $(GEN_DIR)/*.deps $(GEN_DIR)/*.mos $(GEN_DIR)/*.stamp - sed -i -e "s/^ *//" -e "/^[/][/]/d" -e "/^#line /d" -e "/^$$/d" -e "/^ *[/][*].*[*][/] *$$/d" $(GEN_DIR)/*.c $(GEN_DIR)/*.h - tar cJf bootstrap-sources.tar.xz $(GEN_DIR) Makefile.sources + sed -i -e "s/^ *//" -e "/^[/][/]/d" -e "/^#line /d" -e "s/ *[/][*].*[*][/]\([;)]\?\) *$$/\1/" -e "s/^ *[/][*].*[*][/]\(;\?\) */\1/" -e "/^ *$$/d" $(GEN_DIR)/*.c $(GEN_DIR)/*.h + tar cf bootstrap-sources.tar $(GEN_DIR) Makefile.sources + xz --best --force bootstrap-sources.tar templates: $(MAKE) -f $(defaultMakefileTarget) --no-print-directory -C $(TOP_DIR)/Compiler/Template diff --git a/SimulationRuntime/cpp/Core/SimController/SimController.cpp b/SimulationRuntime/cpp/Core/SimController/SimController.cpp index b302c9176c1..65ec73b0f98 100644 --- a/SimulationRuntime/cpp/Core/SimController/SimController.cpp +++ b/SimulationRuntime/cpp/Core/SimController/SimController.cpp @@ -277,7 +277,7 @@ void SimController::Start(SimSettings simsettings, string modelKey) boost::shared_ptr writeoutput_system = boost::dynamic_pointer_cast(mixedsystem); - if((global_settings->getOutputFormat()==BUFFER) && writeoutput_system) + if((global_settings->getOutputFormat()==OM_BUFFER) && writeoutput_system) { boost::shared_ptr simData = getSimData(modelKey).lock(); //get history object to query simulation results diff --git a/SimulationRuntime/cpp/Core/SimController/SimManager.cpp b/SimulationRuntime/cpp/Core/SimController/SimManager.cpp index cad70dee2e8..65ff037d8e7 100644 --- a/SimulationRuntime/cpp/Core/SimController/SimManager.cpp +++ b/SimulationRuntime/cpp/Core/SimController/SimManager.cpp @@ -8,6 +8,10 @@ #include +#if defined(_MSC_VER) && !defined(RUNTIME_STATIC_LINKING) + Logger* Logger::instance = NULL; +#endif + SimManager::SimManager(boost::shared_ptr system, Configuration* config) : _mixed_system (system) , _config (config) @@ -104,7 +108,7 @@ void SimManager::initialize() return; } - Logger::write("SimManager start init",INIT,DEBUG); + Logger::write("SimManager start init",OM_INIT,OM_DEBUG); // Flag für Endlossimulaton (wird gesetzt wenn Solver zurückkommt) _continueSimulation = true; @@ -157,7 +161,7 @@ void SimManager::initialize() memset(_events, false, _dimZeroFunc * sizeof(bool)); } - Logger::write("SimManager assemble completed",INIT,DEBUG); + Logger::write("SimManager assemble completed",OM_INIT,OM_DEBUG); //#if defined(__TRICORE__) || defined(__vxworks) // Initialization for RT simulation if (_config->getGlobalSettings()->useEndlessSim()) @@ -259,24 +263,24 @@ void SimManager::runSimulation() #endif try { - Logger::write("SimManager: start simulation at t = " + boost::lexical_cast(_tStart),SOLV,INFO); + Logger::write("SimManager: start simulation at t = " + boost::lexical_cast(_tStart),OM_SOLV,OM_INFO); runSingleProcess(); // Zeit messen, Ausgabe der SimInfos ISolver::SOLVERSTATUS status = _solver->getSolverStatus(); if ((status & ISolver::DONE) || (status & ISolver::USER_STOP)) { - Logger::write("SimManager: simulation done at t = " + boost::lexical_cast(_tEnd),SOLV,INFO); - Logger::write("SimManager: number of steps = " + boost::lexical_cast(_totStps),SOLV,INFO); + Logger::write("SimManager: simulation done at t = " + boost::lexical_cast(_tEnd),OM_SOLV,OM_INFO); + Logger::write("SimManager: number of steps = " + boost::lexical_cast(_totStps),OM_SOLV,OM_INFO); writeProperties(); } } catch (std::exception & ex) { - Logger::write("SimManager: simulation finish with errors at t = " + boost::lexical_cast(_tEnd),SOLV,ERROR); - Logger::write("SimManager: number of steps = " + boost::lexical_cast(_totStps),SOLV,INFO); + Logger::write("SimManager: simulation finish with errors at t = " + boost::lexical_cast(_tEnd),OM_SOLV,OM_ERROR); + Logger::write("SimManager: number of steps = " + boost::lexical_cast(_totStps),OM_SOLV,OM_INFO); writeProperties(); - Logger::write("SimManager: error = " + boost::lexical_cast(ex.what()),SOLV,ERROR); + Logger::write("SimManager: error = " + boost::lexical_cast(ex.what()),OM_SOLV,OM_ERROR); //ex << error_id(SIMMANAGER); throw; } @@ -296,7 +300,7 @@ void SimManager::stopSimulation() void SimManager::writeProperties() { // decl for Logging - std::pair logM = Logger::getLogMode(SOLV, INFO); + std::pair logM = Logger::getLogMode(OM_SOLV, OM_INFO); Logger::write(boost::lexical_cast("computationTime"),logM); Logger::write(boost::lexical_cast("Geforderte Simulationszeit: ") + boost::lexical_cast(_tEnd),logM); @@ -548,7 +552,7 @@ void SimManager::runSingleProcess() _solverTask = ISolver::SOLVERCALL(_solverTask ^ ISolver::RECORDCALL); /* Logs temporarily disabled BOOST_LOG_SEV(simmgr_lg::get(), simmgr_normal) <<"Run single process." ; */ - Logger::write("SimManager: run single process",SOLV,DEBUG); + Logger::write("SimManager: run single process",OM_SOLV,OM_DEBUG); // Zeitinvervall speichern //_H =_tEnd - _tStart; diff --git a/SimulationRuntime/cpp/Core/SimulationSettings/GlobalSettings.cpp b/SimulationRuntime/cpp/Core/SimulationSettings/GlobalSettings.cpp index e41e5d4b2f7..087bdace21b 100644 --- a/SimulationRuntime/cpp/Core/SimulationSettings/GlobalSettings.cpp +++ b/SimulationRuntime/cpp/Core/SimulationSettings/GlobalSettings.cpp @@ -19,8 +19,8 @@ GlobalSettings::GlobalSettings() , _selected_nonlin_solver("Newton") , _resultsfile_name("results.csv") , _endless_sim(false) - , _outputFormat(EMPTY) - , _outputPointType(ALL) + , _outputFormat(OM_EMPTY) + , _outputPointType(OM_ALL) , _alarm_time(0) { } diff --git a/SimulationRuntime/cpp/Core/Solver/SolverDefaultImplementation.cpp b/SimulationRuntime/cpp/Core/Solver/SolverDefaultImplementation.cpp index 2c8a4f69776..7c433da7e8f 100644 --- a/SimulationRuntime/cpp/Core/Solver/SolverDefaultImplementation.cpp +++ b/SimulationRuntime/cpp/Core/Solver/SolverDefaultImplementation.cpp @@ -111,7 +111,7 @@ void SolverDefaultImplementation::initialize() timeevent_system->setTime(_tCurrent); - if(_settings->getGlobalSettings()->getOutputPointType() != EMPTY2 && _settings->getGlobalSettings()->getOutputFormat() != EMPTY) + if(_settings->getGlobalSettings()->getOutputPointType() != OM_EMPTY2 && _settings->getGlobalSettings()->getOutputFormat() != OM_EMPTY) writeoutput_system->writeOutput(IWriteOutput::HEAD_LINE); // Allocate array with values of zero functions @@ -192,7 +192,7 @@ void SolverDefaultImplementation::writeToFile(const int& stp, const double& t, c } #endif - if(_settings->getGlobalSettings()->getOutputFormat()!= EMPTY) + if(_settings->getGlobalSettings()->getOutputFormat()!= OM_EMPTY) { IWriteOutput* writeoutput_system = dynamic_cast(_system); diff --git a/SimulationRuntime/cpp/Core/Utils/extension/logger.cpp b/SimulationRuntime/cpp/Core/Utils/extension/logger.cpp index d2688e28dbf..ca31e5da204 100644 --- a/SimulationRuntime/cpp/Core/Utils/extension/logger.cpp +++ b/SimulationRuntime/cpp/Core/Utils/extension/logger.cpp @@ -8,7 +8,7 @@ #include #include -Logger* Logger::instance = 0; +Logger* Logger::instance = NULL; Logger::Logger(LogSettings settings, bool enabled) : _settings(settings), _isEnabled(enabled) { @@ -50,18 +50,17 @@ bool Logger::isOutput(std::pair mode) const return isOutput(mode.first, mode.second); } - std::string Logger::getPrefix(LogCategory cat, LogLevel lvl) const { switch(lvl) { - case(DEBUG): + case(OM_DEBUG): return "DEBUG: "; - case(ERROR): + case(OM_ERROR): return "ERROR: "; - case(INFO): + case(OM_INFO): return "INFO: "; - case(WARNING): + case(OM_WARNING): return "WARNING: "; default: return ""; diff --git a/SimulationRuntime/cpp/FMU/FMULogger.cpp b/SimulationRuntime/cpp/FMU/FMULogger.cpp index 3bd3007f3d1..fa4eab569a1 100644 --- a/SimulationRuntime/cpp/FMU/FMULogger.cpp +++ b/SimulationRuntime/cpp/FMU/FMULogger.cpp @@ -9,7 +9,7 @@ #include #if defined(_MSC_VER) && !defined(RUNTIME_STATIC_LINKING) - Logger* Logger::instance = 0; + Logger* Logger::instance = NULL; #endif FMULogger::FMULogger(fmiCallbackLogger callbackLogger, fmiComponent component, fmiString instanceName) : Logger(false), @@ -25,14 +25,14 @@ void FMULogger::writeInternal(std::string errorMsg, LogCategory cat, LogLevel lv { switch(lvl) { - case(ERROR): + case(OM_ERROR): callbackLogger(component, instanceName, fmiError, "?", errorMsg.c_str()); break; - case(WARNING): + case(OM_WARNING): callbackLogger(component, instanceName, fmiWarning, "?", errorMsg.c_str()); break; - case(INFO): - case(DEBUG): + case(OM_INFO): + case(OM_DEBUG): callbackLogger(component, instanceName, fmiOK, "?", errorMsg.c_str()); break; default: diff --git a/SimulationRuntime/cpp/Include/Core/SimulationSettings/IGlobalSettings.h b/SimulationRuntime/cpp/Include/Core/SimulationSettings/IGlobalSettings.h index 37dcf2f34b8..4583a2735fe 100644 --- a/SimulationRuntime/cpp/Include/Core/SimulationSettings/IGlobalSettings.h +++ b/SimulationRuntime/cpp/Include/Core/SimulationSettings/IGlobalSettings.h @@ -25,18 +25,21 @@ using std::string; #include -enum OutputFormat {CSV, MAT, BUFFER, EMPTY}; +// adrpo: the MSVC compiler has issues with some of the enumerations (OUT, DEBUG, ERROR) +enum OutputFormat {OM_CSV, OM_MAT, OM_BUFFER, OM_EMPTY}; +enum LogCategory {OM_INIT = 0, OM_NLS = 1, OM_LS = 2, OM_SOLV = 3, OM_OUT = 4, OM_EVT = 5, OM_OTHER = 6, OM_MOD = 7}; +enum LogLevel {OM_ERROR = 0, OM_WARNING = 1, OM_INFO = 2, OM_DEBUG = 3}; + +enum OutputPointType {OM_ALL, OM_STEP, OM_EMPTY2}; -enum LogCategory {INIT = 0, NLS = 1, LS = 2, SOLV = 3, OUT = 4, EVT = 5, OTHER = 6, MOD = 7}; -enum LogLevel {ERROR = 0, WARNING = 1, INFO = 2, DEBUG = 3}; struct LogSettings { std::vector modes; LogSettings() { - modes = std::vector(8,ERROR); + modes = std::vector(8,OM_ERROR); } void setAll(LogLevel l) @@ -46,7 +49,6 @@ struct LogSettings } }; -enum OutputPointType {ALL, STEP, EMPTY2}; class IGlobalSettings { public: diff --git a/SimulationRuntime/cpp/Include/Core/Utils/extension/logger.hpp b/SimulationRuntime/cpp/Include/Core/Utils/extension/logger.hpp index c3a3872c287..c0240f04da4 100644 --- a/SimulationRuntime/cpp/Include/Core/Utils/extension/logger.hpp +++ b/SimulationRuntime/cpp/Include/Core/Utils/extension/logger.hpp @@ -79,6 +79,4 @@ class BOOST_EXTENSION_EXPORT_DECL Logger bool _isEnabled; }; - - #endif /* LOGGER_HPP_ */ diff --git a/SimulationRuntime/cpp/Include/FMU/FMUGlobalSettings.h b/SimulationRuntime/cpp/Include/FMU/FMUGlobalSettings.h index 10b80be113b..8f3b8c14660 100644 --- a/SimulationRuntime/cpp/Include/FMU/FMUGlobalSettings.h +++ b/SimulationRuntime/cpp/Include/FMU/FMUGlobalSettings.h @@ -27,10 +27,10 @@ class FMUGlobalSettings : public IGlobalSettings virtual bool getInfoOutput() { return false; } virtual void setInfoOutput(bool) {} virtual string getOutputPath() { return "./"; } - virtual OutputFormat getOutputFormat(){return EMPTY;} + virtual OutputFormat getOutputFormat(){return OM_EMPTY;} virtual LogSettings getLogSettings() {return LogSettings();} virtual void setLogSettings(LogSettings) {} - virtual OutputPointType getOutputPointType() { return ALL; }; + virtual OutputPointType getOutputPointType() { return OM_ALL; }; virtual void setOutputPointType(OutputPointType) {}; virtual void setOutputFormat(OutputFormat) {} virtual void setOutputPath(string) {} diff --git a/SimulationRuntime/cpp/Include/FMU/FMUWrapper.h b/SimulationRuntime/cpp/Include/FMU/FMUWrapper.h index 7860c7ec5d4..afd94337a48 100644 --- a/SimulationRuntime/cpp/Include/FMU/FMUWrapper.h +++ b/SimulationRuntime/cpp/Include/FMU/FMUWrapper.h @@ -52,7 +52,7 @@ class FMUWrapper : public IFMUInterface virtual fmiStatus setDebugLogging (fmiBoolean loggingOn) { - Logger::setEnabled(loggingOn); + Logger::setEnabled(loggingOn); return fmiOK; } @@ -66,11 +66,11 @@ class FMUWrapper : public IFMUInterface virtual fmiStatus setContinuousStates (const fmiReal states[], size_t nx) { - Logger::write("setContinuousStates called",OTHER,INFO); + Logger::write("setContinuousStates called",OM_OTHER,OM_INFO); // to set states do the folowing - std::stringstream message; - message << "Setting continuous states"; - Logger::write(message.str(),OTHER,INFO); + std::stringstream message; + message << "Setting continuous states"; + Logger::write(message.str(),OM_OTHER,OM_INFO); _model->setContinuousStates(states); _need_update = true; return fmiOK; @@ -144,13 +144,13 @@ class FMUWrapper : public IFMUInterface eventInfo.terminateSimulation = fmiFalse; eventInfo.upcomingTimeEvent = fmiFalse; //eventInfo.nextTimeEvent no need to set this for this model - Logger::write("Initialization completed",OTHER,INFO); + Logger::write("Initialization completed",OM_OTHER,OM_INFO); return fmiOK; } virtual fmiStatus getDerivatives (fmiReal derivatives[] , size_t nx) { - Logger::write("Try to get derivatives",OTHER,INFO); + Logger::write("Try to get derivatives",OM_OTHER,OM_INFO); updateModel(); _model->getRHS(derivatives); return fmiOK; diff --git a/SimulationRuntime/cpp/Include/FMU2/FMU2GlobalSettings.h b/SimulationRuntime/cpp/Include/FMU2/FMU2GlobalSettings.h index a5bdf888e28..0e6fe4b1d84 100644 --- a/SimulationRuntime/cpp/Include/FMU2/FMU2GlobalSettings.h +++ b/SimulationRuntime/cpp/Include/FMU2/FMU2GlobalSettings.h @@ -63,10 +63,10 @@ class FMU2GlobalSettings : public IGlobalSettings virtual bool getInfoOutput() { return false; } virtual void setInfoOutput(bool) {} virtual string getOutputPath() { return "./"; } - virtual OutputFormat getOutputFormat() { return EMPTY; } + virtual OutputFormat getOutputFormat() { return OM_EMPTY; } virtual LogSettings getLogSettings() { return LogSettings(); } virtual void setLogSettings(LogSettings) {} - virtual OutputPointType getOutputPointType() { return ALL; }; + virtual OutputPointType getOutputPointType() { return OM_ALL; }; virtual void setOutputPointType(OutputPointType) {}; virtual void setOutputFormat(OutputFormat) {} virtual void setOutputPath(string) {} diff --git a/SimulationRuntime/cpp/SimCoreFactory/OMCFactory/OMCFactory.cpp b/SimulationRuntime/cpp/SimCoreFactory/OMCFactory/OMCFactory.cpp index 3b8caff79ff..a77a6c61ce5 100644 --- a/SimulationRuntime/cpp/SimCoreFactory/OMCFactory/OMCFactory.cpp +++ b/SimulationRuntime/cpp/SimCoreFactory/OMCFactory/OMCFactory.cpp @@ -55,10 +55,29 @@ SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[]) { int opt; int portnum; - std::map outputFormatMap = map_list_of("csv", CSV)("mat", MAT)("buffer", BUFFER)("empty", EMPTY); - std::map logCatMap = map_list_of("init", INIT)("nls", NLS)("ls",LS)("solv", SOLV)("output", OUT)("event",EVT)("modell",MOD)("other",OTHER); - std::map logLvlMap = map_list_of("error", ERROR)("warning", WARNING)("info", INFO)("debug", DEBUG); - std::map outputPointTypeMap = map_list_of("all", ALL)("step", STEP)("empty2",EMPTY2); + std::map outputFormatMap = map_list_of + ("csv", OM_CSV) + ("mat", OM_MAT) + ("buffer", OM_BUFFER) + ("empty", OM_EMPTY); + std::map logCatMap = map_list_of + ("init", OM_INIT) + ("nls", OM_NLS) + ("ls", OM_LS) + ("solv", OM_SOLV) + ("output", OM_OUT) + ("event", OM_EVT) + ("modell", OM_MOD) + ("other", OM_OTHER); + std::map logLvlMap = map_list_of + ("error", OM_ERROR) + ("warning", OM_WARNING) + ("info", OM_INFO) + ("debug", OM_DEBUG); + std::map outputPointTypeMap = map_list_of + ("all", OM_ALL) + ("step", OM_STEP) + ("empty2", OM_EMPTY2); po::options_description desc("Allowed options"); desc.add_options() ("help", "produce help message") @@ -157,7 +176,7 @@ SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[]) //cout << "results file: " << vm["results-file"].as() << std::endl; outputFormat_str = vm["OutputFormat"].as(); outputFomat = outputFormatMap[outputFormat_str]; - if(!((outputFomat==CSV) || (outputFomat==EMPTY)||(outputFomat==BUFFER)||(outputFomat==MAT))) + if(!((outputFomat==OM_CSV) || (outputFomat==OM_EMPTY)||(outputFomat==OM_BUFFER)||(outputFomat==OM_MAT))) { std::string eception_msg = "The output format is not supported yet. Please use outputFormat=\"csv\" or outputFormat=\"empty\" or outputFormat=\"matlab\"in simulate command "; throw ModelicaSimulationError(MODEL_FACTORY,eception_msg.c_str()); @@ -184,26 +203,26 @@ SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[]) LogSettings logSet; if (vm.count("log-settings")) { - std::vector log_vec = vm["log-settings"].as >(),tmpvec; - for(unsigned i=0;i(log_vec[i]) + "\n"); - } + std::vector log_vec = vm["log-settings"].as >(),tmpvec; + for(unsigned i=0;i(log_vec[i]) + "\n"); + } } diff --git a/SimulationRuntime/cpp/Solver/CVode/CVode.cpp b/SimulationRuntime/cpp/Solver/CVode/CVode.cpp index 04b33c1fd4f..dcb2921d615 100644 --- a/SimulationRuntime/cpp/Solver/CVode/CVode.cpp +++ b/SimulationRuntime/cpp/Solver/CVode/CVode.cpp @@ -10,6 +10,10 @@ #include #include +#if defined(_MSC_VER) && !defined(RUNTIME_STATIC_LINKING) + Logger* Logger::instance = NULL; +#endif + Cvode::Cvode(IMixedSystem* system, ISolverSettings* settings) : SolverDefaultImplementation(system, settings), _cvodesettings(dynamic_cast(_settings)), @@ -308,14 +312,14 @@ void Cvode::initialize() _cvode_initialized = true; - Logger::write("Cvode: initialized",SOLV,DEBUG); + Logger::write("Cvode: initialized",OM_SOLV,OM_DEBUG); } } void Cvode::solve(const SOLVERCALL action) { - bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == ALL); - bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == EMPTY2); + bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OM_ALL); + bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == OM_EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == OM_EMPTY2); #ifdef RUNTIME_PROFILING MEASURETIME_REGION_DEFINE(cvodeSolveFunctionHandler, "solve"); @@ -454,8 +458,8 @@ void Cvode::CVodeCore() if (_idid < 0) throw ModelicaSimulationError(SOLVER,"CVode::ReInit"); - bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == ALL); - bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == EMPTY2); + bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OM_ALL); + bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == OM_EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == OM_EMPTY2); while (_solverStatus & ISolver::CONTINUE && !_interrupt ) { @@ -939,13 +943,13 @@ void Cvode::writeSimulationInfo() flag = CVodeGetNonlinSolvStats(_cvodeMem, &nni, &ncfn); - Logger::write("Cvode: number steps = " + boost::lexical_cast(nst),SOLV,INFO); - Logger::write("Cvode: function evaluations 'f' = " + boost::lexical_cast(nfe),SOLV,INFO); - Logger::write("Cvode: error test failures 'netf' = " + boost::lexical_cast(netfS),SOLV,INFO); - Logger::write("Cvode: linear solver setups 'nsetups' = " + boost::lexical_cast(nsetups),SOLV,INFO); - Logger::write("Cvode: nonlinear iterations 'nni' = " + boost::lexical_cast(nni),SOLV,INFO); - Logger::write("Cvode: convergence failures 'ncfn' = " + boost::lexical_cast(ncfn),SOLV,INFO); - Logger::write("Cvode: number of evaluateODE calls 'eODE' = " + boost::lexical_cast(_numberOfOdeEvaluations),SOLV,INFO); + Logger::write("Cvode: number steps = " + boost::lexical_cast(nst),OM_SOLV,OM_INFO); + Logger::write("Cvode: function evaluations 'f' = " + boost::lexical_cast(nfe),OM_SOLV,OM_INFO); + Logger::write("Cvode: error test failures 'netf' = " + boost::lexical_cast(netfS),OM_SOLV,OM_INFO); + Logger::write("Cvode: linear solver setups 'nsetups' = " + boost::lexical_cast(nsetups),OM_SOLV,OM_INFO); + Logger::write("Cvode: nonlinear iterations 'nni' = " + boost::lexical_cast(nni),OM_SOLV,OM_INFO); + Logger::write("Cvode: convergence failures 'ncfn' = " + boost::lexical_cast(ncfn),OM_SOLV,OM_INFO); + Logger::write("Cvode: number of evaluateODE calls 'eODE' = " + boost::lexical_cast(_numberOfOdeEvaluations),OM_SOLV,OM_INFO); //// Solver //outputStream << "\nSolver: " << getName() diff --git a/SimulationRuntime/cpp/Solver/IDA/IDA.cpp b/SimulationRuntime/cpp/Solver/IDA/IDA.cpp index bbae0b86aa2..670ded2ba0a 100644 --- a/SimulationRuntime/cpp/Solver/IDA/IDA.cpp +++ b/SimulationRuntime/cpp/Solver/IDA/IDA.cpp @@ -6,6 +6,10 @@ #include #include +#if defined(_MSC_VER) && !defined(RUNTIME_STATIC_LINKING) + Logger* Logger::instance = NULL; +#endif + Ida::Ida(IMixedSystem* system, ISolverSettings* settings) : SolverDefaultImplementation(system, settings), _idasettings(dynamic_cast(_settings)), @@ -282,8 +286,8 @@ void Ida::initialize() void Ida::solve(const SOLVERCALL action) { - bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == ALL); - bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == EMPTY2); + bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OM_ALL); + bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == OM_EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == OM_EMPTY2); #ifdef RUNTIME_PROFILING MEASURETIME_REGION_DEFINE(idaSolveFunctionHandler, "solve"); @@ -422,8 +426,8 @@ void Ida::IDACore() if (_idid < 0) throw std::runtime_error("IDA::ReInit"); - bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == ALL); - bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == EMPTY2); + bool writeEventOutput = (_settings->getGlobalSettings()->getOutputPointType() == OM_ALL); + bool writeOutput = !(_settings->getGlobalSettings()->getOutputFormat() == OM_EMPTY) && !(_settings->getGlobalSettings()->getOutputPointType() == OM_EMPTY2); while (_solverStatus & ISolver::CONTINUE && !_interrupt ) { @@ -919,12 +923,12 @@ void Ida::writeSimulationInfo() flag = IDAGetNonlinSolvStats(_idaMem, &nni, &ncfn); - Logger::write("Cvode: number steps = " + boost::lexical_cast(nst),SOLV,INFO); - Logger::write("Cvode: function evaluations 'f' = " + boost::lexical_cast(nfe),SOLV,INFO); - Logger::write("Cvode: error test failures 'netf' = " + boost::lexical_cast(netfS),SOLV,INFO); - Logger::write("Cvode: linear solver setups 'nsetups' = " + boost::lexical_cast(nsetups),SOLV,INFO); - Logger::write("Cvode: nonlinear iterations 'nni' = " + boost::lexical_cast(nni),SOLV,INFO); - Logger::write("Cvode: convergence failures 'ncfn' = " + boost::lexical_cast(ncfn),SOLV,INFO); + Logger::write("Cvode: number steps = " + boost::lexical_cast(nst),OM_SOLV,OM_INFO); + Logger::write("Cvode: function evaluations 'f' = " + boost::lexical_cast(nfe),OM_SOLV,OM_INFO); + Logger::write("Cvode: error test failures 'netf' = " + boost::lexical_cast(netfS),OM_SOLV,OM_INFO); + Logger::write("Cvode: linear solver setups 'nsetups' = " + boost::lexical_cast(nsetups),OM_SOLV,OM_INFO); + Logger::write("Cvode: nonlinear iterations 'nni' = " + boost::lexical_cast(nni),OM_SOLV,OM_INFO); + Logger::write("Cvode: convergence failures 'ncfn' = " + boost::lexical_cast(ncfn),OM_SOLV,OM_INFO); } int Ida::check_flag(void *flagvalue, const char *funcname, int opt)