Skip to content

Commit

Permalink
+ added a new scope for parfor to handle it differently from normal f…
Browse files Browse the repository at this point in the history
…or loop scope.

+ fix for non-built-in parallel function attributes.

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@12656 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
mahge committed Aug 23, 2012
1 parent 32bd993 commit d377315
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 10 deletions.
13 changes: 10 additions & 3 deletions Compiler/FrontEnd/Env.mo
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,11 @@ end emptyCache;

public constant String forScopeName="$for loop scope$" "a unique scope used in for equations";
public constant String forIterScopeName="$foriter loop scope$" "a unique scope used in for iterators";
public constant String parForScopeName="$pafor loop scope$" "a unique scope used in parfor loops";
public constant String parForIterScopeName="$parforiter loop scope$" "a unique scope used in parfor iterators";
public constant String matchScopeName="$match scope$" "a unique scope used by match expressions";
public constant String caseScopeName="$case scope$" "a unique scope used by match expressions; to be removed when local decls are deprecated";
public constant list<String> implicitScopeNames={forScopeName,forIterScopeName,matchScopeName,caseScopeName};
public constant list<String> implicitScopeNames={forScopeName,forIterScopeName,parForScopeName,parForIterScopeName,matchScopeName,caseScopeName};

// functions for dealing with the environment

Expand Down Expand Up @@ -295,7 +297,7 @@ algorithm
end matchcontinue;
end inForLoopScope;

public function inForIterLoopScope "returns true if environment has a frame that is a for iterator 'loop'"
public function inForOrParforIterLoopScope "returns true if environment has a frame that is a for iterator 'loop'"
input Env env;
output Boolean res;
algorithm
Expand All @@ -306,10 +308,15 @@ algorithm
equation
true = stringEq(name, forIterScopeName);
then true;

case(FRAME(optName = SOME(name))::_)
equation
true = stringEq(name, parForIterScopeName);
then true;

case(_) then false;
end matchcontinue;
end inForIterLoopScope;
end inForOrParforIterLoopScope;

public function stripForLoopScope "strips for loop scopes"
input Env inEnv;
Expand Down
8 changes: 8 additions & 0 deletions Compiler/FrontEnd/Inst.mo
Original file line number Diff line number Diff line change
Expand Up @@ -17180,6 +17180,14 @@ algorithm
purity = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure");
then (DAE.FUNCTION_ATTRIBUTES(inlineType,purity,DAE.FUNCTION_BUILTIN(SOME(name)),DAE.FP_PARALLEL_FUNCTION()));

//parallel functions: non-builtin
case (SCode.CLASS(restriction=SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION())),_)
equation
inlineType = isInlineFunc2(cl);
isBuiltin = Util.if_(SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_BuiltinPtr"), DAE.FUNCTION_BUILTIN_PTR(), DAE.FUNCTION_NOT_BUILTIN());
purity = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure");
then DAE.FUNCTION_ATTRIBUTES(inlineType,purity,isBuiltin,DAE.FP_PARALLEL_FUNCTION());

//kernel functions: never builtin and never inlined.
case (SCode.CLASS(restriction=SCode.R_FUNCTION(SCode.FR_KERNEL_FUNCTION())),_)
then DAE.FUNCTION_ATTRIBUTES(DAE.NO_INLINE(),true,DAE.FUNCTION_NOT_BUILTIN(),DAE.FP_KERNEL_FUNCTION());
Expand Down
20 changes: 18 additions & 2 deletions Compiler/FrontEnd/InstSection.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,22 @@ algorithm
newEnv := Env.extendFrameForIterator(newEnv, iterName, iterType, DAE.UNBOUND(), iterVariability, constOfForIteratorRange);
end addForLoopScope;

protected function addParForLoopScope
"Adds a scope to the environment used in for loops.
adrpo NOTE:
The variability of the iterator SHOULD
be determined by the range constantness!"
input Env.Env env;
input Ident iterName;
input DAE.Type iterType;
input SCode.Variability iterVariability;
input Option<DAE.Const> constOfForIteratorRange;
output Env.Env newEnv;
algorithm
newEnv := Env.openScope(env, SCode.NOT_ENCAPSULATED(), SOME(Env.parForScopeName), NONE());
newEnv := Env.extendFrameForIterator(newEnv, iterName, iterType, DAE.UNBOUND(), iterVariability, constOfForIteratorRange);
end addParForLoopScope;

public function instEqEquation "function: instEqEquation
author: LS, ELN
Equations follow the same typing rules as equality expressions.
Expand Down Expand Up @@ -4861,7 +4877,7 @@ algorithm
t = getIteratorType(t,i,info);
(cache, e_1) = Ceval.cevalRangeIfConstant(cache, env, e_1, prop, impl, info);
(cache,e_2) = PrefixUtil.prefixExp(cache,env, ih, e_1, pre);
env_1 = addForLoopScope(env, i, t, SCode.VAR(), SOME(cnst));
env_1 = addParForLoopScope(env, i, t, SCode.VAR(), SOME(cnst));
(cache,sl_1) = instStatements(cache, env_1, ih, pre, ci_state, sl, source, initial_, impl, unrollForLoops);

// this is where we check the parfor loop for data parallel specific
Expand Down Expand Up @@ -4894,7 +4910,7 @@ algorithm
t = getIteratorType(t,i,info);
(cache, e_1) = Ceval.cevalRangeIfConstant(cache, env, e_1, prop, impl, info);
(cache,e_2) = PrefixUtil.prefixExp(cache, env, ih, e_1, pre);
env_1 = addForLoopScope(env, i, t, SCode.VAR(), SOME(cnst));
env_1 = addParForLoopScope(env, i, t, SCode.VAR(), SOME(cnst));
(cache,sl_1) = instStatements(cache,env_1,ih,pre,ci_state,sl,source,initial_,impl,unrollForLoops);
source = DAEUtil.addElementSourceFileInfo(source,info);
stmt = Algorithm.makeFor(i, e_2, prop, sl_1, source);
Expand Down
32 changes: 27 additions & 5 deletions Compiler/FrontEnd/Static.mo
Original file line number Diff line number Diff line change
Expand Up @@ -7804,9 +7804,11 @@ algorithm

// If we have a function call in an implicit scope type, then go
// up recursively to find the actuall scope and then check.
// But parfor scope is a parallel type so is handled differently.
case(_,_,_, Env.FRAME(optName = SOME(scopeName))::restFrames, _)
equation
true = listMember(scopeName, Env.implicitScopeNames);
false = stringEq(scopeName, Env.parForScopeName);
then isValidWRTParallelScope(inFn,isBuiltin,inFuncParallelism,restFrames,inInfo);

// This two are common cases so keep them at the top.
Expand All @@ -7831,7 +7833,7 @@ algorithm
then false;


//parallel function call in a parallel scope (kernel function, parallel function, or parfor) is OK.
// parallel function call in a parallel scope (kernel function, parallel function) is OK.
// Except when it is calling itself, recurssion
case(_,_,DAE.FP_PARALLEL_FUNCTION(), Env.FRAME(optName = SOME(scopeName), optType = SOME(Env.PARALLEL_SCOPE()))::_, _)
equation
Expand All @@ -7857,6 +7859,11 @@ algorithm
{errorString}, inInfo);
then false;

