Skip to content

Commit 0ed5264

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Fix scalability for systems without variables
If a system has only parameters and no equations, we now properly estimate the size of the HashSet used for creating the ModelInfo structure as variables+parameters. This avoids using linear search due to the HashSet having size 1. This fixes ticket:4590. Belonging to [master]: - OpenModelica/OMCompiler#1961
1 parent 32ea34f commit 0ed5264

File tree

1 file changed

+42
-9
lines changed

1 file changed

+42
-9
lines changed

Compiler/SimCode/SimCodeUtil.mo

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ import Inline;
9898
import List;
9999
import Matching;
100100
import MetaModelica.Dangerous;
101+
import Mutable;
101102
import PriorityQueue;
102103
import SimCodeDump;
103104
import SimCodeFunctionUtil;
@@ -240,10 +241,11 @@ protected
240241
BackendDAE.InlineData inlineData;
241242
list<SimCodeVar.SimVar> inlineSimKnVars;
242243
BackendDAE.Variables emptyVars;
243-
constant Boolean debug = false;
244244
Integer SymEuler_help = 0;
245245
SimCodeVar.SimVar dtSimVar;
246246
BackendDAE.Var dtVar;
247+
248+
constant Boolean debug = false;
247249
algorithm
248250
try
249251
execStat("Backend phase and start with SimCode phase");
@@ -401,6 +403,7 @@ algorithm
401403

402404
// update index of zero-Crossings after equations are created
403405
zeroCrossings := updateZeroCrossEqnIndex(zeroCrossings, eqBackendSimCodeMapping, BackendDAEUtil.equationArraySizeBDAE(dlow));
406+
if debug then execStat("simCode: update zero crossing index"); end if;
404407

405408
// replace div operator with div operator with check of Division by zero
406409
allEquations := List.map(allEquations, addDivExpErrorMsgtoSimEqSystem);
@@ -416,6 +419,7 @@ algorithm
416419
initialEquations := List.map(initialEquations, addDivExpErrorMsgtoSimEqSystem);
417420
initialEquations_lambda0 := List.map(initialEquations_lambda0, addDivExpErrorMsgtoSimEqSystem);
418421
removedInitialEquations := List.map(removedInitialEquations, addDivExpErrorMsgtoSimEqSystem);
422+
if debug then execStat("simCode: addDivExpErrorMsgtoSimEqSystem"); end if;
419423

420424
// collect all LinearSystem and NonlinearSystem algebraic system in modelInfo and update
421425
// the corresponding index (indexNonLinear, indexLinear) in SES_NONLINEAR and SES_LINEAR
@@ -436,11 +440,13 @@ algorithm
436440

437441
// collect symbolic jacobians from state selection
438442
(stateSets, modelInfo, SymbolicJacsStateSelect) := addAlgebraicLoopsModelInfoStateSets(stateSets, modelInfo);
443+
if debug then execStat("simCode: collect and index LS/NLS in modelInfo"); end if;
439444

440445
// collect fmi partial derivative
441446
if FMI.isFMIVersion20(FMUVersion) then
442447
(SymbolicJacsFMI, modelStructure, modelInfo, SymbolicJacsTemp, uniqueEqIndex) := createFMIModelStructure(inFMIDer, modelInfo, uniqueEqIndex);
443448
SymbolicJacsNLS := listAppend(SymbolicJacsTemp, SymbolicJacsNLS);
449+
if debug then execStat("simCode: create FMI model structure"); end if;
444450
end if;
445451
// collect symbolic jacobians in linear loops of the overall jacobians
446452
(LinearMatrices, uniqueEqIndex) := createJacobianLinearCode(symJacs, modelInfo, uniqueEqIndex);
@@ -449,6 +455,7 @@ algorithm
449455
SymbolicJacs := listAppend(SymbolicJacs, SymbolicJacsStateSelect);
450456
// collect jacobian equation only for equantion info file
451457
jacobianEquations := collectAllJacobianEquations(SymbolicJacs);
458+
if debug then execStat("simCode: create Jacobian linear code"); end if;
452459

