Skip to content

Commit

Permalink
Improve vectorization of bindings (#10903)
Browse files Browse the repository at this point in the history
  • Loading branch information
perost committed Jun 29, 2023
1 parent 5601448 commit 56e4b4c
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 14 deletions.
18 changes: 5 additions & 13 deletions OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo
Original file line number Diff line number Diff line change
Expand Up @@ -764,15 +764,15 @@ algorithm
// a binding for each record field, or moved to an initial equation if
// splitting the binding fails.
if Binding.isExplicitlyBound(binding) then
binding := flattenBinding(binding, Prefix.toNonIndexedPrefix(prefix));
binding := flattenBinding(binding, prefix);
binding_exp := Binding.getTypedExp(binding);
binding_var := Binding.variability(binding);

comp_var := Component.variability(comp);
if comp_var <= Variability.STRUCTURAL_PARAMETER or binding_var <= Variability.STRUCTURAL_PARAMETER then
// Constant evaluate parameters that are structural/constant.
binding_exp := Ceval.evalExp(binding_exp);
binding_exp := flattenExp(binding_exp, Prefix.toNonIndexedPrefix(prefix));
binding_exp := flattenExp(binding_exp, prefix);
elseif binding_var == Variability.PARAMETER and Component.isFinal(comp) then
// Try to use inlining first.
try
Expand All @@ -784,7 +784,7 @@ algorithm
if not (Expression.isRecord(binding_exp) or Expression.isCref(binding_exp)) then
try
binding_exp_eval := Ceval.tryEvalExp(binding_exp);
binding_exp_eval := flattenExp(binding_exp_eval, Prefix.toNonIndexedPrefix(prefix));
binding_exp_eval := flattenExp(binding_exp_eval, prefix);

// Throw away the evaluated binding if the number of dimensions no
// longer match after evaluation, in case Ceval fails to apply the
Expand Down Expand Up @@ -1002,14 +1002,13 @@ protected
Type binding_ty;
list<tuple<InstNode, Expression>> iters;
ComponentRef prefix_cr;
Integer dim_count;
algorithm
if not Binding.isBound(binding) then
return;
end if;

prefix_cr := Prefix.indexedPrefix(prefix);
subs := ComponentRef.subscriptsAllFlat(prefix_cr);
subs := list(s for s guard Subscript.isIterator(s) in ComponentRef.subscriptsAllFlat(prefix_cr));

if listEmpty(subs) then
return;
Expand All @@ -1020,16 +1019,9 @@ algorithm

nodes := ComponentRef.nodes(prefix_cr);
dims := List.flatten(list(Type.arrayDims(InstNode.getType(n)) for n in nodes));
dims := List.lastN(dims, listLength(subs));
binding_ty := Type.liftArrayLeftList(binding_ty, dims);

dim_count := Expression.dimensionCount(exp) - Type.dimensionCount(binding_ty);

if dim_count <= 0 then
return;
end if;

dims := List.lastN(dims, dim_count);

if not listEmpty(dims) then
if Expression.isLiteral(exp) then
array_call := Call.makeTypedCall(NFBuiltinFuncs.FILL_FUNC,
Expand Down
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,7 @@ usertype5.mo \
usertype6.mo \
VectorizeBindings1.mo \
VectorizeBindings2.mo \
VectorizeBindings3.mo \
VectorTest.mo \
Visibility1.mo \
Visibility2.mo \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ end VectorizeBindings1;
// class VectorizeBindings1
// parameter Real p = 2.0;
// parameter Real[2, 3] m.q = fill(2.0, 2, 3);
// parameter Real[2, 3] m.p = fill(2.0 * p, 2, 3);
// parameter Real[2, 3] m.p = array(array(2.0 * p for $m2 in 1:3) for $m1 in 1:2);
// end VectorizeBindings1;
// endResult
148 changes: 148 additions & 0 deletions testsuite/flattening/modelica/scodeinst/VectorizeBindings3.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// name: VectorizeBindings3
// keywords:
// status: correct
// cflags: -d=newInst --newBackend
//

operator record Complex
replaceable Real re;
replaceable Real im;

encapsulated operator 'constructor'
function fromReal
import Complex;
input Real re;
input Real im = 0;
output Complex result(re = re, im = im);
algorithm
annotation(Inline = true);
end fromReal;
end 'constructor';

encapsulated operator '*'
function multiply
import Complex;
input Complex c1;
input Complex c2;
output Complex c3;
algorithm
c3 := Complex(c1.re*c2.re - c1.im*c2.im, c1.re*c2.im + c1.im*c2.re);
annotation(Inline = true);
end multiply;

function scalarProduct
import Complex;
input Complex[:] c1;
input Complex[size(c1, 1)] c2;
output Complex c3;
algorithm
c3 := Complex(0);
for i in 1:size(c1, 1) loop
c3 := c3 + c1[i]*c2[i];
end for;
annotation(Inline = true);
end scalarProduct;
end '*';

encapsulated operator function '+'
import Complex;
input Complex c1;
input Complex c2;
output Complex c3;
algorithm
c3 := Complex(c1.re + c2.re, c1.im + c2.im);
annotation(Inline = true);
end '+';
end Complex;

package ComplexMath
function exp
input Complex c1;
output Complex c2;
algorithm
c2 := Complex(.exp(c1.re)*.cos(c1.im), .exp(c1.re)*.sin(c1.im));
end exp;
end ComplexMath;

function symmetricOrientation
input Integer m;
output Real[m] orientation;
algorithm
orientation := {(k - 1)*2*3/m for k in 1:m};
end symmetricOrientation;

model SinglePhaseElectroMagneticConverter
parameter Real effectiveTurns annotation(Evaluate = true);
parameter Real orientation annotation(Evaluate = true);
final parameter Complex N = effectiveTurns*ComplexMath.exp(Complex(0, orientation));
end SinglePhaseElectroMagneticConverter;

model PolyphaseElectroMagneticConverter
parameter Integer m = 3 annotation(Evaluate = true);
parameter Real[m] effectiveTurns;
parameter Real[m] orientation;
SinglePhaseElectroMagneticConverter[m] singlePhaseElectroMagneticConverter(final effectiveTurns = effectiveTurns, final orientation = orientation);
end PolyphaseElectroMagneticConverter;

model SymmetricPolyphaseWinding
parameter Integer m = 3 annotation(Evaluate = true);
parameter Real effectiveTurns = 1;
PolyphaseElectroMagneticConverter electroMagneticConverter(final m = m, final effectiveTurns = fill(effectiveTurns, m), final orientation = symmetricOrientation(m));
end SymmetricPolyphaseWinding;

model IM_SquirrelCage
parameter Integer m(min = 3) = 3;
parameter Real effectiveStatorTurns = 1;
SymmetricPolyphaseWinding stator(final m = m, final effectiveTurns = effectiveStatorTurns);
end IM_SquirrelCage;

model VectorizeBindings3
constant Integer m = 3;
parameter Integer effectiveStatorTurns = 1;
IM_SquirrelCage aimc(effectiveStatorTurns = effectiveStatorTurns);
end VectorizeBindings3;

// Result:
// function Complex "Automatically generated record constructor for Complex"
// input Real re;
// input Real im;
// output Complex res;
// end Complex;
//
// function Complex.'*'.multiply
// input Complex c1;
// input Complex c2;
// output Complex c3;
// algorithm
// c3 := Complex.'constructor'.fromReal(c1.re * c2.re - c1.im * c2.im, c1.re * c2.im + c1.im * c2.re);
// end Complex.'*'.multiply;
//
// function Complex.'constructor'.fromReal
// input Real re;
// input Real im = 0.0;
// output Complex result;
// algorithm
// end Complex.'constructor'.fromReal;
//
// function ComplexMath.exp
// input Complex c1;
// output Complex c2;
// algorithm
// c2 := Complex.'constructor'.fromReal(exp(c1.re) * cos(c1.im), exp(c1.re) * sin(c1.im));
// end ComplexMath.exp;
//
// class VectorizeBindings3
// constant Integer m = 3;
// parameter Integer effectiveStatorTurns = 1;
// final parameter Integer aimc.m(min = 3) = 3;
// parameter Real aimc.effectiveStatorTurns = /*Real*/(effectiveStatorTurns);
// final parameter Integer aimc.stator.m = 3;
// final parameter Real aimc.stator.effectiveTurns = aimc.effectiveStatorTurns;
// final parameter Integer aimc.stator.electroMagneticConverter.m = 3;
// final parameter Real[3] aimc.stator.electroMagneticConverter.effectiveTurns = array(aimc.stator.effectiveTurns for $i1 in 1:3);
// final parameter Real[3] aimc.stator.electroMagneticConverter.orientation = {0.0, 2.0, 4.0};
// parameter Complex[3] aimc.stator.electroMagneticConverter.singlePhaseElectroMagneticConverter.N = array(Complex.'*'.multiply(Complex.'constructor'.fromReal(aimc.stator.electroMagneticConverter.singlePhaseElectroMagneticConverter[$singlePhaseElectroMagneticConverter1].effectiveTurns, 0.0), ComplexMath.exp(Complex.'constructor'.fromReal(0.0, {0.0, 2.0, 4.0}[$singlePhaseElectroMagneticConverter1]))) for $singlePhaseElectroMagneticConverter1 in 1:3);
// final parameter Real[3] aimc.stator.electroMagneticConverter.singlePhaseElectroMagneticConverter.orientation = {0.0, 2.0, 4.0};
// final parameter Real[3] aimc.stator.electroMagneticConverter.singlePhaseElectroMagneticConverter.effectiveTurns = array(aimc.stator.electroMagneticConverter.effectiveTurns[$singlePhaseElectroMagneticConverter1] for $singlePhaseElectroMagneticConverter1 in 1:3);
// end VectorizeBindings3;
// endResult

0 comments on commit 56e4b4c

Please sign in to comment.