Skip to content

Commit 12fc73c

Browse files
authored
[NB] introduce flag to turn of sim code scalarization (#14497)
* [NB] introduce flag to turn of sim code scalarization * [NB] allow array strings as literal bindings * [testsuite] add init xml array test files
1 parent 27490c8 commit 12fc73c

25 files changed

+814
-78
lines changed

OMCompiler/Compiler/FrontEnd/Expression.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13451,6 +13451,7 @@ public function isSimpleLiteralValue "A value that requires nothing special duri
1345113451
output Boolean b;
1345213452
algorithm
1345313453
b := match exp
13454+
case DAE.SCONST() then allow_arrays /* allow string constants with arrays */;
1345413455
case DAE.ICONST() then true;
1345513456
case DAE.RCONST() then true;
1345613457
case DAE.BCONST() then true;

OMCompiler/Compiler/NBackEnd/Classes/NBVariable.mo

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,19 +1525,34 @@ public
15251525
function hasEvaluableBinding
15261526
extends checkVar;
15271527
protected
1528-
Expression binding;
1529-
algorithm
1530-
if isBound(var_ptr) then
1531-
binding := Binding.getExp(var.binding);
1532-
b := Expression.isLiteral(binding);
1528+
Expression binding, start;
1529+
Option<Expression> opt_start;
1530+
function isEvaluable
1531+
input Expression exp;
1532+
output Boolean b;
1533+
protected
1534+
Expression new_exp;
1535+
algorithm
1536+
b := Expression.isLiteralXML(exp);
15331537
if not b then
15341538
// try to extract literal from array constructor (use dummy map, there should not be any new iterators)
1535-
(_, binding) := Iterator.extract(binding);
1536-
binding := SimplifyExp.simplifyDump(binding, true, getInstanceName());
1537-
b := Expression.isLiteral(Ceval.tryEvalExp(binding));
1539+
(_, new_exp) := Iterator.extract(exp);
1540+
new_exp := SimplifyExp.simplifyDump(new_exp, true, getInstanceName());
1541+
b := Expression.isLiteralXML(Ceval.tryEvalExp(new_exp));
15381542
end if;
1543+
end isEvaluable;
1544+
algorithm
1545+
// check binding
1546+
if isBound(var_ptr) then
1547+
binding := Binding.getExp(var.binding);
1548+
b := isEvaluable(binding);
15391549
else
1540-
b := false;
1550+
// check start value
1551+
opt_start := getStartAttribute(var_ptr);
1552+
b := match opt_start
1553+
case SOME(start) then isEvaluable(start);
1554+
else false;
1555+
end match;
15411556
end if;
15421557
end hasEvaluableBinding;
15431558

@@ -1601,9 +1616,9 @@ public
16011616
end setFixed;
16021617

16031618
function setBindingAsStart
1604-
"use this if a binding is found out to be constant, remove variable to known vars (param/const)
1605-
NOTE: this overwrites the old start value. throw error/warning if different?"
1619+
"use this if a binding is found out to be constant, remove variable to known vars (param/const)"
16061620
input Pointer<Variable> var_ptr;
1621+
input Boolean overwrite = false;
16071622
protected
16081623
Variable var;
16091624
algorithm
@@ -1615,7 +1630,7 @@ public
16151630

16161631
case Variable.VARIABLE(backendinfo = binfo as BackendInfo.BACKEND_INFO()) algorithm
16171632
start := Binding.getExp(var.binding);
1618-
binfo.attributes := VariableAttributes.setStartAttribute(binfo.attributes, start, true);
1633+
binfo.attributes := VariableAttributes.setStartAttribute(binfo.attributes, start, overwrite);
16191634
var.backendinfo := binfo;
16201635
then var;
16211636

@@ -1629,8 +1644,9 @@ public
16291644
function setBindingAsStartAndFix
16301645
input output Pointer<Variable> var_ptr;
16311646
input Boolean b = true;
1647+
input Boolean overwrite = false;
16321648
algorithm
1633-
setBindingAsStart(var_ptr);
1649+
setBindingAsStart(var_ptr, overwrite);
16341650
var_ptr := setFixed(var_ptr, b);
16351651
end setBindingAsStartAndFix;
16361652

OMCompiler/Compiler/NBackEnd/Modules/1_Main/NBInitialization.mo

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public
227227
local
228228
Expression e;
229229
// use the start attribute itself if it is not a literal
230-
case SOME(e) guard not Expression.isLiteral(e) then e;
230+
case SOME(e) guard not Expression.isLiteralXML(e) then e;
231231
else algorithm
232232
// create a start variable if it is a literal
233233
(_, name, start_var, start_name) := createStartVar(var, name, {});
@@ -394,7 +394,9 @@ public
394394
end if;
395395
else
396396
for c_var in BVariable.getRecordChildren(var) loop
397-
BVariable.setBindingAsStart(c_var);
397+
if BVariable.isBound(c_var) then
398+
BVariable.setBindingAsStart(c_var, true);
399+
end if;
398400
(parameter_eqs, initial_param_vars) := createParameterEquation(c_var, new_iters, idx, parameter_eqs, initial_param_vars);
399401
end for;
400402
end if;
@@ -409,8 +411,8 @@ public
409411
if BVariable.isFixed(var) then
410412
parameter_eqs := Equation.generateBindingEquation(var, idx, true, new_iters) :: parameter_eqs;
411413
end if;
412-
else
413-
BVariable.setBindingAsStart(var);
414+
elseif BVariable.isBound(var) then
415+
BVariable.setBindingAsStart(var, true);
414416
end if;
415417
end if;
416418
end createParameterEquation;
@@ -444,7 +446,7 @@ public
444446
ComponentRef new_iter;
445447

446448
// convert array constructor to for-equation if elements are not a literal
447-
case SOME(Expression.CALL(call = array_constructor as Call.TYPED_ARRAY_CONSTRUCTOR(exp = e))) guard not Expression.isLiteral(e) algorithm
449+
case SOME(Expression.CALL(call = array_constructor as Call.TYPED_ARRAY_CONSTRUCTOR(exp = e))) guard not Expression.isLiteralXML(e) algorithm
448450
(var_ptr, name, _, _, _, frames, iterator) := createIteratedStartCref(var_ptr, name);
449451
replacements := UnorderedMap.new<Expression>(ComponentRef.hash, ComponentRef.isEqual);
450452
for tpl in List.zip(array_constructor.iters, frames) loop
@@ -454,7 +456,7 @@ public
454456
then Expression.map(array_constructor.exp, function Replacements.applySimpleExp(replacements = replacements));
455457

456458
// use the start attribute itself if it is not a literal
457-
case SOME(e) guard not Expression.isLiteral(e) algorithm
459+
case SOME(e) guard not Expression.isLiteralXML(e) algorithm
458460
if Slice.isFull(var_slice) then
459461
(var_ptr, name, _, _) := createStartVar(var_ptr, name, {});
460462
iterator := Iterator.EMPTY();

OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBAlias.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ protected
265265
(const_vars, alias_vars) := List.splitOnTrue(alias_vars, BVariable.hasConstOrParamAliasBinding);
266266
for var in const_vars loop
267267
BVariable.setVarKind(var, VariableKind.PARAMETER(NONE()));
268-
BVariable.setBindingAsStartAndFix(var);
268+
BVariable.setBindingAsStartAndFix(var, true);
269269
end for;
270270
varData.parameters := VariablePointers.addList(const_vars, varData.parameters);
271271
varData.knowns := VariablePointers.addList(const_vars, varData.knowns);

OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,16 +2342,20 @@ public
23422342
protected
23432343
list<Subscript> subs;
23442344
algorithm
2345-
subs := subscriptsAllFlat(scal);
2346-
if listEmpty(subs) then
2347-
// do not do it for scalar variables
2348-
arr := NONE();
2349-
elseif List.all(subs, function Subscript.isEqual(subscript1 = Subscript.INDEX(Expression.INTEGER(1)))) then
2350-
// if it is the first element, save the array var
2351-
arr := SOME(stripSubscriptsAll(scal));
2345+
if Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE) then
2346+
subs := subscriptsAllFlat(scal);
2347+
if listEmpty(subs) then
2348+
// do not do it for scalar variables
2349+
arr := NONE();
2350+
elseif List.all(subs, function Subscript.isEqual(subscript1 = Subscript.INDEX(Expression.INTEGER(1)))) then
2351+
// if it is the first element, save the array var
2352+
arr := SOME(stripSubscriptsAll(scal));
2353+
else
2354+
// not first element
2355+
arr := NONE();
2356+
end if;
23522357
else
2353-
// not first element
2354-
arr := NONE();
2358+
arr := if Type.isArray(getSubscriptedType(scal)) then SOME(scal) else NONE();
23552359
end if;
23562360
end getArrayCrefOpt;
23572361