453460
SymbolicJacs := listAppend(listReverse(SymbolicJacsNLS), SymbolicJacs);
454461
SymbolicJacs := listAppend(SymbolicJacs, SymbolicJacsTemp);
@@ -6903,7 +6910,6 @@ algorithm
69036910
ny_int, np_int, na_int, ny_bool, np_bool, na_bool, ny_string, np_string, na_string,
69046911
numStateSets, numOptimizeConstraints, numOptimizeFinalConstraints);
69056912
if debug then execStat("simCode: createVarInfo"); end if;
6906-
if debug then execStat("simCode: getHighestDerivation"); end if;
69076913
hasLargeEqSystems := hasLargeEquationSystems(dlow, inInitDAE);
69086914
if debug then execStat("simCode: hasLargeEquationSystems"); end if;
69096915
modelInfo := SimCode.MODELINFO(class_, dlow.shared.info.description, directory, varInfo, vars, functions,
@@ -7415,65 +7421,92 @@ protected
74157421
BackendDAE.Variables aliasVars1, aliasVars2;
74167422
BackendDAE.EqSystems systs1, systs2;
74177423
BackendDAE.Shared shared;
7418-
array<HashSet.HashSet> hs = arrayCreate(1, HashSet.emptyHashSetSized(Util.nextPrime(BackendDAEUtil.daeSize(inSimDAE)+BackendDAEUtil.daeSize(inInitDAE))));
7424+
Mutable<HashSet.HashSet> hs;
74197425
array<list<SimCodeVar.SimVar>> simVars = arrayCreate(size(SimVarsIndex,1), {});
7426+
Integer primeSize;
7427+
7428+
constant Boolean debug = false;
74207429
algorithm
74217430
BackendDAE.DAE(eqs=systs1, shared=shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars1, localKnownVars=localKnownVars1, externalObjects=extvars1, aliasVars=aliasVars1)) := inSimDAE;
74227431
BackendDAE.DAE(eqs=systs2, shared=BackendDAE.SHARED(globalKnownVars=globalKnownVars2, localKnownVars=localKnownVars2, externalObjects=extvars2, aliasVars=aliasVars2)) := inInitDAE;
74237432

