Opened 5 years ago

Closed 3 years ago

#5643 closed defect (fixed)

Connect-equations in for loop are ignored when using -d=nonfScalarize

Reported by: casella Owned by: perost
Priority: critical Milestone: 1.17.0
Component: New Instantiation Version:
Keywords: Cc: federico.terraneo@…, stefano.cherubin@…, massimo.fioravanti@…, rfranke

Description

We are working on a project whereby we need to start from the unscalarized output of the NF flattening to compile Modelica models efficiently. The easiest option seems to be getting the flat Modelica output, parsing it, and starting from there. Unfortunately, there are still some quirks concerning connect-equations in the flat Modelica dump when it is called before the scalarization step.

The attached package contains some simple test cases. The flat, non-scalarized models of the PlainEquations package seem to be ok. Unfortunately, some models in ConnectEquations reveal that connect-equations in for loops are ignored by the flattening process.

For example, ConnectEquations.C is flattened as

class TestArray.ConnectEquations.C "A model using arrays of simple models without arrays"
  final parameter Integer N = 3;
  parameter Real[3] p = {1.0, 1.5, 2.0};
  Real[3] a.x;
  parameter Real[3] a.p = p;
  Real[3] a.c.f;
  Real[3] a.c.e;
  parameter Real s.p = 20.0;
  Real s.c.e;
  Real s.c.f;
equation
  a.c.f = 0.0;
  s.c.e = a[1].c.e;
  s.c.f + a[1].c.f = 0.0;
  for $i in 1:3 loop
    der(a[$i].x) = (-a[$i].p * a[$i].x) + 1.0;
  end for;
  a.c.f = a.x;
  s.c.e = s.p;
  for i in 1:3 - 1 loop
  end for;
end TestArray.ConnectEquations.C;

It is apparent how the effects of connect-equations in the for-loop of model C are missing.

The same happens in ConnectEquations.D

Attachments (1)

TestArray.mo (3.1 KB) - added by casella 5 years ago.

Download all attachments as: .zip

Change History (10)

Changed 5 years ago by casella

comment:1 follow-up: Changed 5 years ago by casella

After discussing the topic in todays devmeeting, I understand the plan is to always unroll and scalarize connect equations, because in general handling connection sets involving arrays and iterators would be too complicated.

I agree with the idea in general, since I expect these equations to be a tiny fraction of the total even in large scale models.

However, in most cases, I expect the connect equations to end up in something like this:

a.p[1].v = a.n[2].v;
a.p[2].v = a.n[3].v;
a.p[3].v = a.n[4].v;
a.p[1].i + a.p[2].i = 0;
a.p[2].i + a.p[3].i = 0;
a.p[3].i + a.p[4].i = 0;

which could be later reconstructed as

for i in 1:3 loop
  a.p[i].v = a.p[i+1].e;
  a.p[i].i + a.n[i+1].i = 0;
end for;

leaving aside an even smaller set of "intractable" connection sets, typically featuring more than two ports. This would be beneficial to speed up the structural analysis and to reduce the generated code size.

I wonder whether this belongs more to the frontend or to the backend, what do you think?

comment:2 in reply to: ↑ 1 Changed 5 years ago by perost

Replying to casella:

I wonder whether this belongs more to the frontend or to the backend, what do you think?

It would probably be most efficient to do it in the frontend, since we could then do the analysis on only the equations generated by the connection handling instead of on the whole model. It will probably be very expensive to do such an analysis, so we probably want to keep the number of equations involved as small as possible.

comment:3 follow-up: Changed 5 years ago by sjoelund.se

Why would you want to reconstruct that for loop? The only thing I could think of to make things more efficiently would be so add the alias variables in the frontend.
Code size would not be affected.

comment:4 in reply to: ↑ 3 Changed 5 years ago by casella

Replying to sjoelund.se:

Why would you want to reconstruct that for loop? The only thing I could think of to make things more efficiently would be so add the alias variables in the frontend.

Yes. When we dealt with the 0.5M equation grid model, alias elimination was a big deal, in fact we had to use an experimental module --removeSimpleEquations = new that unfortunately had some bugs, otherwise the slowdown was significant. I guess array-based alias elimination could be a lot more efficient for large arrays.

In the benchmark model we are presenting at EOOLT 19 there are connect statements inside a triple nested for loop (because of a 3D structure), which can generate as many as 100x100x100 = 1M connect statements. Collapsing the expanded equations back into a 3-fold for loop will be much better than having 2M scalar alias equations to analyze.

Code size would not be affected.

You're right, if alias elimination is performed there should be no increase in code size.

comment:5 Changed 5 years ago by perost

  • Cc rfranke added

Fixed in #476, but it still doesn't work.

Connects in for-loops works correctly now, but regular connectors are not scalarized. This leads to e.g. a.c.f = 0; in the given model, since a.c.f is added to the connection sets instead of a[1].c.f, a[2].c.f and a[3].c.f. This is as far as I know intentional, but it doesn't work if you have connector references with subscripts of course.

comment:6 Changed 5 years ago by casella

Meeting with @rfranke is probably needed to go further

comment:7 Changed 5 years ago by casella

  • Milestone changed from 1.14.0 to 1.16.0

Releasing 1.14.0 which is stable and has many improvements w.r.t. 1.13.2. This issue is rescheduled to 1.16.0

comment:8 Changed 3 years ago by casella

  • Milestone changed from 1.16.0 to 1.17.0

Retargeted to 1.17.0 after 1.16.0 release

comment:9 Changed 3 years ago by casella

  • Resolution set to fixed
  • Status changed from new to closed

PR 6848 and PR 6863 introduced this feature, that must be activated with -d=nonfScalarize,arrayConnect.

-d=newInst is no longer necessary from 1.17.0.

Note: See TracTickets for help on using tickets.