git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@844 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
		
			
				
	
	
		
			141 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
%% demo1_mpe.pl
 | 
						|
%%
 | 
						|
%% This file was originally created on 3/7/2003
 | 
						|
%% by Stasinos Konstantopoulos <konstant@let.rug.nl>
 | 
						|
%% as part of the YAP Prolog distribution.
 | 
						|
%%
 | 
						|
%% This file is in the Public Domain.
 | 
						|
 | 
						|
%% demo1_mpe.pl is the same as demo1.pl, except
 | 
						|
%% that MPE is used to log MPI activity.
 | 
						|
 | 
						|
% make the `floor' operator return integer values
 | 
						|
:- set_prolog_flag(language, iso).
 | 
						|
 | 
						|
 | 
						|
%%
 | 
						|
%% This the calculation that needs to be performed, in this case
 | 
						|
%% the sum of [From..To]
 | 
						|
%%
 | 
						|
 | 
						|
calc(From, From, Acc, Res) :- !,
 | 
						|
	Res is Acc + From.
 | 
						|
calc(From, To, Acc, Res) :- !,
 | 
						|
	Acc1 is Acc + To,
 | 
						|
	To1 is To - 1,
 | 
						|
	calc(From, To1, Acc1, Res).
 | 
						|
 | 
						|
%%
 | 
						|
%% The master node sends teh task definition to
 | 
						|
%% the workers and then collects the results
 | 
						|
%%
 | 
						|
 | 
						|
do(0, NumProc):-
 | 
						|
	!,
 | 
						|
 | 
						|
	% processing state
 | 
						|
	mpe_create_event(Ev1),
 | 
						|
	mpe_create_event(Ev2),
 | 
						|
	mpe_create_state(Ev1,Ev2,processing,green),
 | 
						|
 | 
						|
	% bcasting state
 | 
						|
	mpe_create_event(Ev3),
 | 
						|
	mpe_create_event(Ev4),
 | 
						|
	mpe_create_state(Ev3,Ev4,bcasting,red),
 | 
						|
 | 
						|
	% sending/recving state
 | 
						|
	mpe_create_event(Ev5),
 | 
						|
	mpe_create_event(Ev6),
 | 
						|
	mpe_create_state(Ev5,Ev6,'sending/receiving',brown),
 | 
						|
 | 
						|
	% pretend that the other nodes do not have
 | 
						|
	% access to the task definition.
 | 
						|
	% retrieve it and broadcast it.
 | 
						|
	get_value(from, From),
 | 
						|
	get_value(to, To),
 | 
						|
	mpe_log(Ev3,0,event3),
 | 
						|
	mpi_bcast(msg(From,To), 0),
 | 
						|
	mpe_log(Ev4,0,event4),
 | 
						|
 | 
						|
	% loop to collect and accumulate partial results
 | 
						|
	% from the workers
 | 
						|
	set_value(n, NumProc),
 | 
						|
	set_value(acc, 0),
 | 
						|
	repeat,
 | 
						|
	  mpe_log(Ev5,0,event5),
 | 
						|
	  mpi_receive(T, Source, Tag),
 | 
						|
	  mpe_log(Ev6,0,event6),
 | 
						|
	  format( '0: Proc ~q said: ~q (Tag: ~q)~n', [Source,T,Tag] ),
 | 
						|
	  % accumulate results
 | 
						|
	  get_value(acc, Acc),
 | 
						|
	  NewAcc is Acc + T,
 | 
						|
	  set_value(acc, NewAcc),
 | 
						|
	  % processors still left
 | 
						|
	  get_value(n, Counter),
 | 
						|
	  NewCounter is Counter - 1,
 | 
						|
	  set_value(n, NewCounter),
 | 
						|
	  NewCounter == 1,
 | 
						|
	!,
 | 
						|
	format('0: Sum(~q..~q) = ~q.~n', [From,To,NewAcc]).
 | 
						|
 | 
						|
 | 
						|
%%
 | 
						|
%% The workers hear from the master what needs to
 | 
						|
%% be done, do the work and then send the results back.
 | 
						|
%%
 | 
						|
 | 
						|
do(Rank, NumProc):-
 | 
						|
	!,
 | 
						|
 | 
						|
	% processing state
 | 
						|
	mpe_create_event(Ev1),
 | 
						|
	mpe_create_event(Ev2),
 | 
						|
	mpe_create_state(Ev1,Ev2,processing,green),
 | 
						|
 | 
						|
	% bcasting state
 | 
						|
	mpe_create_event(Ev3),
 | 
						|
	mpe_create_event(Ev4),
 | 
						|
	mpe_create_state(Ev3,Ev4,bcasting,red),
 | 
						|
 | 
						|
	% sending/recving state
 | 
						|
	mpe_create_event(Ev5),
 | 
						|
	mpe_create_event(Ev6),
 | 
						|
	mpe_create_state(Ev5,Ev6,'sending/receiving',brown),
 | 
						|
 | 
						|
	% catch the task broadcast
 | 
						|
	mpe_log(Ev3,0,event3),
 | 
						|
	mpi_bcast(Msg, 0),
 | 
						|
	mpe_log(Ev4,0,event4),
 | 
						|
	Msg = msg(From,To),
 | 
						|
	format( '~q: All are calculating ~q..~q.~n', [Rank,From,To] ),
 | 
						|
	MyFrom is floor(To * (Rank - 1) / (NumProc - 1)) + From,
 | 
						|
	MyTo is floor(To * Rank / (NumProc - 1)) + From - 1,
 | 
						|
	format( '~q: I am calculating ~q..~q.~n', [Rank,MyFrom,MyTo] ),
 | 
						|
	% do the job
 | 
						|
	mpe_log(Ev1,0,event1),
 | 
						|
	calc( MyFrom, MyTo, 0, Result ),
 | 
						|
	mpe_log(Ev2,0,event2),
 | 
						|
	format( '~q: sending ~q to 0. (Tag: 1)~n', [Rank,Result] ),
 | 
						|
	% send back the results
 | 
						|
	mpe_log(Ev5,0,event5),
 | 
						|
	mpi_send(Result, 0, 1),
 | 
						|
	mpe_log(Ev6,0,event6).
 | 
						|
 | 
						|
 | 
						|
%%
 | 
						|
%% This is the entry point
 | 
						|
%%
 | 
						|
 | 
						|
start(From, To):-
 | 
						|
	% store the task definition
 | 
						|
	set_value(from, From),
 | 
						|
	set_value(to, To),
 | 
						|
 | 
						|
	mpi_open(Rank, NumProc, ProcName),
 | 
						|
	format('Rank: ~q NumProc: ~q, ProcName: ~q~n', [Rank,NumProc,ProcName]),
 | 
						|
	mpe_open,
 | 
						|
	do(Rank, NumProc),
 | 
						|
	format( 'Rank ~q finished!~n', [Rank] ),
 | 
						|
	mpe_close( demo1_mpe ),
 | 
						|
	mpi_close.
 |