Skip to content

Commit

Permalink
Implemented code generation of reductions to fix bug 1136, which invo…
Browse files Browse the repository at this point in the history
…lved:

- Extending Exp.expContains to handle reductions.
- Fixing elaboration of reductions in Static.elabReduction.
- Adding code generation for reductions to Codegen.
- Adding testcase 'Reductions' in mosfiles.

Reductions where the range expression is an empty vector is not working reliably
yet.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@4855 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Jan 25, 2010
1 parent 8ee35c6 commit 5806822
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
120 changes: 120 additions & 0 deletions Compiler/Codegen.mo
Expand Up @@ -4670,6 +4670,50 @@ algorithm
cfn = cAddStatements(cfn, {stmt});
then
(cfn,tvar,tnr);

/* reduction of empty vector */
case (DAE.REDUCTION(path = Absyn.IDENT(reduction_op), expr = e1, range =
DAE.MATRIX(scalar = {})), tnr, context)
local
String reduction_op, start_value;
equation
ty = Exp.typeof(e1);
ty = Exp.unliftArray(ty);
type_string = expTypeStr(ty, false);
(_, start_value) = makeReductionFunction(reduction_op, ty);
(decl1, var1, tnr) = generateTempDeclWithAssignment(type_string, tnr, "", start_value);
cfn = cAddVariables(cEmptyFunction, {decl1});
then
(cfn, var1, tnr);

/* reduction */
case (DAE.REDUCTION(path = Absyn.IDENT(reduction_op), expr = e1, ident = iter, range = e2), tnr, context)
local
String reduction_op, start_value, reduction_fun;
DAE.Exp exp_var, accum_var;
Ident iter;
DAE.Statement for_stmt, exp_stmt, reduction_stmt;
equation
ty = Exp.typeof(e1);
ty = Exp.unliftArray(ty);
type_string = expTypeStr(ty, false);
(reduction_fun, start_value) = makeReductionFunction(reduction_op, ty);
(decl1, var1, tnr) = generateTempDecl(type_string, tnr);
(decl2, var2, tnr) = generateTempDeclWithAssignment(type_string, tnr, "", start_value);
exp_var = makeCrefExpFromStringType(var1, ty);
accum_var = makeCrefExpFromStringType(var2, ty);
// Assign the result of the reduction expression to a temporary variable.
exp_stmt = DAE.STMT_ASSIGN(ty, exp_var, e1);
// Do the reduction, accum := reduction_fun(accum, exp);
reduction_stmt = DAE.STMT_ASSIGN(ty, accum_var,
DAE.CALL(Absyn.IDENT(reduction_fun), {accum_var, exp_var}, false, true, ty, DAE.NO_INLINE));
// Generate a for-loop with these statements over the given range.
for_stmt = DAE.STMT_FOR(DAE.ET_INT, false, iter, e2, {exp_stmt, reduction_stmt});
(cfn, tnr) = generateAlgorithmStatement(for_stmt, tnr, context);
cfn = cAddVariables(cfn, {decl1, decl2});
then
(cfn, var2, tnr);

/* valueblock */
case (DAE.VALUEBLOCK(ty,localDecls = ld,body = b,
result = res),tnr,context)
Expand Down Expand Up @@ -5253,6 +5297,50 @@ algorithm
cfn = cAddStatements(cfn, {stmt});
then
(cfn,tvar,tnr);

/* reduction of empty vector */
case (DAE.REDUCTION(path = Absyn.IDENT(reduction_op), expr = e1, range =
DAE.MATRIX(scalar = {})), tnr, context)
local
String reduction_op, start_value;
equation
ty = Exp.typeof(e1);
ty = Exp.unliftArray(ty);
type_string = expTypeStr(ty, false);
(_, start_value) = makeReductionFunction(reduction_op, ty);
(decl1, var1, tnr) = generateTempDeclWithAssignment(type_string, tnr, "", start_value);
cfn = cAddVariables(cEmptyFunction, {decl1});
then
(cfn, var1, tnr);

