Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#6268 closed defect (fixed)

Array[1,dim] gets changed to Array[dim,1]

Reported by: Andreas Heuermann Owned by: Per Östlund
Priority: high Milestone: NeedsInput
Component: Frontend Version: 1.16.0
Keywords: array, newFrontend Cc: Mahder Alemseged Gebremedhin

Description (last modified by Mahder Alemseged Gebremedhin)

I have a model that calls a built-in function point-wise on a vector input with dimension [1,dim], but the output of that function is of dimension [dim,1].

setCommandLineOptions("-d=newInst,optdaedump");
loadString("
model mwe 
  Real vectorA[1,4];
equation
  vectorA = tanh( {{10,20,30,40}} );
end mwe;
"); getErrorString();
simulate(mwe); getErrorString();

When I dump the equation at the first point in the frontend with optdaedump I'll get

Equations (1, 4)
========================================
1/1 (4): vectorA = {{tanh(10.0)}, {tanh(20.0)}, {tanh(30.0)}, {tanh(40.0)}}   [dynamic |0|0|0|0|]

but I would expect to get the same dimension as the input was, so:

vectorA = {{tanh(10.0), tanh(20.0), tanh(30.0), tanh(40.0)}}

This prevents me from solving related ticket #6266.

@mahge930, @perost Any idea where to look at for this?

By the way, if I use the old frontend it gets flattened out is completely wrong.

Change History (17)

comment:1 by Andreas Heuermann, 4 years ago

Using

model mwe 
  Real vectorA[4];
equation
  vectorA = tanh( {10,20,30,40} );
end mwe;

works (when using the newFrontend) as expected.

comment:2 by Andreas Heuermann, 4 years ago

I guess it is just transposed. When looking at a second test case

model mwe2
  Real vectorA[2,4];
  function testFunc
    input Real x_in;
    output Real x_out;
  algorithm
    x_out := tanh(x_in);
  end testFunc;
equation
  vectorA = testFunc( {{10,20,30,40}, {11,21,31,41}} );
end mwe2;

I get

vectorA = {{mwe2.testFunc(10.0), mwe2.testFunc(11.0)}, {mwe2.testFunc(20.0), mwe2.testFunc(21.0)}, {mwe2.testFunc(30.0), mwe2.testFunc(31.0)}, {mwe2.testFunc(40.0), mwe2.testFunc(41.0)}}

comment:3 by Mahder Alemseged Gebremedhin, 4 years ago

The input to the function is a matrix (1x4). So vectorization of the function call will give you back a matrix (also 1x4).

I think this is the expected behavior. Right?

comment:4 by Mahder Alemseged Gebremedhin, 4 years ago

Ahh nvm. You are getting a 4x1 matrix. I see now. Maybe a listReverse missing somewhere.

Last edited 4 years ago by Mahder Alemseged Gebremedhin (previous) (diff)

comment:5 by Mahder Alemseged Gebremedhin, 4 years ago

Description: modified (diff)

comment:6 by Andreas Heuermann, 4 years ago

Is this done in the frontend or in the lawless wasteland between backend and frontend?

comment:7 by Mahder Alemseged Gebremedhin, 4 years ago

It is in the Frontend.

I think it is this line

https://github.com/OpenModelica/OpenModelica/blob/f6d7f171aa541f7e04d213343ace98b3d27a247d/OMCompiler/Compiler/NFFrontEnd/NFCall.mo#L2299

Can you try adding listReverse(iters) instead of just iters to the TYPED_ARRAY_CONSTRUCTOR construction.

Last edited 4 years ago by Mahder Alemseged Gebremedhin (previous) (diff)

comment:8 by Per Östlund, 4 years ago

The new frontend flattens the model to:

class mwe
  Real vectorA[1,1];
  Real vectorA[1,2];
  Real vectorA[1,3];
  Real vectorA[1,4];
equation
  vectorA = array(tanh({{10.0, 20.0, 30.0, 40.0}}[$i1, $i2]) for $i2 in 1:4, $i1 in 1:1);
end mwe;

The array call would expand to:

// After applying inner iterator
array(
 {
  tan({{10.0, 20.0, 30.0, 40.0}}[$i1, 1]),
  tan({{10.0, 20.0, 30.0, 40.0}}[$i1, 2]),
  tan({{10.0, 20.0, 30.0, 40.0}}[$i1, 2]),
  tan({{10.0, 20.0, 30.0, 40.0}}[$i1, 2])
 } for $i1 in 1:1)

<=>

// After applying outer iterator
{{tan({{10.0, 20.0, 30.0, 40.0}}[1, 1]),
  tan({{10.0, 20.0, 30.0, 40.0}}[1, 2]),
  tan({{10.0, 20.0, 30.0, 40.0}}[1, 2]),
  tan({{10.0, 20.0, 30.0, 40.0}}[1, 2])}}

<=>

// After applying subscripts
{{tan(10.0), tan(20.0), tan(30.0), tan(40.0)}}

So the flat model looks correct to me. Since the new frontend does not expand the expression itself it might be that the issue actually lies in the old frontend, which I assume the backend uses to expand it.

comment:9 by Mahder Alemseged Gebremedhin, 4 years ago

@perost Ya probably. It might also be that the two FrontEnd evaluations expect the iterators in different order because the listReverse kind of fixed this case.

It was just a blind guess until you get here :).

