Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 81.5% 101 / 0 / 124
Functions: -% 0 / 1 / 1
Branches: 60.0% 30 / 0 / 50

OMCompiler/Compiler/NFFrontEnd/NFSBGraphUtil.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package NFSBGraphUtil
37
38 protected
39 import SBGraph.VertexDescriptor;
40 import SBGraph.IncidenceList;
41 import Array;
42 import Ceval = NFCeval;
43 import Dimension = NFDimension;
44 import MetaModelica.Dangerous.*;
45 import Error;
46 import Expression = NFExpression;
47 import Operator = NFOperator;
48 import Op = NFOperator.Op;
49 import SBInterval;
50 import SBLinearMap;
51 import SBMultiInterval;
52 import SBPWLinearMap;
53 import SBSet;
54 import SimplifyExp = NFSimplifyExp;
55 import Subscript = NFSubscript;
56 import System;
57 import Vector;
58
59 public
60 function multiIntervalFromDimensions
61 input list<Dimension> dims;
62 input Vector<Integer> vCount;
63 output SBMultiInterval multiInt;
64 protected
65 Vector<Integer> new_vCount;
66 Integer vc, dim_size, index;
67 array<SBInterval> ints;
68 SBInterval int;
69 algorithm
70
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 10 times.
23 if listEmpty(dims) then
71 13 vc := Vector.get(vCount, 1);
72 13 Vector.update(vCount, 1, vc + 1);
73
74 13 multiInt := SBMultiInterval.fromArray(arrayCreate(Vector.size(vCount), SBInterval.new(vc, 1, vc)));
75 else
76 10 ints := arrayCreate(Vector.size(vCount), SBInterval.newEmpty());
77 10 new_vCount := Vector.copy(vCount);
78 index := 1;
79
80
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 for dim in dims loop
81
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if not Dimension.isKnown(dim) then
82 ✗ Error.terminate(getInstanceName() + ": unknown dimension " + Dimension.toString(dim),
83 sourceInfo());
84 end if;
85
86 10 dim_size := Dimension.size(dim);
87 10 vc := Vector.get(vCount, index);
88 10 int := SBInterval.new(vc, 1, vc + dim_size - 1);
89
90
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if SBInterval.isEmpty(int) then
91 ✗ ints := listArray({});
92 ✗ break;
93 else
94 10 ints[index] := int;
95 10 Vector.update(new_vCount, index, vc + dim_size);
96 end if;
97
98 10 index := index + 1;
99 end for;
100
101
2/2
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 9 times.
11 for i in listLength(dims)+1:Vector.size(vCount) loop
102 1 vc := Vector.get(vCount, 1);
103 1 ints[i] := SBInterval.new(vc, 1, vc);
104 end for;
105
106 10 multiInt := SBMultiInterval.fromArray(ints);
107
108
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if not SBMultiInterval.isEmpty(multiInt) then
109 10 Vector.swap(new_vCount, vCount);
110 end if;
111 end if;
112 end multiIntervalFromDimensions;
113
114 function multiIntervalFromSubscripts
115 input list<Subscript> subs;
116 input Vector<Integer> vCount;
117 input output SBMultiInterval multiInt;
118 protected
119 array<SBInterval> mi, miv;
120 SBInterval int;
121 Integer index, aux_lo;
122 Expression sub_exp;
123 algorithm
124 30 miv := SBMultiInterval.intervals(multiInt);
125
126
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 16 times.
30 if listEmpty(subs) then
127 14 mi := Array.map(miv, make_lo_interval);
128 else
129 index := 1;
130 16 mi := arrayCopy(miv);
131
132
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 for s in subs loop
133 16 sub_exp := evalCrefs(Subscript.toExp(s));
134 16 int := intervalFromExp(sub_exp);
135 16 aux_lo := SBInterval.lowerBound(miv[index]) - 1;
136 16 int := SBInterval.new(aux_lo + SBInterval.lowerBound(int),
137 SBInterval.stepValue(int),
138 aux_lo + SBInterval.upperBound(int));
139
140
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 if not SBInterval.isEmpty(int) then
141 16 mi[index] := int;
142 else
143 ✗ mi := listArray({});
144 ✗ break;
145 end if;
146
147 16 index := index + 1;
148 end for;
149
150
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 13 times.
35 for i in listLength(subs)+1:arrayLength(mi) loop
151 3 aux_lo := SBInterval.lowerBound(miv[i]);
152 3 mi[index] := SBInterval.new(aux_lo, 1, aux_lo);
153 end for;
154 end if;
155
156 30 multiInt := SBMultiInterval.fromArray(mi);
157 end multiIntervalFromSubscripts;
158
159 function make_lo_interval
160 input SBInterval i;
161 output SBInterval res;
162 protected
163 Integer lo = SBInterval.lowerBound(i);
164 algorithm
165 15 res := SBInterval.new(lo, 1, lo);
166 end make_lo_interval;
167
168 function evalCrefs
169 input output Expression e;
170 protected
171 function evalCref
172 input Expression e;
173 output Expression outExp;
174 algorithm
175
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 if Expression.isCref(e) then
176 ✗ outExp := Ceval.evalExp(e, Ceval.EvalTarget.new(Absyn.dummyInfo, NFInstContext.ITERATION_RANGE));
177 else
178 outExp := e;
179 end if;
180 end evalCref;
181 algorithm
182 16 e := Expression.map(e, evalCref);
183 end evalCrefs;
184
185 function intervalFromExp
186 input Expression e;
187 output SBInterval i;
188 algorithm
189 i := match e
190 6 case Expression.INTEGER() then SBInterval.new(e.value, 1, e.value);
191 ✗ case Expression.BOOLEAN() then SBInterval.new(Util.boolInt(e.value), 1, Util.boolInt(e.value));
192 ✗ case Expression.REAL() then SBInterval.new(realInt(e.value), 1, realInt(e.value));
193 3 case Expression.BINARY() then intervalFromBinaryExp(e.exp1, e.operator, e.exp2);
194 ✗ case Expression.UNARY() then intervalFromUnaryExp(e.exp);
195 13 case Expression.RANGE() then intervalFromRange(e);
196 else
197 algorithm
198 ✗ Error.terminate(getInstanceName() + " got unknown expression " +
199 Expression.toString(e), sourceInfo());
200 ✗ then
201 fail();
202 end match;
203 end intervalFromExp;
204
205 function intervalFromBinaryExp
206 input Expression lhs;
207 input Operator op;
208 input Expression rhs;
209 output SBInterval i;
210 protected
211 SBInterval lhs_i, rhs_i;
212 Integer lhs_sz, rhs_sz, res;
213 Integer llo, rlo, lhi, rhi, step;
214 algorithm
215 3 lhs_i := intervalFromExp(lhs);
216 3 rhs_i := intervalFromExp(rhs);
217
218 3 lhs_sz := SBInterval.size(lhs_i);
219 3 rhs_sz := SBInterval.size(rhs_i);
220
221 3 llo := SBInterval.lowerBound(lhs_i);
222 3 rlo := SBInterval.lowerBound(rhs_i);
223
224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if lhs_sz == 1 and rhs_sz == 1 then
225 ✗ Expression.INTEGER(value = res) :=
226 Ceval.evalBinaryOp_dispatch(Expression.INTEGER(llo), op, Expression.INTEGER(rlo));
227 ✗ i := SBInterval.new(res, 1, res);
228 elseif lhs_sz == 1 or rhs_sz == 1 then
229 3 lhi := SBInterval.upperBound(lhs_i);
230 3 rhi := SBInterval.upperBound(rhs_i);
231
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 step := SBInterval.stepValue(if lhs_sz == 1 then rhs_i else lhs_i);
232
233 i := match op.op
234 3 case Op.ADD then SBInterval.new(llo + rlo, step, lhi + rhi);
235 ✗ case Op.SUB then SBInterval.new(llo - rlo, step, lhi - rhi);
236 ✗ case Op.MUL then SBInterval.new(llo * rlo, llo * step, lhi * rhi);
237 else
238 algorithm
239 ✗ Error.terminate(getInstanceName() +
240 " got unknown operator " + Operator.symbol(op), sourceInfo());
241 ✗ then
242 fail();
243 end match;
244 else
245 ✗ Error.terminate(getInstanceName() + " got unknown expression " +
246 Expression.toString(Expression.BINARY(lhs, op, rhs)) + "\n", sourceInfo());
247 end if;
248 end intervalFromBinaryExp;
249
250 function intervalFromUnaryExp
251 input Expression e;
252 output SBInterval i;
253 algorithm
254 ✗ i := intervalFromExp(e);
255 ✗ i := SBInterval.new(-SBInterval.lowerBound(i), 1, -SBInterval.upperBound(i));
256 end intervalFromUnaryExp;
257
258 function intervalFromRange
259 input Expression e;
260 output SBInterval i;
261 protected
262 Expression start, stop;
263 Option<Expression> ostep;
264 Integer lo, step, hi;
265 algorithm
266
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 Expression.RANGE(start = start, step = ostep, stop = stop) := SimplifyExp.simplify(e);
267 13 lo := Expression.toInteger(start);
268 13 hi := Expression.toInteger(stop);
269
270
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 if isSome(ostep) then
271 ✗ step := Expression.toInteger(Util.getOption(ostep));
272 else
273 step := 1;
274 end if;
275
276 13 i := SBInterval.new(lo, step, hi);
277 end intervalFromRange;
278
279 function linearMapFromIntervals
280 input VertexDescriptor d1;
281 input VertexDescriptor d2;
282 input SBMultiInterval mi1;
283 input SBMultiInterval mi2;
284 input Vector<Integer> eCount;
285 output String name;
286 output SBPWLinearMap pw1;
287 output SBPWLinearMap pw2;
288 protected
289 array<SBInterval> ints1, ints2, mi;
290 Integer mi1_sz, mi2_sz, sz, sz1, sz2;
291 Integer count, aux_ec;
292 array<Real> g1, g2, o1, o2;
293 Real g1i, g2i, o1i, o2i;
294 SBInterval i1, i2;
295 Vector<Integer> new_ec;
296 SBSet s;
297 SBLinearMap lm1, lm2;
298 algorithm
299 15 ints1 := SBMultiInterval.intervals(mi1);
300 15 mi1_sz := SBMultiInterval.size(mi1);
301
302 15 ints2 := SBMultiInterval.intervals(mi2);
303 15 mi2_sz := SBMultiInterval.size(mi2);
304
305
1/4
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15 if SBMultiInterval.ndim(mi1) <> SBMultiInterval.ndim(mi2) and
306 mi1_sz <> 1 and mi2_sz <> 1 then
307 ✗ Error.terminate(getInstanceName() + " got incompatible connect", sourceInfo());
308 end if;
309
310 sz := arrayLength(ints1);
311 15 g1 := arrayCreateNoInit(sz, 0.0);
312 15 g2 := arrayCreateNoInit(sz, 0.0);
313 15 o1 := arrayCreateNoInit(sz, 0.0);
314 15 o2 := arrayCreateNoInit(sz, 0.0);
315 15 mi := arrayCreateNoInit(sz, ints1[1]);
316 15 new_ec := Vector.new<Integer>();
317
318
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
32 for i in 1:sz loop
319 17 sz1 := SBInterval.size(ints1[i]);
320 17 sz2 := SBInterval.size(ints2[i]);
321
322
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 if sz1 <> sz2 and sz1 <> 1 and sz2 <> 1 then
323 ✗ Error.terminate(getInstanceName() + " got incompatible connect", sourceInfo());
324 end if;
325
326 count := max(sz1, sz2);
327 17 aux_ec := Vector.get(eCount, i);
328 17 mi[i] := SBInterval.new(aux_ec, 1, aux_ec + count - 1);
329
330 17 i1 := ints1[i];
331 17 i2 := ints2[i];
332
333
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 6 times.
17 if sz1 == 1 then
334 11 g1[i] := 0.0;
335 11 o1[i] := SBInterval.lowerBound(i1);
336 else
337 6 g1i := SBInterval.stepValue(i1);
338 6 o1i := -g1i * aux_ec + SBInterval.lowerBound(i1);
339 6 g1[i] := g1i;
340 6 o1[i] := o1i;
341 end if;
342
343
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 7 times.
17 if sz2 == 1 then
344 10 g2[i] := 0.0;
345 10 o2[i] := SBInterval.lowerBound(i2);
346 else
347 7 g2i := SBInterval.stepValue(i2);
348 7 o2i := -g2i * aux_ec + SBInterval.lowerBound(i2);
349 7 g2[i] := g2i;
350 7 o2[i] := o2i;
351 end if;
352
353 17 Vector.push(new_ec, aux_ec + count);
354 end for;
355
356 15 Vector.swap(eCount, new_ec);
357
358 15 s := SBSet.newEmpty();
359 15 s := SBSet.addAtomicSet(SBAtomicSet.new(SBMultiInterval.fromArray(mi)), s);
360
361 15 lm1 := SBLinearMap.new(g1, o1);
362 15 lm2 := SBLinearMap.new(g2, o2);
363
364 15 pw1 := SBPWLinearMap.newScalar(s, lm1);
365 15 pw2 := SBPWLinearMap.newScalar(s, lm2);
366
367 15 name := "E" + String(System.tmpTick());
368 end linearMapFromIntervals;
369
370 annotation(__OpenModelica_Interface="nf_frontend");
371 end NFSBGraphUtil;
372