Skip to content

Commit

Permalink
Improve function evaluation (#10486)
Browse files Browse the repository at this point in the history
- Improve retyping of unknown dimensions.
- Fix retyping of element-wise add/sub operations.

Fixes #10479
  • Loading branch information
perost committed Mar 31, 2023
1 parent f4dc292 commit afd0bf2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 32 deletions.
8 changes: 4 additions & 4 deletions OMCompiler/Compiler/NFFrontEnd/NFTypeCheck.mo
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ algorithm
case Op.POW_EW then checkBinaryOperationPowEW(exp1, type1, exp2, type2, info);
// These operators should not occur in untyped expressions, but sometimes
// we want to retype already typed expressions due to changes in them.
case Op.ADD_SCALAR_ARRAY then checkBinaryOperationAdd(exp1, type1, exp2, type2, info);
case Op.ADD_ARRAY_SCALAR then checkBinaryOperationAdd(exp1, type1, exp2, type2, info);
case Op.SUB_SCALAR_ARRAY then checkBinaryOperationSub(exp1, type1, exp2, type2, info);
case Op.SUB_ARRAY_SCALAR then checkBinaryOperationSub(exp1, type1, exp2, type2, info);
case Op.ADD_SCALAR_ARRAY then checkBinaryOperationEW(exp1, type1, exp2, type2, Op.ADD, info);
case Op.ADD_ARRAY_SCALAR then checkBinaryOperationEW(exp1, type1, exp2, type2, Op.ADD, info);
case Op.SUB_SCALAR_ARRAY then checkBinaryOperationEW(exp1, type1, exp2, type2, Op.SUB, info);
case Op.SUB_ARRAY_SCALAR then checkBinaryOperationEW(exp1, type1, exp2, type2, Op.SUB, info);
case Op.MUL_SCALAR_ARRAY then checkBinaryOperationMul(exp1, type1, exp2, type2, info);
case Op.MUL_ARRAY_SCALAR then checkBinaryOperationMul(exp1, type1, exp2, type2, info);
case Op.MUL_VECTOR_MATRIX then checkBinaryOperationMul(exp1, type1, exp2, type2, info);
Expand Down
60 changes: 32 additions & 28 deletions OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1597,40 +1597,44 @@ protected
algorithm
ty := Expression.typeOf(exp);

// If the expression has already been typed, just get the dimension from the type.
if Type.isKnown(ty) then
// If the expression has already been typed, just get the dimension from the type.
(dim, error) := nthDimensionBoundsChecked(ty, dimIndex);
typedExp := SOME(exp);
else
// Otherwise we try to type as little as possible of the expression to get
// the dimension we need, to avoid introducing unnecessary cycles.
(dim, error) := match exp
// An untyped array, use typeArrayDim to get the dimension.
case Expression.ARRAY(ty = Type.UNKNOWN())
then typeArrayDim(exp, dimIndex);

// A cref, use typeCrefDim to get the dimension.
case Expression.CREF()
then typeCrefDim(exp.cref, dimIndex, context, info);

// Any other expression, type the whole expression and get the dimension
// from the type.
else
algorithm
(e, ty, _) := typeExp(exp, context, info);

if Type.isConditionalArray(ty) then
e := Expression.map(e,
function evaluateArrayIf(target = Ceval.EvalTarget.GENERIC(info)));
(e, ty, _) := typeExp(e, context, info);
end if;
if not Dimension.isUnknown(dim) then
return;
end if;
end if;

typedExp := SOME(e);
then
nthDimensionBoundsChecked(ty, dimIndex);
// Otherwise we try to type as little as possible of the expression to get
// the dimension we need, to avoid introducing unnecessary cycles.
(dim, error) := match exp
// An untyped array, use typeArrayDim to get the dimension.
case Expression.ARRAY(ty = Type.UNKNOWN())
then typeArrayDim(exp, dimIndex);

end match;
end if;
// A cref, use typeCrefDim to get the dimension.
case Expression.CREF()
then typeCrefDim(exp.cref, dimIndex, context, info);

// Any other expression, type the whole expression and get the dimension
// from the type.
else
algorithm
(e, ty, _) := typeExp(exp, context, info);

if Type.isConditionalArray(ty) then
e := Expression.map(e,
function evaluateArrayIf(target = Ceval.EvalTarget.GENERIC(info)));
(e, ty, _) := typeExp(e, context, info);
end if;

typedExp := SOME(e);
then
nthDimensionBoundsChecked(ty, dimIndex);

end match;
end typeExpDim;

function evaluateArrayIf
Expand Down
27 changes: 27 additions & 0 deletions testsuite/flattening/modelica/scodeinst/CevalFuncArray6.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// name: CevalFuncArray6
// keywords:
// status: correct
// cflags: -d=newInst
//
//

function f
input Real x;
output Real[3, 1] table;
protected
Real[:] v = linspace(0, 1, 3);
algorithm
table[:, 1] := 1.*(acos(1 .- v));
end f;

model CevalFuncArray6
parameter Real[:, 1] table = f(1) annotation(Evaluate=true);
end CevalFuncArray6;

// Result:
// class CevalFuncArray6
// final parameter Real table[1,1] = 0.0;
// final parameter Real table[2,1] = 1.047197551196598;
// final parameter Real table[3,1] = 1.570796326794897;
// end CevalFuncArray6;
// endResult
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ CevalFuncArray2.mo \
CevalFuncArray3.mo \
CevalFuncArray4.mo \
CevalFuncArray5.mo \
CevalFuncArray6.mo \
CevalFuncAssert1.mo \
CevalFuncAssert2.mo \
CevalFuncFor1.mo \
Expand Down

0 comments on commit afd0bf2

Please sign in to comment.