Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#6067 closed defect (fixed)

Evaluate = true should be applied to entire parameter records

Reported by: casella Owned by: perost
Priority: blocker Milestone: 1.17.0
Component: New Instantiation Version:
Keywords: Cc: enrico.cunietti@…

Description (last modified by casella)

Please consider the following test case

package TestEvaluateParameterRecord
  record R1
    parameter Integer N = 3;
    parameter Real p = 2 annotation(Evaluate = true);
    parameter Real q[N,N] = [0, 0, 1; 0, 1, 0; 1, 0, 0] annotation(Evaluate = true);
  end R1;

  record R2
    parameter Integer N = 3;
    parameter Real p = 2;
    parameter Real q[N,N] = [0, 0, 1; 0, 1, 0; 1, 0, 0];
  end R2;

  model M
    replaceable parameter R1 data1;
    replaceable parameter R2 data2 annotation(Evaluate = true);
    Real x1[data1.N];
    Real x2[data2.N];
    Real z1;
    Real z2;
  equation
    x1 = data1.q*{1, 2, 3};
    x2 = data2.q*{1, 2, 3};
    z1 = data1.p*time;
    z2 = data2.p*time;
  end M;
end TestEvaluateParameterRecord;

When I flatten model M with the NF I get

equation
  x1[1] = 3.0;
  x1[2] = 2.0;
  x1[3] = 1.0;
  x2[1] = data2.q[1,1] + data2.q[1,2] * 2.0 + data2.q[1,3] * 3.0;
  x2[2] = data2.q[2,1] + data2.q[2,2] * 2.0 + data2.q[2,3] * 3.0;
  x2[3] = data2.q[3,1] + data2.q[3,2] * 2.0 + data2.q[3,3] * 3.0;
  z1 = 2.0 * time;
  z2 = data2.p * time;

In the case of R1, the parameters p and q are indeed evaluated, and the corresponding simple formulations are obtained for the equations, where all the zero terms have been removed.

However, setting the annotation explicitly on each component of the record is a bit inconvenient. One would like to set the annotation once and for all for the entire record. According to Section 18.3 of the specification, I understand the effect should be the same. Unfortunately the NF basically ignores the annotation and does not evaluate the parameters in the record.

This feature is needed to run Modelica models written with matrix/tensor formulations, where the matrix parameters are mostly filled in with zeros. In this case, it is absolutely necessary to evaluate the matrix-vector products, as shown in the above example, otherwise the generate code may contain a ludicrous number of useless terms, that should be removed up front since 0*x = 0 no matter what the value of x is.

@perost, could you please fix that ASAP as you return from you vacation? Thanks!

Change History (9)

comment:1 Changed 4 years ago by casella

  • Description modified (diff)

comment:2 Changed 4 years ago by casella

  • Description modified (diff)

comment:3 Changed 4 years ago by casella

  • Description modified (diff)

comment:4 follow-up: Changed 4 years ago by perost

Fixed in 20d8634. It's not perfect though, it will mark the fields in the record instance as structural but not the record instance itself. That's probably not terribly hard to fix, but it doesn't seem necessary in this case and the code to handle this needs refactoring.

comment:5 in reply to: ↑ 4 ; follow-up: Changed 4 years ago by casella

Replying to perost:

It's not perfect though, it will mark the fields in the record instance as structural but not the record instance itself.

Does it make any difference in practice?

comment:6 Changed 4 years ago by casella

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

In any case, the fix looks good to me from a practical standpoint.

comment:7 in reply to: ↑ 5 Changed 4 years ago by perost

Replying to casella:

Replying to perost:

It's not perfect though, it will mark the fields in the record instance as structural but not the record instance itself.

Does it make any difference in practice?

It means that if you have only data2 somewhere, in other words if you refer to the whole instance and not a field in it, the reference might not be evaluated even if it has an Evaluate=true annotation. I haven't seen any cases where that would cause issues in practice though.

comment:8 Changed 4 years ago by casella

Could this be a problem, e.g., if data2 was fed as a record input to a function which wouldn't then be constant-evaluated?

Note: See TracTickets for help on using tickets.