Skip to content

Commit beb22ab

Browse files
authored
[NB] update for equation handling (#12435)
- add the support of lists as iterator domains - ToDo: handling for events in for loops with list domains
1 parent 3c3452b commit beb22ab

File tree

9 files changed

+150
-39
lines changed

9 files changed

+150
-39
lines changed

OMCompiler/Compiler/BackEnd/BackendDAE.mo

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,12 +666,17 @@ uniontype ZeroCrossing
666666
end ZeroCrossing;
667667

668668
public uniontype SimIterator
669-
record SIM_ITERATOR
669+
record SIM_ITERATOR_RANGE
670670
.DAE.ComponentRef name;
671671
Integer start;
672672
Integer step;
673673
Integer size;
674-
end SIM_ITERATOR;
674+
end SIM_ITERATOR_RANGE;
675+
record SIM_ITERATOR_LIST
676+
.DAE.ComponentRef name;
677+
list<Integer> lst;
678+
Integer size;
679+
end SIM_ITERATOR_LIST;
675680
end SimIterator;
676681

677682
public

OMCompiler/Compiler/BackEnd/BackendDump.mo

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,10 @@ public function simIteratorString
18191819
input BackendDAE.SimIterator iter;
18201820
output String str;
18211821
algorithm
1822-
str := ComponentReference.printComponentRefStr(iter.name) + " in " + intString(iter.start) + ":" + intString(iter.step) + ":" + intString(iter.start + iter.size);
1822+
str := match iter
1823+
case BackendDAE.SIM_ITERATOR_RANGE() then ComponentReference.printComponentRefStr(iter.name) + " in " + intString(iter.start) + ":" + intString(iter.step) + ":" + intString(iter.start + iter.size);
1824+
case BackendDAE.SIM_ITERATOR_LIST() then ComponentReference.printComponentRefStr(iter.name) + " in " + List.toString(iter.lst, intString, "", "{", ", ", "}", true, 10);
1825+
end match;
18231826
end simIteratorString;
18241827

18251828
// =============================================================================

OMCompiler/Compiler/NBackEnd/Util/NBSlice.mo

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,8 @@ protected
14231423
Expression range;
14241424
Integer start, step, stop;
14251425
list<tuple<Integer, Integer>> ranges;
1426+
list<Expression> iterator_exps;
1427+
list<Integer> iterator_lst;
14261428

14271429
// only occurs for non-for-loop equations (no frames to replace)
14281430
case {} algorithm
@@ -1431,9 +1433,22 @@ protected
14311433

14321434
// extract numeric information about the range
14331435
case (iterator, range) :: rest algorithm
1434-
(start, step, stop) := Expression.getIntegerRange(range);
1436+
iterator_lst := match range
1437+
case Expression.RANGE() algorithm
1438+
(start, step, stop) := Expression.getIntegerRange(range);
1439+
then List.intRange3(start,step, stop);
1440+
case Expression.ARRAY() algorithm
1441+
iterator_exps := list(Expression.map(e, function Replacements.applySimpleExp(replacements = replacements)) for e in range.elements);
1442+
iterator_lst := list(Expression.integerValue(SimplifyExp.simplifyDump(e, true, getInstanceName())) for e in iterator_exps);
1443+
then iterator_lst;
1444+
else algorithm
1445+
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because iterator binding could not be parsed: "
1446+
+ ComponentRef.toString(iterator) + " in " + Expression.toString(range)});
1447+
then fail();
1448+
end match;
1449+
14351450
// traverse every index in the range
1436-
for index in start:step:stop loop
1451+
for index in iterator_lst loop
14371452
UnorderedMap.add(iterator, Expression.INTEGER(index), replacements);
14381453
if listEmpty(rest) then
14391454
// bottom line, resolve current configuration and create index for it

OMCompiler/Compiler/NSimCode/NSimGenericCall.mo

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,27 @@ public
152152
end convert;
153153

