Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

[NF] Vectorize arrays of components #2712

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/Types.mo
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ public function isEnumeration "Return true if Type is the builtin String type."
input DAE.Type inType;
output Boolean outBoolean;
algorithm
outBoolean := match(inType)
outBoolean := match(arrayElementType(inType))
case (DAE.T_ENUMERATION()) then true;
else false;
end match;
Expand Down
6 changes: 6 additions & 0 deletions Compiler/NFFrontEnd/NFConnections.mo
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ public
Boolean expanded;
algorithm
cr := ComponentRef.evaluateSubscripts(cref);

if not Flags.isSet(Flags.NF_SCALARIZE) then
connectors := {Connector.fromCref(cr, ComponentRef.getSubscriptedType(cr), source)};
return;
end if;

cref_exp := Expression.CREF(ComponentRef.getSubscriptedType(cr), cr);
(cref_exp, expanded) := ExpandExp.expand(cref_exp);

Expand Down
12 changes: 8 additions & 4 deletions Compiler/NFFrontEnd/NFConnector.mo
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,14 @@ protected

case Type.ARRAY()
algorithm
t := Type.arrayElementType(ty);
for c in ComponentRef.scalarize(name) loop
conns := splitImpl(c, t, face, source, cty, conns);
end for;
if Flags.isSet(Flags.NF_SCALARIZE) then
t := Type.arrayElementType(ty);
for c in ComponentRef.scalarize(name) loop
conns := splitImpl(c, t, face, source, cty, conns);
end for;
else
conns := CONNECTOR(name, ty, face, cty, source) :: conns;
end if;
then
conns;

Expand Down
110 changes: 108 additions & 2 deletions Compiler/NFFrontEnd/NFFlatten.mo
Original file line number Diff line number Diff line change
Expand Up @@ -572,14 +572,34 @@ protected
Expression sub_exp;
list<Subscript> subs;
list<Variable> vrs;
Sections sects;
algorithm
// if we don't scalarize flatten the class and then add dimensions to the types
// if we don't scalarize flatten the class and vectorize it
if not Flags.isSet(Flags.NF_SCALARIZE) then
(vrs, sections) := flattenClass(cls, prefix, visibility, binding, {}, sections);
(vrs, sects) := flattenClass(cls, prefix, visibility, binding, {}, Sections.SECTIONS({}, {}, {}, {}));
// add dimensions to the types
for v in vrs loop
v.ty := Type.liftArrayLeftList(v.ty, dimensions);
vars := v::vars;
end for;
// vectorize equations
() := match sects
case Sections.SECTIONS()
algorithm
for eqn in listReverse(sects.equations) loop
sections := Sections.prependEquation(vectorizeEquation(eqn, dimensions, prefix), sections);
end for;
for eqn in listReverse(sects.initialEquations) loop
sections := Sections.prependEquation(vectorizeEquation(eqn, dimensions, prefix), sections, true);
end for;
for alg in listReverse(sects.algorithms) loop
sections := Sections.prependAlgorithm(vectorizeAlgorithm(alg, dimensions, prefix), sections);
end for;
for alg in listReverse(sects.initialAlgorithms) loop
sections := Sections.prependAlgorithm(vectorizeAlgorithm(alg, dimensions, prefix), sections, true);
end for;
then ();
end match;
return;
end if;

Expand All @@ -601,6 +621,92 @@ algorithm
end if;
end flattenArray;

function vectorizeEquation
input Equation eqn;
input list<Dimension> dimensions;
input ComponentRef prefix;
output Equation veqn;
algorithm
veqn := match eqn
local
InstNode prefix_node, iter;
Integer stop;
Expression range;
case Equation.EQUALITY(lhs = Expression.CREF(), rhs = Expression.CREF())
// let simple equality as is
then eqn;
else
// wrap general equation into for loop
algorithm
iter := match ComponentRef.node(prefix)
case prefix_node as InstNode.COMPONENT_NODE()
then InstNode.COMPONENT_NODE("$i", prefix_node.visibility, Pointer.create(Component.ITERATOR(Type.INTEGER(), Variability.IMPLICITLY_DISCRETE, Component.info(Pointer.access(prefix_node.component)))), prefix_node.parent);
end match;
{Dimension.INTEGER(size = stop)} := dimensions;
range := Expression.RANGE(Type.INTEGER(), Expression.INTEGER(1), NONE(), Expression.INTEGER(stop));
veqn := Equation.mapExp(eqn, function addIterator(prefix = prefix, subscript = Subscript.INDEX(Expression.CREF(Type.INTEGER(), ComponentRef.makeIterator(iter, Type.INTEGER())))));
then
Equation.FOR(iter, SOME(range), {veqn}, Equation.source(eqn));
end match;
end vectorizeEquation;

