Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#5143 closed enhancement (duplicate)

Inefficient translation of models with vectorized components

Reported by: Rüdiger Franke Owned by: Per Östlund
Priority: high Milestone: 2.0.0
Component: New Instantiation Version:
Keywords: Cc: Adrian Pop, Willi Braun, Bernhard Bachmann

Description

This issue follows up #5110. It sketches an important use case for arrays: vectorized model components. The following model was created using OMEdit (stripped graphical annotations here):

model Vectorized
  parameter Integer n = 3;
  Modelica.Blocks.Continuous.Integrator integrator1[n];
  Modelica.Blocks.Interfaces.RealInput u[n];
  Modelica.Blocks.Interfaces.RealOutput y[n];
equation
  connect(u, integrator1.u);
  connect(integrator1.y, y);
  annotation(
    uses(Modelica(version = "3.2.2")));
end Vectorized;

omc -d=newInst,-nfScalarize only declares u and y as arrays and rolls out everything else:

class Vectorized
  parameter Integer n = 3;
  parameter Real integrator1[1].k(unit = "1") = 1.0 "Integrator gain";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1[1].initType = Modelica.Blocks.Types.Init.InitialState "Type of initialization (1: no init, 2: steady state, 3,4: initial output)";
  parameter Real integrator1[1].y_start = 0.0 "Initial or guess value of output (= state)";
  Real integrator1[1].u "Connector of Real input signal";
  Real integrator1[1].y(start = integrator1[1].y_start) "Connector of Real output signal";
  parameter Real integrator1[2].k(unit = "1") = 1.0 "Integrator gain";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1[2].initType = Modelica.Blocks.Types.Init.InitialState "Type of initialization (1: no init, 2: steady state, 3,4: initial output)";
  parameter Real integrator1[2].y_start = 0.0 "Initial or guess value of output (= state)";
  Real integrator1[2].u "Connector of Real input signal";
  Real integrator1[2].y(start = integrator1[2].y_start) "Connector of Real output signal";
  parameter Real integrator1[3].k(unit = "1") = 1.0 "Integrator gain";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1[3].initType = Modelica.Blocks.Types.Init.InitialState "Type of initialization (1: no init, 2: steady state, 3,4: initial output)";
  parameter Real integrator1[3].y_start = 0.0 "Initial or guess value of output (= state)";
  Real integrator1[3].u "Connector of Real input signal";
  Real integrator1[3].y(start = integrator1[3].y_start) "Connector of Real output signal";
  input Real[3] u;
  output Real[3] y;
initial equation
  integrator1[3].y = integrator1[3].y_start;
  integrator1[2].y = integrator1[2].y_start;
  integrator1[1].y = integrator1[1].y_start;
equation
  u[1] = integrator1[1].u;
  u[2] = integrator1[2].u;
  u[3] = integrator1[3].u;
  integrator1[1].y = y[1];
  integrator1[2].y = y[2];
  integrator1[3].y = y[3];
  der(integrator1[1].y) = integrator1[1].k * integrator1[1].u;
  der(integrator1[2].y) = integrator1[2].k * integrator1[2].u;
  der(integrator1[3].y) = integrator1[3].k * integrator1[3].u;
end Vectorized;

The desired result should read instead:

class VectorizedDesired
  parameter Integer n = 3;
  parameter Real integrator1.k[n](unit = "1") = 1.0 "Integrator gain";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1.initType[n] = Modelica.Blocks.Types.Init.InitialState, "Type of initialization (1: no init, 2: steady state, 3,4: initial output)";
  parameter Real integrator1.y_start[n] = 0.0 "Initial or guess value of output (= state)";
  Real integrator1.u[n] "Connector of Real input signal";
  Real integrator1.y[n](start = integrator1.y_start) "Connector of Real output signal";
  input Real[3] u;
  output Real[3] y;
initial equation
  integrator1.y = integrator1.y_start;
equation
  u = integrator1.u;
  integrator1.y = y;
  der(integrator1.y) = integrator1.k .* integrator1.u;
end VectorizedDesired;

A couple of interesting questions arises:

  1. Should array dimensions be "normalized" by collecting them at the end, i.e. integrator1.u[n] instead of integrator1[n].u?
  2. Can n be kept as structural parameter during the translation?
  3. Is each required for Real integrator1.y[n](start = 0.0). The current implementation (see #5110) works fine without each.
  4. Are initializations of arrays with scalars allowed, i.e. parameter Real integrator1.y_start[n] = 0.0? This would simplify the generation of efficient code, i.e. a for loop assigning 0.0 to each array element instead of creation of a temporary array resulting from fill(0.0, n).
  5. Note: the operator changes from * to .*!
  6. Is it a general rule that arrays resulting from vectorized components have a diagonal dependency structure?

Change History (2)

comment:1 by Rüdiger Franke, 6 years ago

Resolution: duplicate
Status: newclosed

comment:2 by Rüdiger Franke, 6 years ago

See #5144

Note: See TracTickets for help on using tickets.