154154
uniontype SimIterator
155-
record SIM_ITERATOR
155+
record SIM_ITERATOR_RANGE
156156
ComponentRef name;
157157
Integer start;
158158
Integer step;
159159
Integer size;
160-
end SIM_ITERATOR;
160+
end SIM_ITERATOR_RANGE;
161+
162+
record SIM_ITERATOR_LIST
163+
ComponentRef name;
164+
list<Integer> lst;
165+
Integer size;
166+
end SIM_ITERATOR_LIST;
161167

162168
function toString
163169
input SimIterator iter;
164-
output String str = "{" + ComponentRef.toString(iter.name) + " | start:" + intString(iter.start) + ", step:" + intString(iter.step) + ", size: " + intString(iter.size) + "}";
170+
output String str;
171+
algorithm
172+
str := match iter
173+
case SIM_ITERATOR_RANGE() then "{" + ComponentRef.toString(iter.name) + " | start:" + intString(iter.start) + ", step:" + intString(iter.step) + ", size: " + intString(iter.size) + "}";
174+
case SIM_ITERATOR_LIST() then "{" + ComponentRef.toString(iter.name) + " | list: " + List.toString(iter.lst, intString, "", "{", ", ", "}", true, 10) + "}";
175+
end match;
165176
end toString;
166177

167178
function fromIterator
@@ -173,23 +184,37 @@ public
173184
ComponentRef name;
174185
Expression range;
175186
Integer start, step, stop;
187+
list<Integer> lst;
176188
algorithm
177189
(names, ranges) := Iterator.getFrames(iter);
178190
for tpl in listReverse(List.zip(names, ranges)) loop
179191
(name, range) := tpl;
180-
(start, step, stop) := match range
181-
case Expression.RANGE() then (Expression.integerValue(range.start), Expression.integerValue(Util.getOptionOrDefault(range.step, Expression.INTEGER(1))), Expression.integerValue(range.stop));
192+
sim_iter := match range
193+
case Expression.RANGE() algorithm
194+
start := Expression.integerValue(range.start);
195+
step := Expression.integerValue(Util.getOptionOrDefault(range.step, Expression.INTEGER(1)));
196+
stop := Expression.integerValue(range.stop);
197+
then SIM_ITERATOR_RANGE(name, start, step, intDiv(stop-start,step)+1) :: sim_iter;
198+
199+
case Expression.ARRAY() guard(range.literal) algorithm
200+
lst := list(Expression.integerValue(e) for e in range.elements);
201+
then SIM_ITERATOR_LIST(name, lst, listLength(lst)) :: sim_iter;
202+
182203
else algorithm
183-
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for incorrect range: " + Expression.toString(range)});
204+
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for incorrect iterator domain: " + Expression.toString(range)});
184205
then fail();
185206
end match;
186-
sim_iter := SIM_ITERATOR(name, start, step, intDiv(stop-start,step)+1) :: sim_iter;
187207
end for;
188208
end fromIterator;
189209

190210
function convert
191211
input SimIterator iter;
192-
output OldBackendDAE.SimIterator old_iter = OldBackendDAE.SIM_ITERATOR(ComponentRef.toDAE(iter.name), iter.start, iter.step, iter.size);
212+
output OldBackendDAE.SimIterator old_iter;
213+
algorithm
214+
old_iter := match iter
215+
case SIM_ITERATOR_RANGE() then OldBackendDAE.SIM_ITERATOR_RANGE(ComponentRef.toDAE(iter.name), iter.start, iter.step, iter.size);
216+
case SIM_ITERATOR_LIST() then OldBackendDAE.SIM_ITERATOR_LIST(ComponentRef.toDAE(iter.name), iter.lst, iter.size);
217+
end match;
193218
end convert;
194219
end SimIterator;
195220

OMCompiler/Compiler/SimCode/SimCodeUtil.mo

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15864,9 +15864,12 @@ end getCMakeVersion;
1586415864
function getSimIteratorSize
1586515865
input list<BackendDAE.SimIterator> iters;
1586615866
output Integer size = 1;
15867+
protected
15868+
Integer local_size;
1586715869
algorithm
1586815870
for iter in iters loop
15869-
size := size * iter.size;
15871+
local_size := match iter case BackendDAE.SIM_ITERATOR_RANGE() then iter.size; case BackendDAE.SIM_ITERATOR_LIST() then iter.size; end match;
15872+
size := size * local_size;
1587015873
end for;
1587115874
end getSimIteratorSize;
1587215875