// parallel function call in a parfor scope is OK.
case(_,_,DAE.FP_PARALLEL_FUNCTION(), Env.FRAME(optName = SOME(scopeName))::_, _)
equation
true = stringEqual(scopeName, Env.parForScopeName);
then true;

//parallel function call in non parallel scope types is error.
case(_,_,DAE.FP_PARALLEL_FUNCTION(),Env.FRAME(optName = SOME(scopeName))::_,_)
Expand Down Expand Up @@ -7887,7 +7894,7 @@ algorithm
{errorString}, inInfo);
then false;

//kernel function call in a parallel scope (kernel function, parallel function, or parfor) is Error.
//kernel function call in a parallel scope (kernel function, parallel function) is Error.
case(_,_,DAE.FP_KERNEL_FUNCTION(), Env.FRAME(optName = SOME(scopeName), optType = SOME(Env.PARALLEL_SCOPE()))::_, _)
equation
errorString = "\n" +&
Expand All @@ -7901,6 +7908,21 @@ algorithm
{errorString}, inInfo);
then false;

//kernel function call in a parfor loop is Error too (similar to above). just different error message.
case(_,_,DAE.FP_KERNEL_FUNCTION(), Env.FRAME(optName = SOME(scopeName))::_, _)
equation
true = stringEqual(scopeName, Env.parForScopeName);
errorString = "\n" +&
"- Kernel function '" +& Absyn.pathString(inFn) +&
"' can not be called from inside parallel for (parfor) loop body." +& "'.\n" +&
"- Kernel functions CAN NOT be called from: 'kernel' functions," +&
" 'parallel' functions or from a body of a" +&
" 'parfor' loop"
;
Error.addSourceMessage(Error.PARMODELICA_ERROR,
{errorString}, inInfo);
then false;

// Kernel function call in a non-parallel scope is OK.
// Except when it is calling itself, recurssion
case(_,_,DAE.FP_KERNEL_FUNCTION(), Env.FRAME(optName = SOME(scopeName))::_, _)
Expand Down Expand Up @@ -11643,7 +11665,7 @@ algorithm
// treated in this way.
case (_, _, _, _, _, _, _, _)
equation
true = Env.inForIterLoopScope(inEnv);
true = Env.inForOrParforIterLoopScope(inEnv);
true = Expression.dimensionKnown(inDimension);
then
(inCache, inSubscript);
Expand Down Expand Up @@ -12021,7 +12043,7 @@ algorithm
case (cache,env,e1,e2,e3,DAE.C_PARAM(),impl,st,_) then (cache,DAE.IFEXP(e1,e2,e3));
case (cache,env,e1,e2,e3,DAE.C_CONST(),impl,st,_)
equation
msg = Util.if_(Env.inFunctionScope(env) or Env.inForIterLoopScope(env), Ceval.NO_MSG(), Ceval.MSG(inInfo));
msg = Util.if_(Env.inFunctionScope(env) or Env.inForOrParforIterLoopScope(env), Ceval.NO_MSG(), Ceval.MSG(inInfo));
(cache,Values.BOOL(cond),_) = Ceval.ceval(cache,env, e1, impl, st,msg);
res = Util.if_(cond, e2, e3);
then
Expand All @@ -12030,7 +12052,7 @@ algorithm
// the stupid Lookup which instantiates packages without modifiers.
case (cache,env,e1,e2,e3,DAE.C_CONST(),impl,st,_)
equation
true = Env.inFunctionScope(env) or Env.inForIterLoopScope(env);
true = Env.inFunctionScope(env) or Env.inForOrParforIterLoopScope(env);
then
(cache, DAE.IFEXP(e1, e2, e3));

Expand Down

0 comments on commit d377315

Please sign in to comment.