GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
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 http://www.epm.ornl.gov/pvm.

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!

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`

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

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

        pvm>

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 help.

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
        onyx
        prata.nsrc.nus.sg
        laksa ep=$HOME/perl5/bin

In the above example hostfile we are adding the hosts onyx, prata.nsrc.nus.sg 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 executables.

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 $HOME/bin.

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

        Parallel::Pvm::addhosts("prata","laksa");

Or we can delete a host from our configuration by calling

        Parallel::Pvm::delhosts("laksa");

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";
          }
        }

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.

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 onyx.nsrc.nus.sg by calling

        Parallel::Pvm::spawn("client",1,PvmTaskHost,"onyx.nsrc.nus.sg");

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

        Parallel::Pvm::spawn("client",4,PvmTaskArch,"RS6K");

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

        Parallel::Pvm::spawn("client",4,PvmTaskArch,"RS6K",argv);

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

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");
        Parallel::Pvm::pack(1234);
        Parallel::Pvm::send($dtid,999);

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 example,

        $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 "pvm_packstr").

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

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

        Parallel::Pvm::catchout;

for stdout or

        Parallel::Pvm::catchout(stderr);

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

        Parallel::Pvm::setopt(PvmOutTid,$tid);

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);
        Parallel::Pvm::notify(PvmTaskExit,999,@monitor_task);
        ...

        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:

        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
        Parallel::Pvm::send($serv_tid,$REQUEST);

        # receive service from server
        Parallel::Pvm::recv(-1,$RESPONSE);
        @service_packet = Parallel::Pvm::unpack ;
        ...

Server:

        while(1){
           ...

           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 ;
                 Parallel::Pvm::pack(@service);
                 Parallel::Pvm::send($stid,$RESPONSE);
                 
                 # exit child process
                 exit ;
              }
           }       
           ...
        
        }

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*.

Parallel::Pvm::start_pvmd
Starts pvmd if it's not already running.

        $info = Parallel::Pvm::start_pvmd($block, @args) ;
    
Parallel::Pvm::addhosts
Adds one or more host names to a parallel virtual machine. Eg.

        $info = Parallel::Pvm::addhosts(@host_list) ;
    
Parallel::Pvm::bufinfo
Returns information about the requested message buffer. Eg.

        ($info,$bytes,$tag,$tid) = Parallel::Pvm::bufinfo($bufid);
    
Parallel::Pvm::catchout
Catches output from children tasks. Eg.

        # Parallel::Pvm::catchout(stdout);
        $bufid = Parallel::Pvm::catchout;
    
Parallel::Pvm::config
Returns information about the present virtual machine configuration. Eg.

        ($info,@host_ref_list) = Parallel::Pvm::config ;
    
Parallel::Pvm::delhosts
Deletes one or more hosts from the virtual machine. Eg.

        $info = Parallel::Pvm::delhosts(@host_list);
    
Parallel::Pvm::exit
Tells the local PVM daemon that the process is leaving. Eg.

        $info = Parallel::Pvm::exit ;
    
Parallel::Pvm::freebuf
Disposes of a message buffer. Eg.

        $info = Parallel::Pvm::freebuf($bufid);
    
Parallel::Pvm::getopt
Shows various libpvm options. Eg.

        $val = Parallel::Pvm::getopt(PvmOutputTid);
        $val = Parallel::Pvm::getopt(PvmFragSize);
    
Parallel::Pvm::getrbuf
Returns the message buffer identifier for the active receive buffer. Eg.

        $bufid = Parallel::Pvm::getrbuf ;
    
Parallel::Pvm::getsbuf
Returns the message buffer identifier for the active send buffer. Eg.

        $bufid = Parallel::Pvm::getsbuf ;
    
Parallel::Pvm::halt
Shuts down the entire PVM system. Eg.

        $info = Parallel::Pvm::halt ;
    
Parallel::Pvm::hostsync
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 - remote_clk.

Parallel::Pvm::initsend
Clears default send buffer and specifies message encoding. Eg.

        # Parallel::Pvm::initsend(PvmDataDefault) ;
        $bufid = Parallel::Pvm::initsend
    
Parallel::Pvm::kill
Terminates a specified PVM process.

        $info = Parallel::Pvm::kill($tid);
    
Parallel::Pvm::mcast
Multicast the data in the active message buffer to a set of tasks. Eg.

        $info = Parallel::Pvm::mcast(@tid_list,$tag);
    
Parallel::Pvm::mkbuf
Creates a new message buffer. Eg.

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

        $bufid = Parallel::Pvm::mkbuf(PvmDataRaw);
    
Parallel::Pvm::mstat
Returns the status of a host in the virtual machine. Eg.

        $status = Parallel::Pvm::mstat($host);
    
Parallel::Pvm::mytid
Returns the tid of the calling process.

        $mytid = Parallel::Pvm::mytid ;
    
Parallel::Pvm::notify
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);
    
Parallel::Pvm::nrecv
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) ;
    
Parallel::Pvm::pack
Packs active message buffer with data. Eg.

        $info = Parallel::Pvm::pack(@data_list);
    
Parallel::Pvm::parent
Returns the tid of the process that spawned the calling process. Eg.

        $tid = Parallel::Pvm::parent ;
    
Parallel::Pvm::perror
Prints the error status of the las PVM call.

        $info = Parallel::Pvm::perror($msg);
    
Parallel::Pvm::precv
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.

Parallel::Pvm::probe
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);
    
Parallel::Pvm::psend
Packs and sends data in one call. Eg.

        $info = Parallel::Pvm::psend($tid,$tag,@send_buffer);
    
Parallel::Pvm::pstat
Returns the status of the specified PVM process. Eg.

        $status = Parallel::Pvm::pstat($tid);
    
Parallel::Pvm::recv
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);
    
Parallel::Pvm::recvf
Redefines the comparison function used to accept messages. Eg.

        Parallel::Pvm::recvf(\&new_foo);
    
Parallel::Pvm::recv_notify
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);
    
Parallel::Pvm::recvf_old
Resets the comparison function for accepting messages to the previous method before a call to Parallel::Pvm::recf.
Parallel::Pvm::reg_hoster
Registers this task as responsible for adding new PVM hosts. Eg.

        $info = Parallel::Pvm::reg_hoster ;
    
Parallel::Pvm::reg_rm
Registers this task as a PVM resource manager. Eg.

        $info = Parallel::Pvm::reg_rm ;
    
Parallel::Pvm::reg_tasker
Registers this task as responsible for starting new PVM tasks. Eg.

        $info = Parallel::Pvm::reg_tasker ;
    
Parallel::Pvm::send
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);
    
Parallel::Pvm::sendsig
Sends a signal to another PVM process. Eg.

        use POSIX qw(:signal_h);
        ...

        $info = Parallel::Pvm::sendsig($tid,SIGKILL);
    
Parallel::Pvm::setopt
Sets various libpvm options. Eg.

        $oldval=Parallel::Pvm::setopt(PvmOutputTid,$val);

        $oldval=Parallel::Pvm::setopt(PvmRoute,PvmRouteDirect);
    
Parallel::Pvm::setrbuf
Switches the active receive buffer and saves the previous buffer. Eg.

        $oldbuf = Parallel::Pvm::setrbuf($bufid);
    
Parallel::Pvm::setsbuf
Switches the active send buffer. Eg.

        $oldbuf = Parallel::Pvm::setsbuf($bufid);
    
Parallel::Pvm::spawn
Starts new PVM processes. Eg.

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

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

        ($ntask,@tid_list) = Parallel::Pvm::spawn("compute.pl",4,PvmTaskHost,"onyx",argv);
    
Parallel::Pvm::tasks
Returns information about the tasks running on the virtual machine. Eg.

        # 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) ;
    
Parallel::Pvm::tidtohost
Returns the host ID on which the specified task is running. Eg.

        $dtid = Parallel::Pvm::tidtohost($tid);
    
Parallel::Pvm::trecv
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);
    
Parallel::Pvm::unpack
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, edward@nsrc.nus.sg, National Supercomputing Research Centre, Singapore

Denis Leconte, denis_leconte@geocities.com

Ulrich Pfeifer, pfeifer@wait.de

perl(1), pvm_intro(1PVM)
2005-07-15 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.