Opened 9 years ago
Last modified 7 years ago
#3526 new defect
Code generation fails for array in records
Reported by: | Lennart Ochel | Owned by: | Lennart Ochel |
---|---|---|---|
Priority: | high | Milestone: | Future |
Component: | Code Generation | Version: | |
Keywords: | record array | Cc: | Mahder Alemseged Gebremedhin, jan.hagemann@… |
Description
Template CodegenUtil.ScalarVariableType failed fort he following model:
model test record R Real r[3]; end R; function f input Real x; output R y; algorithm y.r[1] := 1.0+x; y.r[2] := 2.0+x; y.r[3] := 3.0+x; end f; R x; R y; equation x = y; y = f(time); end test;
Maybe this is also related to the module removeSimpleEquations
, since the model works fine if it get disabled using --removeSimpleEquations=none
.
Change History (10)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
This is a backend problem. The generation fails on a variable named $TMP_test_R4.r. This looks like an automatically generated variable as a result of some processing. The type of the variable is ARRAY. Which is where the problem is. It should be a scalar. I think the subscripts form whatever this variable was based on are ignored somehow.
Since all arrays are expanded in a simulation model there was no rule to handle array types in ScalarVariableType (which btw is only used for the _init.xml) file it seems.
do you know where this $TMP_* var could be coming from? Somewhere in removeSimpleEquations() I will try to find it and see what happened.
comment:3 by , 9 years ago
removeSimpleEquations expands y = f(time)
to test.R({x1.r[1], x1.r[2], x1.r[3]}) = test.f(time)
. That kind of expression is handled wrong in SimCode. Due to missing optimization this is handled as nonlinear system for which the temporary variable is introduced which contains wrong type information (see SimCodeUtil.createTempVars).
Even if the type information would be correct the model will still fail. That can be tested using following model:
model test record R Real r[3]; end R; function f input Real x; output R y; algorithm y.r[1] := 1.0+x; y.r[2] := 2.0+x; y.r[3] := 3.0+x; end f; Real a[3]; equation R({a[1], a[2], a[3]}) = f(time); end test;
comment:4 by , 9 years ago
PR269 should fix the wrong type information. Therewith, both models from above will lead to the same error for the generated c code.
test_02nls.c:87:50: warning: implicit declaration of function '$P$TMP_test_R1$Pr_index' is invalid in C99 [-Wimplicit-function-declaration] real_array_create(&tmp1007, ((modelica_real*)&($P$TMP_test_R1$Pr_index(((modelica_integer) 1)))), 1, 3); ^ test_02nls.c:87:48: error: cannot take the address of an rvalue of type 'int' real_array_create(&tmp1007, ((modelica_real*)&($P$TMP_test_R1$Pr_index(((modelica_integer) 1)))), 1, 3); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test_02nls.c:88:10: error: assigning to 'double' from incompatible type 'real_array_t' (aka 'struct base_array_s') res[0] = sub_alloc_real_array(tmp1006, tmp1007); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test_02nls.c:139:50: warning: implicit declaration of function '$P$TMP_test_R4$Pr_index' is invalid in C99 [-Wimplicit-function-declaration] real_array_create(&tmp1010, ((modelica_real*)&($P$TMP_test_R4$Pr_index(((modelica_integer) 1)))), 1, 3); ^ test_02nls.c:139:48: error: cannot take the address of an rvalue of type 'int' real_array_create(&tmp1010, ((modelica_real*)&($P$TMP_test_R4$Pr_index(((modelica_integer) 1)))), 1, 3); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test_02nls.c:140:10: error: assigning to 'double' from incompatible type 'real_array_t' (aka 'struct base_array_s') res[0] = sub_alloc_real_array(tmp1009, tmp1010); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 warnings and 4 errors generated.
comment:5 by , 9 years ago
PR271 has fixed this.
You can't take the last type and expect it to work :) that's cheating. You have to either expand the array of leave it as it is.
I think the subscripts form whatever this variable was based on are ignored somehow.
I was wrong here. As it turned out the variable is actually an array (it is created for an array). But it was not expanded. More specifically the tmpVars entry was an array. Which was unexpected for the code-generator because it handles scalars only. Everything is expanded at that point.
We have the possibility to actually handle un-expanded versions of residual equations (or with a bitmore changes all simvars). I have expanded residual equations now because I was not sure where the residual array (res*
) passed to the residualFunc*s is allocated. If we make sure that is allocated correctly considering array residual variables everything should work fine. I will check.
That kind of expression is handled wrong in SimCode. Due to missing optimization this is handled as nonlinear system
I am gonna try and fix this. I think I know what the problem is.
Regarding crefs andtypes:
When you want the type of a cref you have to consider the subs as well. If you don't consider the subs you might get an array type for a cref that is actually a scalar because the identType stored is the array type. For example for r[2]
the cref is stored as
DAE.CREF_IDENT(r, DAE.T_ARRAY(DAE.REAL, {3}, tysource), {2}) ^^^^^^^^ ^ ^ base type dims subs
so if you take just the type you get an array.
Also don't take types from the last ident. In most cases this might work but when the we have complex arrays involved (e.g. a.b where a is an array of records) the last type will not give you the correct type even when you have considered its subs. a.b here is actually an array.
Avoid that ComponentReference.crefLastType
function by all means :). It is the reason we have problems with records and arrays. Same for ComponentReference.crefType
I have added a new function ComponentReference.crefTypeFull
which will give you the correct type of a cref. It is not considering WHOLEDIM() subs right now but I will fix it. Use this when you want the type of a cref anywhere.
There is also one more function Expression.crefToExp
which will convert a DAE.ComponentReference to a DAE.Exp with the correct type. Use this one instead of Expression.crefExp
which only considers last subs.
comment:9 by , 8 years ago
Milestone: | 1.11.0 → 1.12.0 |
---|
Milestone moved to 1.12.0 due to 1.11.0 already being released.
comment:10 by , 7 years ago
Milestone: | 1.12.0 → Future |
---|
The milestone of this ticket has been reassigned to "Future".
If you think the issue is still valid and relevant for you, please select milestone 1.13.0 for back-end, code generation and run-time issues, or 2.0.0 for front-end issues.
If you are aware that the problem is no longer present, please select the milestone corresponding to the version of OMC you used to check that, and set the status to "worksforme".
In both cases, a short informative comment would be welcome.
Mahder do you think this should be fixed in the templates or in the back end?