[m-rev.] for review: dependent parallel conjunctions

Peter Wang wangp at students.cs.mu.oz.au
Mon Aug 7 19:47:44 AEST 2006


On 2006-08-07, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
> 
> On Tue, 1 Aug 2006, Peter Wang wrote:
> >% predicate P, followed by signals in a conjunction (there must be at 
> >least one
> >% wait or one signal).  If the code of P is available then a specialised
> >% ("parallel") version of P is produced, taking futures in place of any
> >% arguments which need to be waited on or signalled.  For example:
> >%
> >%   wait(FutureX, X),
> >%   p(X, Y),
> >%   impure signal(FutureY, Y)
> >%
> >% would be transformed into:
> >%
> >%   Parallel__p(FutureX, FutureY),
> >%
> >% where the wait and signal calls are now in the body of Parallel__p.
> 
> >% If building in a non-parallel grade then dependent parallel conjunctions
> >% are simply converted into sequential conjunctions.
> 
> Reword as:
> 
> 	In non-parallel grades dependent parallel conjunctions are
> 	treated like sequential conjunctions.

Dependent parallel conjunctions still have the determinism limitation of
parallel conjunctions, so "treated like sequential conjunctions" is too
strong.

> >:- type par_procs
> >   --->    par_procs(done_par_procs, pending_par_procs).
> >
> >:- type done_par_procs ==       map(par_proc_call_pattern, new_par_proc).
> >:- type pending_par_procs ==    assoc_list(par_proc_call_pattern, 
> >new_par_proc).
> 
> Add documentation for these types.
> 
> Perhaps instead of pending_par_proc, requested_par_procs or
> requested_par_spec_procs?

Those would require more line wrapping :-)  Besides, a "request" can be
denied.  In this case they *must* be created as calls have already been
made to the pending procedures.

> >dependent_par_conj(!ModuleInfo, !IO) :-
> >   ModuleInfo0 = !.ModuleInfo,
> 
> Why is it necessary to have multiple copies of the HLDS?  (From the code 
> below
> it looks like what you need is just the pred_table.)

It's also used in add_pending_par_proc_2 for:

    proc_info_get_initial_instmap(!.ProcInfo, ModuleInfo0, InstMap0),

