#6067 closed defect (fixed)
Evaluate = true should be applied to entire parameter records
Reported by: | Francesco Casella | Owned by: | Per Östlund |
---|---|---|---|
Priority: | blocker | Milestone: | 1.17.0 |
Component: | New Instantiation | Version: | |
Keywords: | Cc: | enrico.cunietti@… |
Description (last modified by )
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 by , 4 years ago
Description: | modified (diff) |
---|
comment:2 by , 4 years ago
Description: | modified (diff) |
---|
comment:3 by , 4 years ago
Description: | modified (diff) |
---|
follow-up: 5 comment:4 by , 4 years ago
follow-up: 7 comment:5 by , 4 years ago
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 by , 4 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
In any case, the fix looks good to me from a practical standpoint.
comment:7 by , 4 years ago
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 by , 4 years ago
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?
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.