Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Pvm(3)		      User Contributed Perl Documentation		Pvm(3)

       Parallel::Pvm - Perl extension for the Parallel Virtual Machine (PVM)
       Message Passing System

	 use Parallel::Pvm;

       The PVM message passing system enables a	programmer to configure	a
       group of	(possibly heterogenous)	computers connected by a network into
       a parallel virtual machine.  The	system was developed by	the University
       of Tennessee, Oak Ridge National	Laboratory and Emory University.

       Using PVM, applications can be developed	which spawns parallel
       processes onto nodes in the virtual machine to perform specific tasks.
       These parallel tasks can	also periodically exchange information using a
       set of message passing functions	developed for the system.

       PVM applications	have mostly been developed in the scientific and
       engineering fields.  However applications for real-time and
       client/server systems can also be developed.  PVM simply	provides a
       convenient way for managing parallel tasks and communications without
       need for	rexec or socket	level programming.

       As a utility, PVM enables an organisation to leverage on	the computers
       already available for parallel processing.  Parallel applications can
       be started during non-peak hours	to utilise idle	CPU cycles.  Or
       dedicated workstation clusters connected	via a high performance network
       like ATM	can be used for	high performance computing.

       It is recommended that you read the PVM manual pages and	the book "PVM:
       Parallel	Virtual	Machine, A users's guide and tutorial for networked
       parallel	computing".  Both the PVM system and the book can be obtained
       from the	HTTP address

       For the rest of this document we	will provide a tutorial	introduction
       to developing PVM applications using perl.  The interface for some of
       the PVM functions have been changed of course to	give it	a more perl-
       like feel.

       Remember	think perl think parallel!  Good Luck!

   Environment Variables
       After installing	PVM on your computer, there are	two mandatory
       environment variables that have to be set in your .login	or .cshrc
       files; PVM_ROOT and PVM_ARCH.  PVM_ROOT points to the base of the PVM
       installation directory, and PVM_ARCH specifies the architecture of the
       computer	on which PVM is	running.   An example of how this can be set
       for csh is shown	below,

	       setenv PVM_ROOT /usr/local/pvm3
	       setenv PVM_ARCH `$PVM_ROOT/lib/pvmgetarch`

   Setting up your rsh permission
       In order	for PVM	applications to	run, rsh permission has	to be enabled.
       This involves creating a	.rhosts	file in	your HOME directory
       containing, for each line, the host and account name you	wish to	allow
       remote execution	privillages.  An example .rhosts file to allow a PVM
       application to remotely execute on the host onyx	and prata using	the
       account edward is shown below,

	       onyx    edward
	       prata   edward

   Configuring your parallel virtual machine
       Parallel	process	management and communications is handled by a set of
       distributed deamons running on each of the nodes	of the virtual
       machine.	 The daemon executable,	pvmd, is started when a	computer is
       added to	the virtual machine.  A	computer can be	added to the virtual
       machine either statically in a console program or using a hostfile, or
       dynamically within the application code itself.

       The first method	of configuring your virtual machine is to use the
       console program $PVM_ROOT/lib/pvm.  Run it from the command prompt.
       The console program will	first add the local host into the virtual
       machine and display the prompt


       To add a	host, eg onyx, as a node in your parallel virtual machine,
       simply type

	       pvm> add	onyx

       To display the current virtual machine configuration type

	       pvm> conf

       which will display node information pertaining to the host name,	host
       id, host	architecture, relative speed and data format.  The console
       program has a number of other commands which can	be viewed by typing

       The second method of configuring	your virtual machine is	to use a
       hostfile.   The hostfile	is simply an ASCII text	file specifing the
       host names of the computers to be added into your virtual machine.

       Additional options may be also be defined for the nodes pertaining to
       the working directory, execution	path, login name, alternative hostname
       etc. A simple example of	a hostfile is shown below.

	       * wd=$HOME/work ep=$HOME/bin
	       laksa ep=$HOME/perl5/bin

       In the above example hostfile we	are adding the hosts onyx, and laksa into	the virtual machine. We	are also
       specifying the working directory, wd, in	which we want our application
       to run, and the execution path, ep, in which we want PVM	to look	for

       The * in	the first line defines a global	option for all the hosts
       specified after it.  We can however provide an option locally to	over-
       ride this global	option.	 This is seen for the host laksa where we have
       specified its execution path to be $HOME/perl5/bin instead of the

       The third method	of configuring your virtual machine is to call the
       functions Parallel::Pvm::addhosts or Parallel::Pvm::delhosts within
       your application.  You must still start your master pvmd	daemon first.
       This can	be achieved by starting	pvm and	typing quit or simply typing

	       echo quit | pvm

       The PVM application can then be started where we	can add	the hosts
       prata and laksa by calling


       Or we can delete	a host from our	configuration by calling


       PVM also	provides a function, Parallel::Pvm::conf, to query the
       configuration of	the parallel virtual machine. An example code to check
       the current configuration is shown below.

	       ($info,@conf) = Parallel::Pvm::conf ;
	       if ( $info == PvmOk ){
		 foreach $node (@conf){
		  print	"host id = $node->{'hi_tid'}\n";
		  print	"host name = $node->{'hi_name'}\n";
		  print	"host architecture = $node->{'hi_arch'}\n";
		  print	"host speed = $node->{'hi_speed'}\n";

   Enrolling a task into PVM
       A task has to expilictly	enroll into PVM	in order for it	to be known by
       other PVM tasks.	 This can often	be done	by the call

	       $mytid =	Parallel::Pvm::mytid ;

       where $mytid is the task	id, TID, assigned by the PVM system to the
       calling process.	 Note however that calling any PVM function in a
       program will also enroll	it into	the system.

   Spawning parallel tasks
       A PVM application can spawn parallel tasks in your parallel virtual
       machine.	 Assuming there	is exists an executable	called client, we can
       spawn four client tasks in our virtual machine by calling

	       ($ntask,@tids) =	Parallel::Pvm::spawn("client",4);

       For each	of the four spawned processes, the PVM system first allocates
       a host node and looks for the executable	in the execuation path of that
       host.  If the executable	is found it is started.

       The task	which called the Parallel::Pvm::spawn is known as the parent
       task.  The number of children tasks which are actually spawned by
       Parallel::Pvm::spawn is returned	in the scalar $ntask.  The @tids array
       returns the task	id, TID, of the	spawned	children tasks which will be
       useful later for	communicating with them.  A TID	< 0 indicates a	task
       failure to spawn	and can	be used	to determine the nature	of the
       problem.	 Eg.

	       foreach $tid (@tids){
		  if ( $tid < 0	){
		     if	( $tid == PvmNoMem )
			warn "no memory	! \n";
		     }else if (	$tid ==	PvmSysErr ){
			warn "pvmd not responding ! \n";
		     } ...


       For more	sophisticated users, Parallel::Pvm::spawn may be given
       additional argument parameters to control how/where you want a task to
       be spawned.  For	example, you can specifically spawn client in the
       internet	host by calling


       Or you can spawn	client on host nodes only of a particular
       architecture, say RS6K workstations, by calling


       Also, if	the spawned remote executable requires an argument argv, you
       can supply this by calling


       Note that tasks which have been spawned by using	Parallel::Pvm::spawn
       do not need to be explicitly enrolled into the pvm system.

   Exchanging messages between tasks
       Messages	can be sent to a task enrolled into PVM	by specifying the
       example code sequence

	       Parallel::Pvm::initsend ;
	       Parallel::Pvm::pack(2.345,"hello	dude");

       In our example we first call Parallel::Pvm::initsend to initialize the
       internal	PVM send buffer.  We then call Parallel::Pvm::buffer to	fill
       this buffer with	a double (2.345), a string ("hello dude"), and an
       integer (1234) <b>Actually, currently all arguments are converted to
       strings</b>.  Having filled the send buffer with	the data that is to be
       sent, we	call Parallel::Pvm::send to do the actual send to the task
       identifed by the	TID $dtid.  We also label the sending message to
       disambiguate it with other messages with	a tag.	This is	done with the
       999 argument in Parallel::Pvm::send function.

       For the destination task, we can	receive	the message sent by performing
       a blocking receive with the function Parallel::Pvm::recv.  A code
       sequence	for the	above example on the recipent end will be

	       if ( Parallel::Pvm::recv	>= 0 ){
		  $int_t = Parallel::Pvm::unpack ;
		  ($double_t,$str_t) = Parallel::Pvm::unpack ;

       Note that we must unpack	the message in the reverse order in which we
       packed our message.  In our example Parallel::Pvm::recv will receive
       any message sent	to it.	In order to selectively	receive	a message, we
       could specify the TID of	the source task	and the	message	tag.  For

	       $tag = 999;
	       Parallel::Pvm::recv($stid,$tag) ;

       Caveats:	Messages may not contain the vertical tab character "\v". If
       you pass	messages to programs written in	other languages, you need to
       know that "Parallel::Pvm::pack" packs everything	as strings (with

       Other message passing functions that you	may find useful	are
       Parallel::Pvm::psend, Parallel::Pvm::trecv, Parallel::Pvm::nrecv	and

   Parallel I/O
       Note that the file descriptors in a parent task are not inherented in
       the spawned children tasks unlike fork.	By default any file I/O	will
       be performed in the working directory specified in the hostfile if no
       absolute	path was provided for the opened file.	If no working
       directory is specified, the default is the $HOME	directory.  For
       directories which are not NFS mounted, this would mean that each	task
       performs	its own	separate I/O.

       In the case of tty output, tasks	which are not started from the command
       prompt will have	their stdout and stderr	directed to the	file
       pvml.<uid>.  This may be	redirected to a	parent task by calling


       for stdout or


       for stderr.   You can direct the	stdout or stderr output	of a task to
       another TID , other then	its parent, by calling


   Incorporating fault tolerance
       The function Parallel::Pvm::notify can be used to incorporate some
       fault tolerance into your PVM application.  You may use it to ask the
       PVM to monitor the liveliness of	a set of hosts or tasks	during the
       execution of a PVM application.	For example you	can instrument your
       application to monitor 3	tasks with TID $task1, $task2, and $task3, by
       using the code segments

	       @monitor	= ($task1,$task2,$task3);

	       if ( Parallel::Pvm::probe(-1,999) ){
		  $task	= Parallel::Pvm::recv_notify ;
		  print	"Oops! task $task has failed ... \n" ;

       If either $task1, $task2	or $task3 fails,  the notification will	take
       the form	of a single message with the tag 999.  The message content
       will inform you of the TID of the failed	task.

       A similar scheme	may be employed	for the	notification of	host failures
       in your parallel	virtual	machine.

   Client/Server example

	       use Pvm;
	       use File::Basename;

	       # Look for server tid and assume
	       # server	name is	'service_provider'

	       @task_list = Parallel::Pvm::tasks ;
	       foreach $task (@task_list){
		  $a_out = $task->{'ti_a_out'} ;
		  $base	= basename $a_out ;
		  if ( $base eq	'service_provider' )
		       $serv_tid = $task->{'ti_tid'} ;

	       # This is just one way (not necessarily the
	       # best) of getting a server tid.
	       # You could do the same thing by	reading
	       # the server tid	posted in a file.


	       # send request for service

	       # receive service from server
	       @service_packet = Parallel::Pvm::unpack ;



		  if ( Parallel::Pvm::probe(-1,$REQUEST) ){

		     # a service request has arrived !
		     $bufid = Parallel::Pvm::recv ;
		     ($info,$bytes,$tag,$stid) = Parallel::Pvm::bufinfo($bufid)	;

		     if	( fork == 0 ){
			# fork child process to	handle service

			# provide service
			Parallel::Pvm::initsend	;

			# exit child process
			exit ;


   PVM groups
       The PVM dynamic group functions have not	completely been	ported to Perl
       yet.  We	do not support pvm_scatter, pvm_gather,	and pvm_reduce
       currently.  This	is connected to	the limited datatype support in	the
       rest of the Perl	interface.

       The group functions provide facilities for collecting processes under a
       single group label, and applying	aggregate operations onto them.
       Examples	of these functions are Parallel::Pvm::barrier,
       Parallel::Pvm::reduce, Parallel::Pvm::bcast etc.	 One of	our concerns
       is that these group functions may be changed or augmented in the	future
       releases	of PVM 3.4*.

	   Starts pvmd if it's not already running.

		   $info = Parallel::Pvm::start_pvmd($block, @args) ;

	   Adds	one or more host names to a parallel virtual machine. Eg.

		   $info = Parallel::Pvm::addhosts(@host_list) ;

	   Returns information about the requested message buffer. Eg.

		   ($info,$bytes,$tag,$tid) = Parallel::Pvm::bufinfo($bufid);

	   Catches output from children	tasks.	Eg.

		   # Parallel::Pvm::catchout(stdout);
		   $bufid = Parallel::Pvm::catchout;

	   Returns information about the present virtual machine
	   configuration. Eg.

		   ($info,@host_ref_list) = Parallel::Pvm::config ;

	   Deletes one or more hosts from the virtual machine. Eg.

		   $info = Parallel::Pvm::delhosts(@host_list);

	   Tells the local PVM daemon that the process is leaving.  Eg.

		   $info = Parallel::Pvm::exit ;

	   Disposes of a message buffer. Eg.

		   $info = Parallel::Pvm::freebuf($bufid);

	   Shows various libpvm	options.  Eg.

		   $val	= Parallel::Pvm::getopt(PvmOutputTid);
		   $val	= Parallel::Pvm::getopt(PvmFragSize);

	   Returns the message buffer identifier for the active	receive
	   buffer. Eg.

		   $bufid = Parallel::Pvm::getrbuf ;

	   Returns the message buffer identifier for the active	send buffer.

		   $bufid = Parallel::Pvm::getsbuf ;

	   Shuts down the entire PVM system. Eg.

		   $info = Parallel::Pvm::halt ;

	   Gets	time-of-day clock from PVM host. Eg.

		   ($info,$remote_clk,$delta) =	Parallel::Pvm::hostsync($host) ;

	   where delta is the time-of-day equivalent to	local_clk -

	   Clears default send buffer and specifies message encoding. Eg.

		   # Parallel::Pvm::initsend(PvmDataDefault) ;
		   $bufid = Parallel::Pvm::initsend

	   Terminates a	specified PVM process.

		   $info = Parallel::Pvm::kill($tid);

	   Multicast the data in the active message buffer to a	set of tasks.

		   $info = Parallel::Pvm::mcast(@tid_list,$tag);

	   Creates a new message buffer. Eg.

		   # Parallel::Pvm::mkbuf(PvmDataDefault);
		   $bufid = Parallel::Pvm::mkbuf ;

		   $bufid = Parallel::Pvm::mkbuf(PvmDataRaw);

	   Returns the status of a host	in the virtual machine.	 Eg.

		   $status = Parallel::Pvm::mstat($host);

	   Returns the tid of the calling process.

		   $mytid = Parallel::Pvm::mytid ;

	   Requests notification of PVM	events.	Eg.

		   $info = Parallel::Pvm::notify(PvmHostDelete,999,$host_list);

		   # turns on notification for new host
		   $info = Parallel::Pvm::notify(PvmHostAdd);

		   # turns off notification for	new host
		   $info = Parallel::Pvm::notify(PvmHostAdd,0);

	   Nonblocking receive.	 Eg.

		   # Parallel::Pvm::nrecv(-1,-1);
		   $bufid = Parallel::Pvm::nrecv ;

		   # Parallel::Pvm::nrecv($tid,-1);
		   $bufid = Parallel::Pvm::nrecv($tid) ;

		   $bufid = Parallel::Pvm::nrecv($tid,$tag) ;

	   Packs active	message	buffer with data. Eg.

		   $info = Parallel::Pvm::pack(@data_list);

	   Returns the tid of the process that spawned the calling process.

		   $tid	= Parallel::Pvm::parent	;

	   Prints the error status of the las PVM call.

		   $info = Parallel::Pvm::perror($msg);

	   Receives a message directly into a buffer.

		   # Parallel::Pvm::precv(-1,-1);
		   @recv_buffer	= Parallel::Pvm::precv ;

		   # Parallel::Pvm::precv($tid,-1);
		   @recv_buffer	= Parallel::Pvm::precv($tid);

		   @recv_buffer	= Parallel::Pvm::precv($tid,$tag);

	   Note	that the current limit for the receive buffer is 100 KBytes
	   unless you specify a	third argument overwriting this	limit.

	   Checks whether a message has	arrived.  Eg.

		   # Parallel::Pvm::probe(-1,-1);
		   $bufid = Parallel::Pvm::probe ;

		   # Parallel::Pvm::probe($tid,-1);
		   $bufid = Parallel::Pvm::probe($tid);

		   $bufid = Parallel::Pvm::probe($tid,$tag);

	   Packs and sends data	in one call.  Eg.

		   $info = Parallel::Pvm::psend($tid,$tag,@send_buffer);

	   Returns the status of the specified PVM process.  Eg.

		   $status = Parallel::Pvm::pstat($tid);

	   Receives a message.	Eg.

		   # Parallel::Pvm::recv(-1,-1);
		   $bufid = Parallel::Pvm::recv	;

		   # Parallel::Pvm::recv($tid,-1);
		   $bufid = Parallel::Pvm::recv($tid) ;

		   $bufid = Parallel::Pvm::recv($tid,$tag);

	   Redefines the comparison function used to accept messages.  Eg.


	   Receives the	notification message initiated by
	   Parallel::Pvm::notify.  This	should be preceded by a
	   Parallel::Pvm::probe.  Eg.

		   # for PvmTaskExit and PvmHostDelete notification
		   if (	Parallel::Pvm::probe(-1,$notify_tag) ){
			   $message = Parallel::Pvm::recv_notify(PvmTaskExit) ;

		   # for PvmHostAdd notification
		   @htid_list =	Parallel::Pvm::recv_notify(PvmHostAdd);

	   Resets the comparison function for accepting	messages to the
	   previous method before a call to Parallel::Pvm::recf.

	   Registers this task as responsible for adding new PVM hosts.	 Eg.

		   $info = Parallel::Pvm::reg_hoster ;

	   Registers this task as a PVM	resource manager.  Eg.

		   $info = Parallel::Pvm::reg_rm ;

	   Registers this task as responsible for starting new PVM tasks.  Eg.

		   $info = Parallel::Pvm::reg_tasker ;

	   Send	the data in the	active message buffer.	Eg.

		   # Parallel::Pvm::send(-1,-1);
		   $info = Parallel::Pvm::send ;

		   # Parallel::Pvm::send($tid,-1);
		   $info = Parallel::Pvm::send($tid);

		   $info = Parallel::Pvm::send($tid,$tag);

	   Sends a signal to another PVM process.  Eg.

		   use POSIX qw(:signal_h);

		   $info = Parallel::Pvm::sendsig($tid,SIGKILL);

	   Sets	various	libpvm options.	 Eg.



	   Switches the	active receive buffer and saves	the previous buffer.

		   $oldbuf = Parallel::Pvm::setrbuf($bufid);

	   Switches the	active send buffer.  Eg.

		   $oldbuf = Parallel::Pvm::setsbuf($bufid);

	   Starts new PVM processes.  Eg.

		   # Parallel::Pvm::spawn("",4,PvmTaskDefault,"");
		   ($ntask,@tid_list) =	Parallel::Pvm::spawn("",4);

		   ($ntask,@tid_list) =	Parallel::Pvm::spawn("",4,PvmTaskHost,"onyx");

		   ($ntask,@tid_list) =	Parallel::Pvm::spawn("",4,PvmTaskHost,"onyx",argv);

	   Returns information about the tasks running on the virtual machine.

		   # Parallel::Pvm::tasks(0); Returns all tasks
		   ($info,@task_list) =	Parallel::Pvm::tasks ;

		   # Returns only for task $tid
		   ($info,@task_list) =	Parallel::Pvm::tasks($tid) ;

	   Returns the host ID on which	the specified task is running.	Eg.

		   $dtid = Parallel::Pvm::tidtohost($tid);

	   Receive with	timeout.  Eg.

		   # Parallel::Pvm::trecv(-1,-1,1,0); time out after 1 sec
		   $bufid = Parallel::Pvm::trecv ;

		   # time out after 2*1000000 +	5000 usec
		   $bufid = Parallel::Pvm::trecv($tid,$tag,2,5000);

	   Unpacks the active receive message buffer.  Eg.

		   @recv_buffer	= Parallel::Pvm::unpack	;

	   An optional integer argument	gives the maximum message size to
	   unpack.  Default is 100_000 bytes.

       Edward Walker,, National Supercomputing Research
       Centre, Singapore

       Denis Leconte,

       Ulrich Pfeifer,

       perl(1),	pvm_intro(1PVM)

perl v5.32.1			  2005-07-15				Pvm(3)


Want to link to this manual page? Use this URL:

home | help