OMCompiler/Compiler/Template/CodegenC.tpl

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4952,7 +4952,7 @@ template zeroCrossingTpl(Integer index1, Exp relation, Option<list<SimIterator>>
49524952
let &preExp = buffer ""
49534953
let &sub = buffer ""
49544954
let forHead = match iter
4955-
case SOME(iter_) then (iter_ |> it as SIM_ITERATOR(__) =>
4955+
case SOME(iter_) then (iter_ |> it =>
49564956
forIterator(it, contextZeroCross, &preExp, &varDecls, &auxFunction, &sub)
49574957
;separator="\n";empty)
49584958
else ""
@@ -4963,7 +4963,7 @@ template zeroCrossingTpl(Integer index1, Exp relation, Option<list<SimIterator>>
49634963
else ""
49644964
let tmp_ = match iter case SOME(iter_) then "+tmp" else ""
49654965
let forTail = match iter
4966-
case SOME(iter_) then (iter_ |> it as SIM_ITERATOR(__) => "}";separator="\n";empty)
4966+
case SOME(iter_) then (iter_ |> it => "}";separator="\n";empty)
49674967
else ""
49684968
match relation
49694969
case exp as RELATION(__) then
@@ -5124,7 +5124,7 @@ template relationTpl(Integer index1, Exp relation, Option<list<SimIterator>> ite
51245124
let &preExp = buffer ""
51255125
let &sub = buffer ""
51265126
let forHead = match iter
5127-
case SOME(iter_) then (iter_ |> it as SIM_ITERATOR(__) =>
5127+
case SOME(iter_) then (iter_ |> it =>
51285128
forIterator(it, contextZeroCross, &preExp, &varDecls, &auxFunction, &sub)
51295129
;separator="\n";empty)
51305130
else ""
@@ -5135,7 +5135,7 @@ let &preExp = buffer ""
51355135
else ""
51365136
let tmp_ = match iter case SOME(iter_) then "+tmp" else ""
51375137
let forTail = match iter
5138-
case SOME(iter_) then (iter_ |> it as SIM_ITERATOR(__) => "}";separator="\n";empty)
5138+
case SOME(iter_) then (iter_ |> it => "}";separator="\n";empty)
51395139
else ""
51405140
match relation
51415141
case exp as RELATION(__) then
@@ -7438,33 +7438,53 @@ end genericBranch;
74387438
74397439
template genericIterator(SimIterator iter, Context context, Text &preExp, Text &varDecls, Text &auxFunction, Text &sub)
74407440
::= match iter
7441-
case SIM_ITERATOR() then
7442-
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7443-
<<
7444-
int <%iter_%>_loc = tmp % <%size%>;
7445-
int <%iter_%> = <%step%> * <%iter_%>_loc + <%start%>;
7446-
tmp /= <%size%>;
7447-
>>
7441+
case SIM_ITERATOR_RANGE() then
7442+
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7443+
<<
7444+
int <%iter_%>_loc = tmp % <%size%>;
7445+
int <%iter_%> = <%step%> * <%iter_%>_loc + <%start%>;
7446+
tmp /= <%size%>;
7447+
>>
7448+
case SIM_ITERATOR_LIST() then
7449+
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7450+
let arr = (lst |> elem => '<%elem%>'; separator=", ")
7451+
<<
7452+
static const int <%iter_%>_lst[<%size%>] = {<%arr%>};
7453+
int <%iter_%>_loc = tmp % <%size%>;
7454+
int <%iter_%> = <%iter_%>_lst[<%iter_%>_loc];
7455+
tmp /= <%size%>;
7456+
>>
74487457
end genericIterator;
74497458
74507459
template forIterator(SimIterator iter, Context context, Text &preExp, Text &varDecls, Text &auxFunction, Text &sub)
74517460
::= match iter
7452-
case SIM_ITERATOR() then
7453-
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7454-
let rel = if intGt(step, 0) then "<" else ">"
7455-
let sign = if intGt(step, 0) then "+" else "-"
7456-
<<
7457-
for(int <%iter_%>=<%start%>; <%iter_%><%rel%><%start%><%sign%><%size%>; <%iter_%>+=<%step%>){
7458-
>>
7461+
case SIM_ITERATOR_RANGE() then
7462+
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7463+
let rel = if intGt(step, 0) then "<" else ">"
7464+
let sign = if intGt(step, 0) then "+" else "-"
7465+
<<
7466+
for(int <%iter_%>=<%start%>; <%iter_%><%rel%><%start%><%sign%><%size%>; <%iter_%>+=<%step%>){
7467+
>>
7468+
case SIM_ITERATOR_LIST() then
7469+
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7470+
<<
7471+
for(int <%iter_%>_=0; <%iter_%>_<<%size%>; <%iter_%>_++){
7472+
<%iter_%> = <%iter_%>_lst[<%iter_%>_];
7473+
>>
74597474
end forIterator;
74607475
74617476
template forIteratorBody(SimIterator iter, Context context, Text &preExp, Text &varDecls, Text &auxFunction, Text &sub)
74627477
::= match iter
7463-
case SIM_ITERATOR() then
7464-
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7465-
<<
7466-
(<%iter_%>-<%start%>)/<%step%>+<%size%>*(
7467-
>>
7478+
case SIM_ITERATOR_RANGE() then
7479+
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7480+
<<
7481+
(<%iter_%>-<%start%>)/<%step%>+<%size%>*(
7482+
>>
7483+
case SIM_ITERATOR_LIST() then
7484+
let iter_ = contextCref(name, contextOther, &preExp, &varDecls, &auxFunction, &sub)
7485+
<<
7486+
<%iter_%>_+<%size%>*(
7487+
>>
74687488
end forIteratorBody;
74697489
74707490
template genericCallHeaders(list<SimGenericCall> genericCalls, Context context)

OMCompiler/Compiler/Template/SimCodeTV.mo

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,12 +1654,17 @@ package BackendDAE
16541654
end ZeroCrossing;
16551655

16561656
uniontype SimIterator
1657-
record SIM_ITERATOR
1657+
record SIM_ITERATOR_RANGE
16581658
DAE.ComponentRef name;
16591659
Integer start;
16601660
Integer step;
16611661
Integer size;
1662-
end SIM_ITERATOR;
1662+
end SIM_ITERATOR_RANGE;
1663+
record SIM_ITERATOR_LIST
1664+
DAE.ComponentRef name;
1665+
list<Integer> lst;
1666+
Integer size;
1667+
end SIM_ITERATOR_LIST;
16631668
end SimIterator;
16641669

16651670
uniontype TimeEvent

testsuite/simulation/modelica/NBackend/array_handling/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ diagonal_slice_for.mos\
88
exemplary.mos\
99
simple_der_for.mos\
1010
for_exp.mos\
11+
for_list.mos\
1112

1213
# test that currently fail. Move up when fixed.
1314
# Run make failingtest
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// name: for_list
2+
// keywords: NewBackend
3+
// status: correct
4+
5+
loadString("
6+
model for_list
7+
Real[7] x;
8+
equation
9+
for i in {1,3,7} loop
10+
x[i] = time + i;
11+
end for;
12+
for i in {2,4,5,6} loop
13+
x[i] = time * i;
14+
end for;
15+
end for_list;
16+
"); getErrorString();
17+
18+
setCommandLineOptions("--newBackend");
19+
20+
simulate(for_list); getErrorString();
21+
22+
// Result:
23+
// true
24+
// ""
25+
// true
26+
// record SimulationResult
27+
// resultFile = "for_list_res.mat",
28+
// simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 1e-6, method = 'dassl', fileNamePrefix = 'for_list', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
29+
// messages = "LOG_SUCCESS | info | The initialization finished successfully without homotopy method.
30+
// LOG_SUCCESS | info | The simulation finished successfully.
31+
// "
32+
// end SimulationResult;
33+
// ""
34+
// endResult

0 commit comments

Comments
 (0)