OMCompiler/Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4684,6 +4684,29 @@ public
46844684
end match;
46854685
end isLiteral;
46864686

4687+
function isLiteralXML
4688+
"allows for expressions additionally for init_xml"
4689+
input Expression exp;
4690+
output Boolean literal;
4691+
algorithm
4692+
literal := match exp
4693+
local
4694+
Expression call_exp;
4695+
case INTEGER() then true;
4696+
case REAL() then true;
4697+
case STRING() then true;
4698+
case BOOLEAN() then true;
4699+
case ENUM_LITERAL() then true;
4700+
case ARRAY() then exp.literal or Array.all(exp.elements, isLiteralXML);
4701+
case RECORD() then List.all(exp.elements, isLiteralXML);
4702+
case RANGE() then isLiteralXML(exp.start) and isLiteralXML(exp.stop) and
4703+
Util.applyOptionOrDefault(exp.step, isLiteralXML, true);
4704+
case FILENAME() then true;
4705+
case CALL(call = Call.TYPED_ARRAY_CONSTRUCTOR(exp = call_exp)) then isLiteralXML(call_exp);
4706+
else false;
4707+
end match;
4708+
end isLiteralXML;
4709+
46874710
function isLiteralReplace
46884711
input Expression exp;
46894712
output Boolean b;