> >process_proc_for_dep_par_conj_with_ignores(PredId, ProcId, IgnoreVars,
> >       !ModuleInfo, !ParProcs, !IO) :-
> >   some [!PredInfo, !ProcInfo, !Body, !VarSet, !VarTypes] (
> >       module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
> >           !:PredInfo, !:ProcInfo),
> >       proc_info_get_goal(!.ProcInfo, !:Body),
> >       proc_info_get_varset(!.ProcInfo, !:VarSet),
> >       proc_info_get_vartypes(!.ProcInfo, !:VarTypes),
> >       proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, InstMap0),
> >
> >       Info0 = dep_par_info(!.ParProcs, !.ModuleInfo,
> >           !.VarSet, !.VarTypes, IgnoreVars),
> >
> >       search_goal_for_par_conj(!Body, InstMap0, _, Info0, Info1),
> >
> >       (if handle_dep_par_conj(!.ModuleInfo) then
> >           replace_sequences_in_goal(!Body, Info1, Info2),
> >           Info2 = dep_par_info(!:ParProcs, !:ModuleInfo,
> >               !:VarSet, !:VarTypes, _IgnoreVars),
> >           rename_apart_in_goal(!.ModuleInfo, !Body, InstMap0,
> >               !VarSet, !VarTypes)
> 
> Introducing fresh variables, by renaming apart, might potentially mean that
> the RTTI varmaps need to be updated.  (I'm pretty sure that isn't the
> case here, but if so there should at least be a comment explaining why it is
> okay not to update them.)

I don't know anything about RTTI.  I'll fix it later if something happens.

> >:- pred add_pending_par_proc_2(pred_proc_id::in, pred_proc_id::in,
> >   list(arg_pos)::in, module_info::in, module_info::in, module_info::out,
> >   par_procs::in, par_procs::out, io::di, io::uo) is det.
> >
> >add_pending_par_proc_2(proc(OldPredId, OldProcId), proc(PredId, ProcId),
> >       FutureArgs, ModuleInfo0, !ModuleInfo, !ParProcs, !IO) :-
> >   some [!VarSet, !VarTypes, !ProcInfo] (
> >       % Get the proc_info from _before_ the dependent parallel conjunction
> >       % pass was ever run, so we get untransformed procedure bodies.
> 
> Why is that necessary?

The transformation just doesn't handle already transformed parallel
conjunctions.  You get things like signals and waits on the same future
in a conjunct, futures of futures, etc.  Comment added.

> >   % Determine if a parallel conjunction is a dependent parallel 
> >   conjunction.
> >   % If so, allocate futures for variables shared between conjuncts.
> >   % Insert wait and signal calls for those futures into the conjuncts.
> >   %
> >:- pred search_goal_for_par_conj(hlds_goal::in, hlds_goal::out,
> >   instmap::in, instmap::out, dep_par_info::in, dep_par_info::out) is det.
> >
> >search_goal_for_par_conj(Goal0, Goal, InstMap0, InstMap, !Info) :-
> >   search_goal_for_par_conj_2(Goal0, Goal, InstMap0, !Info),
> >   update_instmap(Goal0, InstMap0, InstMap).
> >
> 
> Why is it Goal0 not Goal in the first argument to update_instmap?

I think it was a mistake (but actually it shouldn't make a difference).
Changed anyway.

> >   % Succeed if Var is a variable bound between InstMap and
> >   % InstMap+InstMapDelta.
> >   %
> >:- pred produced_variable(module_info::in, instmap::in, instmap_delta::in,
> >   prog_var::in) is semidet.
> >
> >produced_variable(ModuleInfo, InstMap, InstMapDelta, Var) :-
> >   instmap.lookup_var(InstMap, Var, OldVarInst),
> >   inst_is_free(ModuleInfo, OldVarInst),
> >   instmap_delta_search_var(InstMapDelta, Var, VarInst),
> >   inst_is_bound(ModuleInfo, VarInst).
> >
> 
> Consider adding this to instmap.m, as instmap_delta_var_is_bound or 
> something like that.

Ok.

> >   replace_sequences_in_conj_2([], Goals0, Goals, !Info).
> >
> >:- pred replace_sequences_in_conj_2(hlds_goals::in, hlds_goals::in,
> >   hlds_goals::out, dep_par_info::in, dep_par_info::out) is det.
> >
> >replace_sequences_in_conj_2(RevGoals, [], reverse(RevGoals), !Info).
> >replace_sequences_in_conj_2(RevGoals0, [Goal0 | Goals0], Goals, !Info) :-
> >   Goal0 = GoalExpr0 - GoalInfo0,
> >   (if
> >       GoalExpr0 = plain_call(_, _, _, _, _, _),
> >       not is_wait_goal(Goal0),
> >       not is_signal_goal(Goal0)
> >   then
> >       CallGoal0 = GoalExpr0 - GoalInfo0,  % dumb mode system
> 
> If you think the mode system is dumb then fix it ... ;-)

In that case it's really, really smart.

> >
> >   % The comments in this predicate are from unused_args.m
> >   %
> 
> The comments in this predicate shouldn't be from unused_args.m ;-)
> (At the very least that comment needs an XXX on it saying that they
> need to be updated - preferably the actual comments in the predicate
> would be updated.)

They are updated.  See, mine talks about parallelisation rather than
specialisation.

> To be continued ... (could you please post an amended version of the 
> description of the transformation in the comments at the head of the
> module).

I followed your suggestions, but I'm not sure what else there is to say.

Peter

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list