141 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			141 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								%% 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.
							 |