OMCompiler/Compiler/NSimCode/NSimCode.mo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,8 @@ public
561561
partitionData = OldSimCode.PARTITIONDATA(-1,{},{},{}),
562562
daeModeData = if isSome(simCode.daeModeData) then SOME(DaeModeData.convert(Util.getOption(simCode.daeModeData))) else NONE(),
563563
inlineEquations = {},
564-
omsiData = NONE());
564+
omsiData = NONE(),
565+
scalarized = Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE));
565566
end convert;
566567

567568
function getDirectoryAndLibs

OMCompiler/Compiler/NSimCode/NSimJacobian.mo

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public
215215
SimStrongComponent.Block columnEqn;
216216
list<SimStrongComponent.Block> columnEqns = {};
217217
VarData varData;
218-
VariablePointers seed_scalar, res_scalar, tmp_scalar;
218+
VariablePointers seed_vec, res_vec, tmp_vec;
219219
Pointer<list<SimVar>> seedVars_ptr = Pointer.create({});
220220
Pointer<list<SimVar>> resVars_ptr = Pointer.create({});
221221
Pointer<list<SimVar>> tmpVars_ptr = Pointer.create({});
@@ -245,13 +245,20 @@ public
245245
indices.generic_call_map := sim_map;
246246

247247
// scalarize variables for sim code
248-
seed_scalar := VariablePointers.scalarize(varData.seedVars);
249-
res_scalar := VariablePointers.scalarize(varData.resultVars);
250-
tmp_scalar := VariablePointers.scalarize(varData.tmpVars);
248+
if Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE) then
249+
seed_vec := VariablePointers.scalarize(varData.seedVars);
250+
res_vec := VariablePointers.scalarize(varData.resultVars);
251+
tmp_vec := VariablePointers.scalarize(varData.tmpVars);
252+
else
253+
seed_vec := varData.seedVars;
254+
res_vec := varData.resultVars;
255+
tmp_vec := varData.tmpVars;
256+
end if;
257+
251258
// use dummy simcode indices to always start at 0 for column and seed vars
252-
VariablePointers.map(seed_scalar, function SimVar.traverseCreate(acc = seedVars_ptr, indices_ptr = Pointer.create(NSimCode.EMPTY_SIM_CODE_INDICES()), varType = VarType.SIMULATION));
253-
VariablePointers.map(res_scalar, function SimVar.traverseCreate(acc = resVars_ptr, indices_ptr = Pointer.create(NSimCode.EMPTY_SIM_CODE_INDICES()), varType = VarType.SIMULATION));
254-
VariablePointers.map(tmp_scalar, function SimVar.traverseCreate(acc = tmpVars_ptr, indices_ptr = Pointer.create(NSimCode.EMPTY_SIM_CODE_INDICES()), varType = VarType.SIMULATION));
259+
VariablePointers.map(seed_vec, function SimVar.traverseCreate(acc = seedVars_ptr, indices_ptr = Pointer.create(NSimCode.EMPTY_SIM_CODE_INDICES()), varType = VarType.SIMULATION));
260+
VariablePointers.map(res_vec, function SimVar.traverseCreate(acc = resVars_ptr, indices_ptr = Pointer.create(NSimCode.EMPTY_SIM_CODE_INDICES()), varType = VarType.SIMULATION));
261+
VariablePointers.map(tmp_vec, function SimVar.traverseCreate(acc = tmpVars_ptr, indices_ptr = Pointer.create(NSimCode.EMPTY_SIM_CODE_INDICES()), varType = VarType.SIMULATION));
255262
seedVars := listReverse(Pointer.access(seedVars_ptr));
256263
resVars := listReverse(Pointer.access(resVars_ptr));
257264
tmpVars := listReverse(Pointer.access(tmpVars_ptr));

