From 9839b8276a14ca9a850f77b5b7bc274190bdad20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Fri, 23 Oct 2020 16:26:50 +0200 Subject: [PATCH] Array connection improvements. - Replace : subscripts with 1:size subscripts. - Fill out connector crefs with : subscripts such that all dimensions are subscripted. - Pad the maps for each connector so they all have the same dimensions. --- .../Compiler/NFFrontEnd/NFArrayConnections.mo | 19 ++++-- .../Compiler/NFFrontEnd/NFComponentRef.mo | 63 +++++++++++++++++++ OMCompiler/Compiler/NFFrontEnd/NFSubscript.mo | 21 +++++++ 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/OMCompiler/Compiler/NFFrontEnd/NFArrayConnections.mo b/OMCompiler/Compiler/NFFrontEnd/NFArrayConnections.mo index 1e226e1f5cc..85e8196a16a 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFArrayConnections.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFArrayConnections.mo @@ -308,10 +308,10 @@ protected input output ComponentRef cref; output list subs; algorithm + cref := ComponentRef.fillSubscripts(cref); + cref := ComponentRef.replaceWholeSubscripts(cref); subs := ComponentRef.subscriptsAllFlat(cref); cref := ComponentRef.stripSubscriptsAll(cref); - - // TODO: Replace any : in the subs with the correct dimension. end separate; function getConnectIntervals @@ -346,7 +346,7 @@ protected mi := Array.map(miv, make_lo_interval); else index := 1; - mi := arrayCreate(listLength(subs), SBInterval.newEmpty()); + mi := arrayCopy(miv); for s in subs loop sub_exp := evalCrefs(Subscript.toExp(s)); @@ -365,6 +365,11 @@ protected index := index + 1; end for; + + for i in listLength(subs)+1:arrayLength(mi) loop + aux_lo := SBInterval.lowerBound(miv[i]); + mi[index] := SBInterval.new(aux_lo, 1, aux_lo); + end for; end if; outMI := SBMultiInterval.fromArray(mi); @@ -406,7 +411,7 @@ protected mi := SBMultiInterval.fromArray(arrayCreate(Vector.size(vCount), SBInterval.new(vc, 1, vc))); else - ints := arrayCreate(listLength(dims), SBInterval.newEmpty()); + ints := arrayCreate(Vector.size(vCount), SBInterval.newEmpty()); new_vc := Vector.copy(vCount); index := 1; @@ -431,6 +436,11 @@ protected index := index + 1; end for; + for i in listLength(dims)+1:Vector.size(vCount) loop + vc := Vector.get(vCount, 1); + ints[i] := SBInterval.new(vc, 1, vc); + end for; + mi := SBMultiInterval.fromArray(ints); if not SBMultiInterval.isEmpty(mi) then @@ -899,6 +909,7 @@ protected if Type.isArray(Expression.typeOf(outExp)) then subs := list(Subscript.fromTypedExp(i) for i in indices); + subs := List.firstN(subs, Type.dimensionCount(Expression.typeOf(outExp))); outExp := Expression.applySubscripts(subs, outExp); end if; end generateConnector; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo index d4c4145b3b4..5bc70d68e5f 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo @@ -44,6 +44,7 @@ protected import Class = NFClass; import List; import Prefixes = NFPrefixes; + import MetaModelica.Dangerous.*; import ComponentRef = NFComponentRef; @@ -572,6 +573,68 @@ public end match; end foldSubscripts; + function fillSubscripts + "Fills in any unsubscripted dimensions in the cref with : subscripts." + input output ComponentRef cref; + algorithm + () := match cref + local + list dims; + Integer dim_count, sub_count; + + case CREF() + algorithm + dims := Type.arrayDims(cref.ty); + dim_count := listLength(dims); + sub_count := listLength(cref.subscripts); + + if sub_count < dim_count then + cref.subscripts := List.consN(dim_count - sub_count, Subscript.WHOLE(), cref.subscripts); + end if; + + cref.restCref := fillSubscripts(cref.restCref); + then + (); + + else (); + end match; + end fillSubscripts; + + function replaceWholeSubscripts + "Replaces any : subscripts with slice subscripts for the corresponding dimension." + input output ComponentRef cref; + algorithm + () := match cref + local + list dims; + list subs; + + case CREF() + algorithm + if List.exist(cref.subscripts, Subscript.isWhole) then + dims := Type.arrayDims(cref.ty); + subs := {}; + + for s in cref.subscripts loop + if Subscript.isWhole(s) then + s := Subscript.fromDimension(listHead(dims)); + end if; + + subs := s :: subs; + dims := listRest(dims); + end for; + + cref.subscripts := listReverseInPlace(subs); + end if; + + cref.restCref := replaceWholeSubscripts(cref.restCref); + then + (); + + else (); + end match; + end replaceWholeSubscripts; + function compare input ComponentRef cref1; input ComponentRef cref2; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFSubscript.mo b/OMCompiler/Compiler/NFFrontEnd/NFSubscript.mo index b38a2f9b7f7..cc284fd6831 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFSubscript.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFSubscript.mo @@ -727,6 +727,27 @@ public end match; end toDimension; + function fromDimension + "Returns a slice subscripts that covers the given dimension. + Will fail for untyped or unknown dimensions." + input Dimension dimension; + output Subscript subscript; + algorithm + subscript := match dimension + case Dimension.INTEGER() + then Subscript.SLICE(Expression.makeIntegerRange(1, 1, dimension.size)); + case Dimension.BOOLEAN() + then Subscript.SLICE(Expression.makeRange(Expression.BOOLEAN(false), NONE(), Expression.BOOLEAN(true))); + case Dimension.ENUM() + then Subscript.SLICE(Expression.makeRange( + Expression.makeEnumLiteral(dimension.enumType, 1), + NONE(), + Expression.makeEnumLiteral(dimension.enumType, Type.enumSize(dimension.enumType)))); + case Dimension.EXP() + then Subscript.SLICE(Expression.makeRange(Expression.INTEGER(1), NONE(), dimension.exp)); + end match; + end fromDimension; + function scalarize input Subscript subscript; input Dimension dimension;