7433+
primeSize := Util.nextPrime(
7434+
integer(1.4*(
7435+
BackendVariable.varsSize(globalKnownVars1)+BackendVariable.varsSize(globalKnownVars2)+
7436+
BackendVariable.varsSize(localKnownVars1)+BackendVariable.varsSize(localKnownVars2)+
7437+
BackendVariable.varsSize(aliasVars1)+BackendVariable.varsSize(aliasVars2)+
7438+
BackendVariable.varsSize(extvars1)+BackendVariable.varsSize(extvars2)+
7439+
BackendDAEUtil.daeSize(inSimDAE)+BackendDAEUtil.daeSize(inInitDAE)
7440+
)));
7441+
hs := Mutable.create(HashSet.emptyHashSetSized(primeSize));
7442+
74247443
if not Flags.isSet(Flags.NO_START_CALC) then
74257444
(systs1) := List.map2(systs1, preCalculateStartValues, globalKnownVars1, shared);
74267445
(globalKnownVars1, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(globalKnownVars1, evaluateStartValues, shared);
74277446
//systs2 := List.map1(systs2, preCalculateStartValues, globalKnownVars2);
7447+
if debug then execStat("createVars: evaluateStartValues"); end if;
74287448
end if;
74297449

74307450
// ### simulation ###
74317451
// Extract from variable list
74327452
simVars := List.fold1(list(BackendVariable.daeVars(syst) for syst in systs1), BackendVariable.traverseBackendDAEVars, function extractVarsFromList(aliasVars=aliasVars1, vars=globalKnownVars1, hs=hs), simVars);
7453+
if debug then execStat("createVars: variable list"); end if;
74337454

74347455
// Extract from known variable list
74357456
simVars := BackendVariable.traverseBackendDAEVars(globalKnownVars1, function extractVarsFromList(aliasVars=aliasVars1, vars=globalKnownVars1, hs=hs), simVars);
7457+
if debug then execStat("createVars: known variable list"); end if;
74367458

74377459
// Extract from localKnownVars variable list
74387460
simVars := BackendVariable.traverseBackendDAEVars(localKnownVars1, function extractVarsFromList(aliasVars=aliasVars1, vars=globalKnownVars1, hs=hs), simVars);
7461+
if debug then execStat("createVars: local known variables list"); end if;
74397462

74407463
// Extract from removed variable list
74417464
simVars := BackendVariable.traverseBackendDAEVars(aliasVars1, function extractVarsFromList(aliasVars=aliasVars1, vars=globalKnownVars1, hs=hs), simVars);
7465+
if debug then execStat("createVars: removed variables list"); end if;
74427466

74437467
// Extract from external object list
74447468
simVars := BackendVariable.traverseBackendDAEVars(extvars1, function extractVarsFromList(aliasVars=aliasVars1, vars=globalKnownVars1, hs=hs), simVars);
7469+
if debug then execStat("createVars: external object list"); end if;
74457470

74467471

74477472
// ### initialization ###
74487473
// Extract from variable list
74497474
simVars := List.fold1(list(BackendVariable.daeVars(syst) for syst in systs2), BackendVariable.traverseBackendDAEVars, function extractVarsFromList(aliasVars=aliasVars2, vars=globalKnownVars2, hs=hs), simVars);
7475+
if debug then execStat("createVars: variable list (init)"); end if;
74507476

74517477
// Extract from known variable list
74527478
simVars := BackendVariable.traverseBackendDAEVars(globalKnownVars2, function extractVarsFromList(aliasVars=aliasVars2, vars=globalKnownVars2, hs=hs), simVars);
7479+
if debug then execStat("createVars: known variable list (init)"); end if;
74537480

74547481
// Extract from localKnownVars variable list
74557482
simVars := BackendVariable.traverseBackendDAEVars(localKnownVars2, function extractVarsFromList(aliasVars=aliasVars2, vars=globalKnownVars2, hs=hs), simVars);
7483+
if debug then execStat("createVars: local known variables list (init)"); end if;
74567484

74577485
// Extract from removed variable list
74587486
simVars := BackendVariable.traverseBackendDAEVars(aliasVars2, function extractVarsFromList(aliasVars=aliasVars2, vars=globalKnownVars2, hs=hs), simVars);
7487+
if debug then execStat("createVars: removed variables list (init)"); end if;
74597488

74607489
// Extract from external object list
74617490
simVars := BackendVariable.traverseBackendDAEVars(extvars2, function extractVarsFromList(aliasVars=aliasVars2, vars=globalKnownVars2, hs=hs), simVars);
7462-
7491+
if debug then execStat("createVars: external object list (init)"); end if;
74637492

74647493
addTempVars(simVars, tempvars);
7494+
if debug then execStat("createVars: addTempVars"); end if;
74657495
//BaseHashSet.printHashSet(hs);
74667496

74677497
// sort variables on index
74687498
sortSimvars(simVars);
7499+
if debug then execStat("createVars: sortSimVars"); end if;
74697500

74707501
if stringEqual(Config.simCodeTarget(), "Cpp") then
74717502
extendIncompleteArray(simVars);
7503+
if debug then execStat("createVars: Cpp, extendIncompleteArray"); end if;
74727504
end if;
74737505

74747506
// Index of algebraic and parameters need to fix due to separation of integer variables
74757507
fixIndex(simVars);
74767508
setVariableIndex(simVars);
7509+
if debug then execStat("createVars: fix and set index"); end if;
74777510

74787511
outVars := SimCodeVar.SIMVARS(
74797512
Dangerous.arrayGetNoBoundsChecking(simVars, Integer(SimVarsIndex.state)),
@@ -7511,9 +7544,9 @@ protected function extractVarsFromList
75117544
input output BackendDAE.Var var;
75127545
input output array<list<SimCodeVar.SimVar>> simVars;
75137546
input BackendDAE.Variables aliasVars, vars;
7514-
input array<HashSet.HashSet> hs;
7547+
input Mutable<HashSet.HashSet> hs;
75157548
algorithm
7516-
if if ComponentReference.isPreCref(var.varName) or ComponentReference.isStartCref(var.varName) then false else not BaseHashSet.has(var.varName, arrayGet(hs,1)) then
7549+
if if ComponentReference.isPreCref(var.varName) or ComponentReference.isStartCref(var.varName) then false else not BaseHashSet.has(var.varName, Mutable.access(hs)) then
75177550
/* ignore variable, since they are treated by kind in the codegen */
75187551
if not BackendVariable.isAlgebraicOldState(var) then
75197552
extractVarFromVar(var, aliasVars, vars, simVars, hs);
@@ -7531,7 +7564,7 @@ protected function extractVarFromVar
75317564
input BackendDAE.Variables inAliasVars;
75327565
input BackendDAE.Variables inVars;
75337566
input array<list<SimCodeVar.SimVar>> simVars;
7534-
input array<HashSet.HashSet> hs "all processed crefs";
7567+
input Mutable<HashSet.HashSet> hs "all processed crefs";
75357568
protected
75367569
SimCodeVar.SimVar simVar;
75377570
SimCodeVar.SimVar derivSimvar;
@@ -7545,10 +7578,10 @@ algorithm
75457578

75467579

75477580
// update HashSet
7548-
arrayUpdate(hs, 1, BaseHashSet.add(simVar.name, arrayGet(hs,1)));
7581+
Mutable.update(hs, BaseHashSet.add(simVar.name, Mutable.access(hs)));
75497582
if (not isalias) and (BackendVariable.isStateVar(dlowVar) or BackendVariable.isAlgState(dlowVar)) then
75507583
derivSimvar := derVarFromStateVar(simVar);
7551-
arrayUpdate(hs, 1, BaseHashSet.add(derivSimvar.name, arrayGet(hs,1)));
7584+
Mutable.update(hs, BaseHashSet.add(derivSimvar.name, Mutable.access(hs)));
75527585
else
75537586
derivSimvar := simVar; // Just in case
75547587
end if;

0 commit comments

Comments
 (0)