Opened 11 years ago
Closed 10 years ago
#2449 closed defect (duplicate)
code generation fails for algorithm
Reported by: | Lennart Ochel | Owned by: | Mahder Alemseged Gebremedhin |
---|---|---|---|
Priority: | blocker | Milestone: | 1.9.1 |
Component: | Code Generation | Version: | trunk |
Keywords: | Cc: |
Description
Code generation Fails for the following algorithm:
model test parameter Integer N = 3; Boolean disTAin[N] = {true,false,true}; Integer remTAin[N]; Integer nremTAin; algorithm nremTAin:=0; for i in 1:N loop if disTAin[i] then nremTAin:=1 + nremTAin; remTAin[nremTAin]:=i; else end if; end for; end test;
Change History (6)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
I have not looked at the generated code in detail, yet. Anyway there are warnings during compilation:
test.c: In function 'eqFunction_6': test.c:193: warning: passing argument 1 of 'integer_array_element_addr' from incompatible pointer type .../OpenModelica/build/include/omc/integer_array.h:148: note: expected 'const struct integer_array_t *' but argument is of type 'modelica_integer *'
Probably the segmentation fault during runtime is related to that. Anyway, I will have a closer look at this at Monday.
comment:3 by , 11 years ago
I guess the segmentation fault is related to the code generation for that algorithm:
gcc output
test_06inz.c: In function ‘eqFunction_4’: test_06inz.c:128:9: warning: passing argument 1 of ‘integer_array_element_addr’ from incompatible pointer type [enabled by default] .../include/omc/integer_array.h:148:26: note: expected ‘const struct integer_array_t *’ but argument is of type ‘modelica_integer *’
valgrind output
==14356== Invalid read of size 8 ==14356== at 0x435B8C: calc_base_index_va (in .../tests/temp/test) ==14356== by 0x40DCFD: integer_array_element_addr (in .../tests/temp/test) ==14356== by 0x40BC1D: eqFunction_4 (test_06inz.c:128) ==14356== by 0x40BC96: functionInitialEquations (test_06inz.c:142) ==14356== by 0x4210C8: symbolic_initialization (in .../tests/temp/test) ==14356== by 0x422D02: initialization (in .../tests/temp/test) ==14356== by 0x41CAC4: initializeModel (in .../tests/temp/test) ==14356== by 0x41DF80: solver_main (in .../tests/temp/test) ==14356== by 0x429E98: callSolver (in .../tests/temp/test) ==14356== by 0x42A48F: startNonInteractiveSimulation(int, char**, DATA*) (in .../tests/temp/test) ==14356== by 0x42CAFA: _main_SimulationRuntime (in .../tests/temp/test) ==14356== by 0x40B600: main (in .../tests/temp/test) ==14356== Address 0x0 is not stack'd, malloc'd or (recently) free'd
corresponding c function
[...] 75| /* 76| equation index: 4 77| type: ALGORITHM 78| 79| nremTAin := 0; 80| for i in 1:3 loop 81| if {true, false, true}[i] then 82| nremTAin := 1 + nremTAin; 83| remTAin[nremTAin] := i; 84| end if; 85| end for; 86| */ 87| void eqFunction_4(DATA *data) 88| { 99| modelica_boolean tmp0; 90| modelica_integer tmp1; 91| modelica_integer tmp2; 92| modelica_integer tmp3; 93| $PnremTAin = (modelica_integer) 0; 94| 95| tmp1 = (modelica_integer) 1; tmp2 = (1); tmp3 = (modelica_integer) 3; 96| if(!tmp2) 97| { 98| FILE_INFO info = omc_dummyFileInfo; 99| omc_assert(info, "assertion range step != 0 failed"); 100| } 101| else if(!(((tmp2 > 0) && (tmp1 > tmp3)) || ((tmp2 < 0) && (tmp1 < tmp3)))) 102| { 103| modelica_integer $Pi; 104| for($Pi = (modelica_integer) 1; in_range_integer($Pi, tmp1, tmp3); $Pi += tmp2) 105| { 106| switch((modelica_integer)$Pi) 107| { /* ASUB */ 108| case 1: { 109| tmp0 = (1); 110| break; 111| } 112| case 2: { 113| tmp0 = (0); 114| break; 115| } 116| case 3: { 117| tmp0 = (1); 118| break; 119| } 120| default: 121| assert(NULL == "index out of bounds"); 122| } 123| 124| if(tmp0) 125| { 126| $PnremTAin = ((modelica_integer) 1 + (modelica_integer)$PnremTAin); 127| 128| (*integer_array_element_addr(&$PremTAin, 1, (modelica_integer)$PnremTAin)) = (modelica_integer)$Pi; 129| } 130| } 131| } 132| } [...]
Everything would work fine if the code of line 128 looks like the following:
*(&$PremTAin+(modelica_integer)$PnremTAin-1) = (modelica_integer)$Pi;
Can someone have a look at this, who is more aware of the code generation for arrays than me?
comment:4 by , 11 years ago
The generated code gets even worse in the case of hierarchical models:
package test block foo input Boolean inb[3]; output Integer out[3]; protected Integer n; algorithm n:=0; for i in 1:3 loop if inb[i] then n:=1 + n; out[n]:=i; else end if; end for; end foo; model foo2 foo foo_(inb = disTAin); Boolean disTAin[3] = {true,false,true}; Integer remTAin[3]; algorithm remTAin:=foo_.out; end foo2; end test;
test.foo2.c: In function 'eqFunction_7': test.foo2.c:193: error: expected expression before 'modelica_integer' test.foo2.c:193: error: expected ';' before '$Pfoo_$Pn$rB' mingw32-make: *** [test.foo2.o] Error 1
Corresponding code:
[...] 193| $Pfoo_$Pout$lB(modelica_integer)$Pfoo_$Pn$rB = (modelica_integer)$Pi; [...]
comment:6 by , 10 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
The first one must have been working for a while now. The big problem is the second one. It has the same issues as #2686. The time has come to deal with it once and for all :).
I am halfway fixing it. It needs a couple of things
- Variables should be sorted properly. This is done. However each list is sorted separately now. This can problematic in cases where, for example, certain array variables are selected as state vars while others are treated as algebraic and/or discrete vars.
What I am thinking is instead of having the SimCode lists with the actual variables (like state vars, algebraic vars ...) we can have one list with all the Real/Integer vars and keep only the indexes of the variables in the different lists. Then use this index to access each kind of var.
- Alias elimination should not be done for array members. Eliminating the whole array is okay but not a subset of elements. We can disable this but it seems to make some models considerably bigger.
So maybe we can eliminate the equations but the variables should still be generated in to the simulation arrays to make sure indexing the array returns the correct element. We can put this off until we finish (1) and make sure things are working.
- We need a modified cref generation in templates. I have this already for simulation cases and functions should not be difficult since not much has changed there. One problem I have there is getting some crefs with subscript lists while the type is not array. This works okay for 1D arrays but more than that we need the dims info to do offsetting.
Some places in the front-end or back-end (I know some here) are creating these kinds of crefs. So I have to fix those as well to have uniform cref generation.
Any ideas?
Anyways I think we can close this ticket as a duplicate.
What is failing in this example for code generation? The seg.fault at runtime?