function vectorizeAlgorithm
input Algorithm alg;
input list<Dimension> dimensions;
input ComponentRef prefix;
output Algorithm valg;
algorithm
valg := match alg
local
InstNode prefix_node, iter;
Integer stop;
Expression range;
list<Statement> body;
case Algorithm.ALGORITHM(statements = {Statement.ASSIGNMENT(lhs = Expression.CREF(), rhs = Expression.CREF())})
// let simple assignment as is
then alg;
else
// wrap general algorithm into for loop
algorithm
iter := match ComponentRef.node(prefix)
case prefix_node as InstNode.COMPONENT_NODE()
then InstNode.COMPONENT_NODE("$i", prefix_node.visibility, Pointer.create(Component.ITERATOR(Type.INTEGER(), Variability.IMPLICITLY_DISCRETE, Component.info(Pointer.access(prefix_node.component)))), prefix_node.parent);
end match;
{Dimension.INTEGER(size = stop)} := dimensions;
range := Expression.RANGE(Type.INTEGER(), Expression.INTEGER(1), NONE(), Expression.INTEGER(stop));
body := Statement.mapExpList(alg.statements, function addIterator(prefix = prefix, subscript = Subscript.INDEX(Expression.CREF(Type.INTEGER(), ComponentRef.makeIterator(iter, Type.INTEGER())))));
then
Algorithm.ALGORITHM({Statement.FOR(iter, SOME(range), body, alg.source)}, alg.source);
end match;
end vectorizeAlgorithm;

function addIterator
input output Expression exp;
input ComponentRef prefix;
input Subscript subscript;
algorithm
exp := Expression.map(exp, function addIterator_traverse(prefix = prefix, subscript = subscript));
end addIterator;

function addIterator_traverse
input output Expression exp;
input ComponentRef prefix;
input Subscript subscript;
algorithm
exp := match exp
local
ComponentRef restCref;
case Expression.CREF(cref = ComponentRef.CREF(restCref = restCref))
algorithm
if ComponentRef.isEqual(restCref, prefix) then
exp.cref := ComponentRef.addSubscript(subscript, exp.cref);
end if;
then
exp;
else exp;
end match;
end addIterator_traverse;

function subscriptBindingOpt
input list<Subscript> subscripts;
input output Option<Binding> binding;
Expand Down
29 changes: 29 additions & 0 deletions Compiler/NFFrontEnd/NFSections.mo
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,35 @@ public
end match;
end prependEquation;

function prependAlgorithm
input Algorithm alg;
input output Sections sections;
input Boolean isInitial = false;
algorithm
sections := match sections
case SECTIONS()
algorithm
if isInitial then
sections.initialAlgorithms := alg :: sections.initialAlgorithms;
else
sections.algorithms := alg :: sections.algorithms;
end if;
then
sections;

case EMPTY()
then if isInitial then SECTIONS({}, {}, {}, {alg}) else SECTIONS({}, {}, {alg}, {});

else
algorithm
Error.assertion(false, getInstanceName() +
" got invalid Sections to prepend algorithm to", sourceInfo());
then
fail();

end match;
end prependAlgorithm;

function append
input list<Equation> equations;
input list<Equation> initialEquations;
Expand Down
2 changes: 2 additions & 0 deletions Compiler/SimCode/SimCodeUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -7076,6 +7076,8 @@ algorithm
elseif isConst then
addSimVar(simVar, SimVarsIndex.stringConst, simVars);
end if;
else
Error.addInternalError("Failed to find SimVar list for Var: " + BackendDump.varString(dlowVar), sourceInfo());
end if;
// external objects
elseif BackendVariable.isExtObj(dlowVar) then
Expand Down