OMCompiler/Compiler/NSimCode/NSimVar.mo

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ public
965965
input SplitType splitType;
966966
input VarType varType;
967967
protected
968-
VariablePointers scalar_vars;
968+
VariablePointers sim_vars = if Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE) then VariablePointers.scalarize(vars) else vars;
969969
Pointer<list<SimVar>> acc = Pointer.create({});
970970
Pointer<list<SimVar>> real_lst = Pointer.create({});
971971
Pointer<list<SimVar>> int_lst = Pointer.create({});
@@ -974,17 +974,15 @@ public
974974
Pointer<list<SimVar>> enum_lst = Pointer.create({});
975975
Pointer<SimCode.SimCodeIndices> indices_ptr = Pointer.create(simCodeIndices);
976976
algorithm
977-
// scalarize variables for simcode
978-
scalar_vars := VariablePointers.scalarize(vars);
979977
if splitType == SplitType.NONE then
980978
// Do not split and return everything as one single list
981-
VariablePointers.map(scalar_vars, function SimVar.traverseCreate(acc = acc, indices_ptr = indices_ptr, varType = varType));
979+
VariablePointers.map(sim_vars, function SimVar.traverseCreate(acc = acc, indices_ptr = indices_ptr, varType = varType));
982980
simVars := {listReverse(Pointer.access(acc))};
983981
simCodeIndices := Pointer.access(indices_ptr);
984982
elseif splitType == SplitType.TYPE then
985983
// Split the variables by basic type (real, integer, boolean, string)
986984
// and return a list for each type
987-
VariablePointers.map(scalar_vars, function splitByType(real_lst = real_lst, int_lst = int_lst, bool_lst = bool_lst, string_lst = string_lst, enum_lst = enum_lst, indices_ptr = indices_ptr, varType = varType));
985+
VariablePointers.map(sim_vars, function splitByType(real_lst = real_lst, int_lst = int_lst, bool_lst = bool_lst, string_lst = string_lst, enum_lst = enum_lst, indices_ptr = indices_ptr, varType = varType));
988986
simVars := {listReverse(Pointer.access(real_lst)),
989987
listReverse(Pointer.access(int_lst)),
990988
listReverse(Pointer.access(bool_lst)),
@@ -1009,7 +1007,7 @@ public
10091007
protected
10101008
SimCode.SimCodeIndices simCodeIndices = Pointer.access(indices_ptr);
10111009
algorithm
1012-
() := match (var.ty, varType)
1010+
() := match (Type.arrayElementType(var.ty), varType)
10131011

10141012
case (Type.REAL(), VarType.SIMULATION)
10151013
algorithm
@@ -1189,8 +1187,13 @@ public
11891187
input UnorderedMap<ComponentRef, SimVar> simcode_map;
11901188
output list<SimVar> vars = {};
11911189
algorithm
1192-
vars := list(UnorderedMap.getSafe(BVariable.getVarName(v), simcode_map, sourceInfo()) for v in VariablePointers.scalarizeList({var}));
1190+
if Flags.getConfigBool(Flags.SIM_CODE_SCALARIZE) then
1191+
vars := list(UnorderedMap.getSafe(BVariable.getVarName(v), simcode_map, sourceInfo()) for v in VariablePointers.scalarizeList({var}));
1192+
else
1193+
vars := {UnorderedMap.getSafe(BVariable.getVarName(var), simcode_map, sourceInfo())};
1194+
end if;
11931195
end getVars;
1196+
11941197
end SimVars;
11951198

11961199
constant SimVars emptySimVars = SIMVARS(

OMCompiler/Compiler/SimCode/SimCode.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ uniontype SimCode
161161
Option<DaeModeData> daeModeData;
162162
list<SimEqSystem> inlineEquations;
163163
Option<OMSIData> omsiData "used for OMSI to generate equations code";
164+
Boolean scalarized;
164165
end SIMCODE;
165166
end SimCode;
166167

0 commit comments

Comments
 (0)