comment:10 by Per Östlund, 4 years ago

Actually, I can't replicate the issue at all now that I actually try. Running the script in the description gives the expected result for me:

Equations (1, 4)
========================================
1/1 (4): vectorA = {{tanh(10.0), tanh(20.0), tanh(30.0), tanh(40.0)}}   [dynamic |0|0|0|0|]

and the model simulates successfully. So I'm not sure what's going on here.

comment:11 by Per Östlund, 4 years ago

Aha, it's the changes AnHeuermann made in #6266 that's causing the issue, that's why it's working for me. But the model in #6266 also works for me without giving any out of bounds error.

comment:12 by Per Östlund, 4 years ago

Or maybe it's not the changes that's causing it, I notice the array was wrong for him before the changes too.

in reply to:  7 comment:13 by Andreas Heuermann, 4 years ago

Replying to mahge930:

It is in the Frontend.

I think it is this line

https://github.com/OpenModelica/OpenModelica/blob/f6d7f171aa541f7e04d213343ace98b3d27a247d/OMCompiler/Compiler/NFFrontEnd/NFCall.mo#L2299

Can you try adding listReverse(iters) instead of just iters to the TYPED_ARRAY_CONSTRUCTOR construction.

That looks very good:

vectorA = testFunc( {{10,20,30,40}, {11,21,31,41}} );
Equations (1, 8)
========================================
1/1 (8): vectorA = {{mwe2.testFunc(10.0), mwe2.testFunc(20.0), mwe2.testFunc(30.0), mwe2.testFunc(40.0)}, {mwe2.testFunc(11.0), mwe2.testFunc(21.0), mwe2.testFunc(31.0), mwe2.testFunc(41.0)}}   [dynamic |0|0|0|0|]

comment:15 by Per Östlund, 4 years ago

That's not the correct solution, it will cause issues with the new frontend since the arrays will be reversed to how they should be.

I now noticed that it doesn't actually work for me, I'd forgotten that I also added the listReverse. So the issue occurs during the lowering in the backend, probably due to calling some old frontend function that handles the array call wrong.

comment:16 by Per Östlund, 4 years ago

Resolution: fixed
Status: newclosed

Fixed in 620b4e42.

comment:17 by Francesco Casella, 4 years ago

Summary: Array[1,dim] get's changed to Array[dim,1]Array[1,dim] gets changed to Array[dim,1]
Note: See TracTickets for help on using tickets.