/* reduction */
case (DAE.REDUCTION(path = Absyn.IDENT(reduction_op), expr = e1, ident = iter, range = e2), tnr, context)
local
String reduction_op, start_value, reduction_fun;
DAE.Exp exp_var, accum_var;
Ident iter;
DAE.Statement for_stmt, exp_stmt, reduction_stmt;
equation
ty = Exp.typeof(e1);
ty = Exp.unliftArray(ty);
type_string = expTypeStr(ty, false);
(reduction_fun, start_value) = makeReductionFunction(reduction_op, ty);
(decl1, var1, tnr) = generateTempDecl(type_string, tnr);
(decl2, var2, tnr) = generateTempDeclWithAssignment(type_string, tnr, "", start_value);
exp_var = makeCrefExpFromStringType(var1, ty);
accum_var = makeCrefExpFromStringType(var2, ty);
// Assign the result of the reduction expression to a temporary variable.
exp_stmt = DAE.STMT_ASSIGN(ty, exp_var, e1);
// Do the reduction, accum := reduction_fun(accum, exp);
reduction_stmt = DAE.STMT_ASSIGN(ty, accum_var,
DAE.CALL(Absyn.IDENT(reduction_fun), {accum_var, exp_var}, false, true, ty, DAE.NO_INLINE));
// Generate a for-loop with these statements over the given range.
for_stmt = DAE.STMT_FOR(DAE.ET_INT, false, iter, e2, {exp_stmt, reduction_stmt});
(cfn, tnr) = generateAlgorithmStatement(for_stmt, tnr, context);
cfn = cAddVariables(cfn, {decl1, decl2});
then
(cfn, var2, tnr);

/* valueblock */
case (DAE.VALUEBLOCK(ty,localDecls = ld,body = b,
result = res),tnr,context)
Expand Down Expand Up @@ -10480,6 +10568,12 @@ algorithm

case(DAE.CREF(_,_),_) then {};

case (DAE.REDUCTION(expr = e1), fn)
equation
res = getMatchingExps(e1, fn);
then
res;

case (DAE.VALUEBLOCK(localDecls = ld,body = body,result = e),fn)
local
list<DAE.Element> ld;
Expand Down Expand Up @@ -10600,4 +10694,30 @@ algorithm
exp := Exp.makeCrefExp(cref, DAE.ET_OTHER);
end makeCrefExpFromString;

protected function makeCrefExpFromStringType
input String name;
input DAE.ExpType ty;
output DAE.Exp e;
algorithm
e := DAE.CREF(DAE.CREF_IDENT(name, ty, {}), ty);
end makeCrefExpFromStringType;

protected function makeReductionFunction
input String reductionOp;
input DAE.ExpType type_;
output String func;
output String startValue;
algorithm
(func, startValue) := matchcontinue(reductionOp, type_)
case ("min", DAE.ET_INT) then ("min", "1073741823");
case ("min", DAE.ET_REAL) then ("min", "1.e60");
case ("max", DAE.ET_INT) then ("max", "-1073741823");
case ("max", DAE.ET_REAL) then ("max", "-1.e60");
case ("sum", DAE.ET_INT) then ("intAdd", "0");
case ("sum", DAE.ET_REAL) then ("realAdd", "0");
case ("product", DAE.ET_INT) then ("intMul", "1");
case ("product", DAE.ET_REAL) then ("realMul", "1");
end matchcontinue;
end makeReductionFunction;

end Codegen;
5 changes: 5 additions & 0 deletions Compiler/Exp.mo
Expand Up @@ -8552,6 +8552,11 @@ algorithm
res = expContains(e, cr);
then
res;
case (DAE.REDUCTION(expr = e), cr)
equation
res = expContains(e, cr);
then
res;
case (e,cr)
equation
true = RTOpts.debugFlag("failtrace");
Expand Down
6 changes: 5 additions & 1 deletion Compiler/Static.mo
Expand Up @@ -1402,6 +1402,7 @@ algorithm
dae = DAEUtil.joinDaes(dae1,dae2);
then
(cache, exp_1, prop, st,dae);

/* min, max, sum and product */
case (cache,env,fn,exp,{(iter,SOME(iterexp))},impl,st,doVect)
equation
Expand All @@ -1417,7 +1418,7 @@ algorithm
env_1 = Env.extendFrameForIterator(env_1, iter, iterty, DAE.VALBOUND(Values.INTEGER(1)), SCode.CONST());
(cache,_,DAE.PROP(expty,expconst),st,dae3) = elabExp(cache,env_1, exp, impl, st,doVect) "const so that expr is elaborated to const" ;
const = Types.constAnd(expconst, iterconst);
prop = DAE.PROP(expty, expconst);
prop = DAE.PROP(expty, const);
fn_1 = Absyn.crefToPath(fn);
dae = DAEUtil.joinDaeLst({dae1,dae2,dae3});
then
Expand Down Expand Up @@ -2408,6 +2409,9 @@ algorithm
Boolean doVect;
DAE.DAElist dae,dae1,dae2;

case (cache, _, {}, _, _, _)
then (cache, {}, DAE.PROP((DAE.T_REAL({}), NONE), DAE.C_CONST), DAE.DAE({}, DAE.AVLTREENODE(NONE, 0, NONE, NONE)));

case (cache,env,{e},impl,st,doVect)
equation
(cache,e_1,prop,_,dae) = elabExp(cache,env, e, impl, st,doVect);
Expand Down

0 comments on commit 5806822

Please sign in to comment.