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 Martin Sjölund, 11 years ago

What is failing in this example for code generation? The seg.fault at runtime?

comment:2 by Lennart Ochel, 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 Lennart Ochel, 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 Lennart Ochel, 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:5 by Martin Sjölund, 10 years ago

The first model now works, but not foo2.

comment:6 by Mahder Alemseged Gebremedhin, 10 years ago

Resolution: duplicate
Status: newclosed

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

  1. 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.

  1. 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.

  1. 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.

Note: See TracTickets for help on using tickets.