diff --git a/OMCompiler/Compiler/NFFrontEnd/NFCall.mo b/OMCompiler/Compiler/NFFrontEnd/NFCall.mo index e09fbef1756..67ae2e3eb94 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFCall.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFCall.mo @@ -2110,14 +2110,8 @@ protected purity := Variability.purityMin(purity, exp_pur); {fn} := Function.typeRefCache(call.ref); TypeCheck.checkReductionType(ty, Function.name(fn), call.exp, info); - - fold_id := Util.getTempVariableIndex(); - res_id := Util.getTempVariableIndex(); - default_exp := reductionDefaultValue(fn, ty); - fold_exp := reductionFoldExpression(fn, ty, variability, purity, fold_id, res_id, info); - fold_tuple := (fold_exp, fold_id, res_id); then - (TYPED_REDUCTION(fn, ty, variability, purity, arg, iters, default_exp, fold_tuple), ty, variability, purity); + (makeTypedReduction(fn, ty, variability, purity, arg, iters, info), ty, variability, purity); else algorithm @@ -2127,6 +2121,31 @@ protected end match; end typeReduction; +public + function makeTypedReduction + input Function fn; + input Type ty; + input Variability var; + input Purity purity; + input Expression arg; + input list> iters; + input SourceInfo info; + output Call call; + protected + String fold_id, res_id; + Option default_exp, fold_exp; + tuple, String, String> fold_tuple; + algorithm + fold_id := Util.getTempVariableIndex(); + res_id := Util.getTempVariableIndex(); + default_exp := reductionDefaultValue(fn, ty); + fold_exp := reductionFoldExpression(fn, ty, var, purity, fold_id, res_id, info); + fold_tuple := (fold_exp, fold_id, res_id); + + call := TYPED_REDUCTION(fn, ty, var, purity, arg, iters, default_exp, fold_tuple); + end makeTypedReduction; + +protected function reductionDefaultValue input Function fn; input Type ty; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo b/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo index 84afa55796a..e8db2b56e96 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo @@ -242,9 +242,11 @@ algorithm case "fill" then simplifyFill(listHead(args), listRest(args), call); case "homotopy" then simplifyHomotopy(args, call); + case "max" guard listLength(args) == 1 then simplifyReducedArrayConstructor(listHead(args), call); + case "min" guard listLength(args) == 1 then simplifyReducedArrayConstructor(listHead(args), call); case "ones" then simplifyFill(Expression.INTEGER(1), args, call); - case "sum" then simplifySumProduct(listHead(args), call, isSum = true); case "product" then simplifySumProduct(listHead(args), call, isSum = false); + case "sum" then simplifySumProduct(listHead(args), call, isSum = true); case "transpose" then simplifyTranspose(listHead(args), call); case "vector" then simplifyVector(listHead(args), call); case "zeros" then simplifyFill(Expression.INTEGER(0), args, call); @@ -282,10 +284,34 @@ algorithm end for; end if; else - exp := Expression.CALL(call); + exp := simplifyReducedArrayConstructor(exp, call); end if; end simplifySumProduct; +function simplifyReducedArrayConstructor + input Expression arg; + input Call call; + output Expression exp; +algorithm + exp := match arg + local + Call arr_call; + Function fn; + Type ty; + Variability var; + Purity purity; + + case Expression.CALL(call = arr_call as Call.TYPED_ARRAY_CONSTRUCTOR()) + guard Type.dimensionCount(arr_call.ty) == 1 + algorithm + Call.TYPED_CALL(fn = fn, ty = ty, var = var, purity = purity) := call; + then + Expression.CALL(Call.makeTypedReduction(fn, ty, var, purity, arr_call.exp, arr_call.iters, AbsynUtil.dummyInfo)); + + else Expression.CALL(call); + end match; +end simplifyReducedArrayConstructor; + function simplifyTranspose input Expression arg; input Call call; diff --git a/testsuite/flattening/modelica/scodeinst/FuncVectorization4.mo b/testsuite/flattening/modelica/scodeinst/FuncVectorization4.mo index 85613aaafc5..61cf412efaf 100644 --- a/testsuite/flattening/modelica/scodeinst/FuncVectorization4.mo +++ b/testsuite/flattening/modelica/scodeinst/FuncVectorization4.mo @@ -28,7 +28,7 @@ end FuncVectorization4; // output Real s = 0.0; // algorithm // for i in 1:size(x, 1) loop -// s := s + sum(array(abs(x[i,$i1]) for $i1 in 1:size(x[i,:], 1))); +// s := s + sum(abs(x[i,$i1]) for $i1 in 1:size(x[i,:], 1)); // end for; // end FuncVectorization4.f; // diff --git a/testsuite/flattening/modelica/scodeinst/FuncVectorization6.mo b/testsuite/flattening/modelica/scodeinst/FuncVectorization6.mo new file mode 100644 index 00000000000..e38ff2e1cd5 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/FuncVectorization6.mo @@ -0,0 +1,41 @@ +// name: FuncVectorization6 +// keywords: vectorization function +// status: correct +// cflags: -d=newInst +// +// + +model FuncVectorization6 + function f + input Real[:, :] x; + output Real s = 0.0; + algorithm + for i in 1:size(x, 1) loop + s := s + min(abs(x[i, :])); + end for; + end f; + + Real x; +equation + x = f({{time, 2, 3}, {4, 5, 6}}); + x = f({{1, 2, 3}, {4, 5, 6}}); +end FuncVectorization6; + + +// Result: +// function FuncVectorization6.f +// input Real[:, :] x; +// output Real s = 0.0; +// algorithm +// for i in 1:size(x, 1) loop +// s := s + min(abs(x[i,$i1]) for $i1 in 1:size(x[i,:], 1)); +// end for; +// end FuncVectorization6.f; +// +// class FuncVectorization6 +// Real x; +// equation +// x = FuncVectorization6.f({{time, 2.0, 3.0}, {4.0, 5.0, 6.0}}); +// x = 5.0; +// end FuncVectorization6; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index 0fb0a8aac65..b636a89103e 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -551,6 +551,7 @@ FuncVectorization2.mo \ FuncVectorization3.mo \ FuncVectorization4.mo \ FuncVectorization5.mo \ +FuncVectorization6.mo \ FuncVectorizationBuiltin.mo \ FuncVectorizationCastConflict1.mo \ FuncVectorizationMap1.mo \