﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
3214	Failure to generate or compile code when functions returning arrays or arrays of arrays are involved	Gustaf Thorslund	Mahder Alemseged Gebremedhin	"This continues the array and array of arrays story from ticket #3212 and #3213, so you may call it matrix revolutions if you like.

In the following code the first two models (RAITest and RAETest) works fine, and if simulated for more than one second they could probably plot a stairway to heaven. The fourth model (AIAITest) does on the other hand create a bit of headache since it generates code that later gives compilation warnings and asserted simulation. For this reason a third model (RAIArrayTest) have been introduced, and it fails a bit earlier when trying to generate code. Unless it's the same bug, this ticket is for AIAITest and new ticket should probably be created for RAIArrayTest.
 
{{{#!mo
package ArrayReturnTest
  constant Integer N = 3;
  type E = enumeration (e1, e2, e3);
  type AI = Real[N];
  type AE = Real[E];
  type AIAI = AI[N];
  type AIAE = AE[N];
  
  function RAI
    input Real x;
    output AI a;
  algorithm
    a := {1, 2, 3} * x;
  end RAI;

  function RAE
    input Real x;
    output AE a;
  algorithm
    a := {1, 2, 3} * x;
  end RAE;

  function NextAIAI
    input AIAI state;
    input Real t;
    output AIAI next;
  algorithm
    for i loop
      next[i] := state[i] + RAI(t)*i;
    end for;
  end NextAIAI;
  
  model RAITest // Works fine
    AI state(start = {0,0,0});
  algorithm
    when sample(0, 0.1) then
      state := state + RAI(time);
    end when;
  end RAITest;

  model RAETest // Works fine
    AE state(start = {0,0,0});
  algorithm
    when sample(0, 0.1) then
      state := state + RAE(time);
    end when;
  end RAETest;

  model RAIArrayTest // Fails during code generation
    AI s[N](each start = 0, each fixed = true);
  algorithm
    when sample(0, 0.1) then
      for i loop
	s[i] := s[i] + RAI(time);
      end for;
    end when;
  end RAIArrayTest;
  
  model AIAITest // Fails when trying to compile generated code
    AIAI state(each start = 0, each fixed = true);
  algorithm
    when sample(0, 0.1) then
      state := NextAIAI(state, time);
    end when;
  end AIAITest;
  
end ArrayReturnTest;
}}}

Here is what happens when trying to compile the code generated by AIAITest:
{{{
gcc   -fPIC -O0 -falign-functions -march=native     -I""/home/gustaf/local/openmodelica/include/omc/c"" -I. -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME  -c -o ArrayReturnTest.AIAITest_functions.o ArrayReturnTest.AIAITest_functions.c
ArrayReturnTest.AIAITest_functions.c: In function ‘omc_ArrayReturnTest_NextAIAI’:
ArrayReturnTest.AIAITest_functions.c:32:165: warning: passing argument 2 of ‘copy_real_array_data’ from incompatible pointer type
       copy_real_array_data(add_alloc_real_array(tmp1, mul_alloc_real_array_scalar(omc_ArrayReturnTest_RAI(threadData, _t), ((modelica_real)(modelica_integer)_i))), &(*real_array_element_addr(&_next, 1, /* modelica_integer */ (modelica_integer)_i)));
                                                                                                                                                                     ^
In file included from /home/gustaf/local/openmodelica/include/omc/c/util/modelica.h:88:0,
                 from ArrayReturnTest.AIAITest_functions.h:4,
                 from ArrayReturnTest.AIAITest_functions.c:1:
/home/gustaf/local/openmodelica/include/omc/c/util/real_array.h:84:13: note: expected ‘struct real_array_t *’ but argument is of type ‘modelica_real *’
 extern void copy_real_array_data(const real_array_t source, real_array_t* dest);
             ^
}}}

When trying to simulate it the following happens:
{{{
$ ./ArrayReturnTest.AIAITest 
base_array.c: array dimensions sizes are NULL!
ArrayReturnTest.AIAITest: util/real_array.c:98: copy_real_array_data: Assertion `base_array_ok(dest)' failed.
Aborted
}}}

Kind of sad to see the main actor die at the end...

Anyhow, as said earlier there is a way to fail earlier, even before entering lethal missions. This is where RAIArrayTest comes in. Trying to generate code for it fails with:

{{{
build$ omc ../ArrayReturnTest.mo -i=ArrayReturnTest.RAIArrayTest -s -d=initialization
function ArrayReturnTest.RAI
  input Real x;
  output Real[3] a;
algorithm
  a := {x, 2.0 * x, 3.0 * x};
end ArrayReturnTest.RAI;

class ArrayReturnTest.RAIArrayTest
  Real s[1,1](start = 0.0, fixed = true);
  Real s[1,2](start = 0.0, fixed = true);
  Real s[1,3](start = 0.0, fixed = true);
  Real s[2,1](start = 0.0, fixed = true);
  Real s[2,2](start = 0.0, fixed = true);
  Real s[2,3](start = 0.0, fixed = true);
  Real s[3,1](start = 0.0, fixed = true);
  Real s[3,2](start = 0.0, fixed = true);
  Real s[3,3](start = 0.0, fixed = true);
algorithm
  when sample(0.0, 0.1) then
    for i in 1:3 loop
      s[i] := {s[i,1], s[i,2], s[i,3]} + ArrayReturnTest.RAI(time);
    end for;
  end when;
end ArrayReturnTest.RAIArrayTest;
Error processing file: ../ArrayReturnTest.mo
Error: Too few equations, under-determined system. The model has 1 equation(s) and 9 variable(s).
Error: Internal error Transformation Module PFPlusExt index Reduction Method Pantelides failed!

# Error encountered! Exiting...
# Please check the error message and the flags.

Execution failed!
}}}

$ omc --version
1.9.2+dev (r25040)
"	defect	closed	high	1.9.4	Backend	trunk	fixed	array, function, algorithm	Per Östlund Lennart Ochel Willi Braun Mahder Alemseged Gebremedhin
