












 






<!doctype linuxdoc system>
<book>

<title> S-Lang PVM Module Reference
<author> John C. Houck, <tt>houck@space.mit.edu</tt>
<date> Oct 28, 2005

<toc>

<chapt>Introduction to the PVM Module<p>

 PVM (Parallel Virtual Machine) is a software package which
 permits a heterogeneous collection of Unix and/or Windows
 computers, connected by a network, to be used as a single
 large parallel computer.  The <tt>PVM</tt> module provides a
 <bf>S-lang</bf> interface to this package. By performing distributed
 computations with <bf>S-lang</bf> one can make better use of available
 computer resources yet still retain the advantages of
 programming in an interpreted language.

 This document briefly describes how to use the <bf>S-lang</bf>
 interface to <tt>PVM</tt>.  It assumes that the reader is
 already familiar with the PVM package itself.
 
 For complete details on obtaining, installing and using the
 PVM package, see the <url url="http://www.csm.ornl.gov/pvm/" name="PVM documentation">.  Note that, once the
 PVM package is properly installed on your computer, the PVM
 <tt>man</tt> pages will provide detailed documentation on all
 the PVM library functions.  
 
 Although the <bf>S-lang</bf> <tt>PVM</tt> module functions often have
 slightly different interfaces, the differences are usually
 minor so the PVM documentation is quite helpful.  Because
 the <bf>S-lang</bf> interface is not yet fully documented, it will
 be necessary to consult the <tt>PVM</tt> documentation directly
 to make full use of the <bf>S-lang</bf> <tt>PVM</tt> module.
 
 Because PVM processes require running programs on remote
 hosts, it is necessary to provide each host with the full path
 to the relevant executables.  To simplify this process, it may
 be useful to create a directory, e.g.<tt>$HOME/bin/PVM</tt>, on
 every host and put relevant executables in that directory so
 that the same relative path will work on all machines.  This
 PVM path may be specified in the <tt>$HOME/.pvmhosts</tt>
 configuration file; for a detailed description of the contents
 of this file, see the <tt>pvmd</tt> man page.
 
 The usage examples discussed in this manual assume that the
 PVM has already been initialized by running a command such as
<tscreen><verb>
  unix&gt; pvm ~/.pvmhosts
</verb></tscreen>
 This starts the PVM <it>console</it> and also starts the PVM
 daemon, <tt>pvmd</tt>, on each remote host.  This daemon runs
 all PVM slave processes and handles all communications with
 the parent process and the rest of the PVM.
 
 The execution environment of the PVM slave processes is
 inherited from the corresponding <tt>pvmd</tt> process which, in
 turn, is inherited from the parent process which started the
 PVM <it>console</it>.  However, it is sometimes useful to
 configure the environment of the remote <tt>pvmd</tt> process
 using a startup script, <tt>$HOME/.pvmprofile</tt>. This is a
 Bourne shell script which, if present, is run when <tt>pvmd</tt>
 is started.  For a detailed description of the contents of
 this file, see the <tt>pvmd</tt> man page.
 
<chapt>Using the PVM Module<p>

 To use the <tt>PVM</tt> module in a <bf>S-lang</bf> script, it is first
 necessary to make the functions in the package known to the
 interpreter via
<tscreen><verb>
    () = evalfile ("pvm");
</verb></tscreen>
 or, if the application embedding the interpreter supports the
 <tt>require</tt> function,
<tscreen><verb>
    require ("pvm");
</verb></tscreen>
 may be used.  If there is a namespace conflict between symbols in the
 script and those defined in the module, it may be necessary to load
 the PVM package into a namespace, e.g.,
<tscreen><verb>
   () = evalfile ("pvm", "p");
</verb></tscreen>
 will place the PVM symbols into a namespace called <tt>p</tt>.

 Once the PVM module has been loaded, the functions it defines
 may be used in the usual way, e.g.,
<tscreen><verb>
    require ("pvm");
        .
        .
    variable master_tid = pvm_mytid ();
</verb></tscreen>
 where <tt>pvm_mytid</tt> is the PVM function which returns the
 task identifier of the calling process.

<chapt>Examples<p>

 This section presents examples of two alternate methods of
 using the PVM module.  The source code for these examples is
 included in the <tt>PVM</tt> module source code distribution
 in the <tt>examples</tt> subdirectory. The first method uses PVM
 library routines to manage a simple distributed application.
 The second method uses the higher-level master-slave
 interface.  This interface can provide a high degree of
 tolerance to failure of slave machines which proves useful in
 long-running distributed applications.

<sect>Example 1:  A Simple <it>Hello World</it> Program<p>

 In programming language tutorials, the first example is
 usually a program which simply prints out a message such as
 <it>Hello World</it> and then exits.  The intent of such a trivial
 example is to illustrate all the steps involved in writing and
 running a program in that language.

 To write a <it>Hello World</it> program using the PVM module, we will
 write two programs, the master (<#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/hello_master" name="hello_master"></#if><#unless output=html>hello_master</#unless>), and the
 slave (<#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/hello_master" name="hello_slave"></#if><#unless output=html>hello_slave</#unless>).  The master process will spawn a
 slave process on different host and then wait for a message
 from that slave process.  When the slave runs, it sends a
 message to the master, or parent, and then exits. For the
 purpose of this example, we will assume that the PVM consists
 of two hosts, named <tt>vex</tt> and <tt>pirx</tt>, and that the
 slave process will run on <tt>pirx</tt>.

<sect1>The <tt>hello_master</tt> program<p>

 First, consider the master process, <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/hello_master" name="hello_master"></#if><#unless output=html>hello_master</#unless>.
 Conceptually, it must specify the full path to the slave
 executable and then send that information to the slave host
 (<tt>pirx</tt>).  For this example, we assume that the
 master and slave executables are in the same directory and
 that the master process is started in that directory. With
 this assumption, we can construct the path to the slave
 executable using the <tt>getcwd</tt> and <tt>path_concat</tt>
 functions. We then send this information to the slave host
 using the <tt>pvm_spawn</tt> function:
<tscreen><verb>
   path = path_concat (getcwd(), "hello_slave");
   slave_tid = pvm_spawn (path, PvmTaskHost, "pirx", 1);
</verb></tscreen>
 The first argument to <tt>pvm_spawn</tt> specifies the full path
 to the slave executable.  The second argument is a bit mask
 specifying options associated with spawning the slave process.
 The <tt>PvmTaskHost</tt> option indicates that the slave process
 is to be started on a specific host.  The third argument gives
 the name of the slave host and the last argument indicates how
 many copies of this process should be started. The return
 value of <tt>pvm_spawn</tt> is an array of task identifiers for
 each of the slave processes; negative values indicate that an
 error occurred.

 Having spawned the <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/hello_master" name="hello_slave"></#if><#unless output=html>hello_slave</#unless> process on <tt>pirx</tt>,
 the master process calls the <tt>pvm_recv</tt> function to
 receive a message from the slave.
<tscreen><verb>
   bufid = pvm_recv (-1, -1);
</verb></tscreen>
 The first argument to <tt>pvm_recv</tt> specifies the task
 identifier of the slave process expected to send the message
 and the second argument specifies the type of message that is
 expected.  A slave task identifier <tt>-1</tt> means that a
 message from any slave will be accepted.  Similarly, a message
 identifier of <tt>-1</tt> means that any type of message will be
 accepted.  In this example, we could have specified
 the slave task id and the message identifier explicitly:
<tscreen><verb>
  bufid = pvm_recv (slave_tid, 1);
</verb></tscreen>
 When a suitable message is received, the contents of the
 message are stored in a PVM buffer and <tt>pvm_recv</tt> returns
 the buffer identifier which may be used by the PVM application
 to retrieve the contents of the buffer.

 Retrieving the contents of the buffer normally requires
 knowing the format in which the information is stored. In this
 case, because we accepted all types of messages from the
 slave, we may need to examine the message buffer to find out
 what kind of message was actually recieved. The
 <tt>pvm_bufinfo</tt> function is used to obtain information
 about the contents of the buffer.
<tscreen><verb>
   (,msgid,) = pvm_bufinfo (bufid);
</verb></tscreen>
 Given the buffer identifier, <tt>pvm_bufinfo</tt> returns the
 number of bytes, the message identifier and the task identifer
 sending the message.

 Because we know that the slave process sent a single object of
 <tt>Struct_Type</tt>, we retrieve it by calling the
 <tt>pvm_recv_obj</tt> function.
<tscreen><verb>
   variable obj = pvm_recv_obj();
   vmessage ("%s says %s", obj.from, obj.msg);
</verb></tscreen>
 This function is not part of the PVM package but is a higher
 level function provided by the <tt>PVM</tt> module.  It
 simplifies the process of sending <bf>S-lang</bf> objects between hosts
 by handling some of the bookkeeping required by the lower
 level PVM interface.  Having retrieved a <bf>S-lang</bf> object from
 the message buffer, we can then print out the message.
 Running <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/hello_master" name="hello_master"></#if><#unless output=html>hello_master</#unless>, we see:
<tscreen><verb>
  vex&gt; ./hello_master
  pirx says Hello World
</verb></tscreen>
 Note that before exiting, all PVM processes should call the
 <tt>pvm_exit</tt> function to inform the <tt>pvmd</tt> daemon of
 the change in PVM status.
<tscreen><verb>
   pvm_exit();
   exit(0);
</verb></tscreen>
 At this point, the script may exit normally.

<sect1>The <tt>hello_slave</tt> program<p>

 Now, consider the slave process, <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/hello_master" name="hello_slave"></#if><#unless output=html>hello_slave</#unless>.
 Conceptually, it must first determine the location of its
 parent process, then create and send a message to that
 process.

 The task identifier of the parent process is obtained using
 the <tt>pvm_parent</tt> function.
<tscreen><verb>
   variable ptid = pvm_parent();
</verb></tscreen>
 For this example, we will send a message consisting of a
 <bf>S-lang</bf> structure with two fields, one containing the name of
 the slave host and the other containing the string
 <tt>"Hello World"</tt>.

 We use the <tt>pvm_send_obj</tt> function to send this this
 message because it automatically handles packaging all the
 separate structure fields into a PVM message buffer and also
 sends along the structure field names and data types so that
 the structure can be automatically re-assembled by the
 receiving process. This makes it possible to write code which
 transparently sends <bf>S-lang</bf> objects from one host to
 another. To create and send the structure:
<tscreen><verb>
   variable s = struct {msg, from};
   s.msg = "Hello World";
   s.from = getenv ("HOST");

   pvm_send_obj (ptid, 1, s);
</verb></tscreen>
 The first argument to <tt>pvm_send_obj</tt> specifies the task
 identifier of the destination process, the second argument is
 a message identifier which is used to indicate what kind of
 message has been sent.  The remaining arguments contain the
 data objects to be included in the message.

 Having sent a message to the parent process, the slave process
 then calls <tt>pvm_exit</tt> to inform the <tt>pvmd</tt> daemon
 that its work is complete.  This allows <tt>pvmd</tt> to notify
 the parent process that a slave process has exited. The slave
 then exits normally.

<sect>Example 2:  Using the Master-Slave Interface<p>

 The <tt>PVM</tt> module provides a higher level interface to
 support the master-slave paradigm for distributed
 computations. The symbols associated with this interface have
 the <tt>pvm_ms</tt> prefix to distinguish them from those
 symbols associated with the PVM package itself.

 The <tt>pvm_ms</tt> interface provides a means for handling
 computations which consist of a predetermined list of tasks
 which can be performed by running arbitrary slave processes
 which take command-line arguments. The interface provides a
 high degree of robustness, allowing one to add or delete hosts
 from the PVM while the distributed process is running and also
 ensuring that the task list will be completed even if one or
 more slave hosts fail (e.g. crash) during the computation.
 Experience has shown that this failure tolerance is
 surprisingly important.  Long-running distributed computations
 experience failure of one or more hosts with surprising
 frequency and it is essential that such failures do not
 require restarting the entire distributed computation from the
 beginning.

 Scripts using this interface must initialize it by loading
 the <tt>pvm_ms</tt> package via, e.g.
<tscreen><verb>
      require ("pvm_ms");
</verb></tscreen>
 As an example of how to use this interface, we examine the
 scripts <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="master"></#if><#unless output=html>master</#unless> and <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="slave"></#if><#unless output=html>slave</#unless>.

<sect1>The <tt>master</tt> program<p>

 The <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="master"></#if><#unless output=html>master</#unless> script first builds a list of tasks each
 consisting of an array of strings which provide the command
 line for each slave process that will be spawned on the PVM.
 For this simple example, the same command line will be
 executed a specified number of times. First, the script
 constructs the path to the <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="slave"></#if><#unless output=html>slave</#unless> executable,
 (<tt>Slave_Pgm</tt>), and then the command line (<tt>Cmd</tt>), that
 each <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="slave"></#if><#unless output=html>slave</#unless> instance will invoke.  Then the array of
 tasks is constructed:

<tscreen><verb>
 variable pgm_argvs = Array_Type[N];
 variable pgm_argv = [Slave_Pgm, Cmd];

 pgm_argvs[*] = pgm_argv;
</verb></tscreen>

 The distribution of these tasks across the available PVM is
 automatically handled by the <tt>pvm_ms</tt> interface. The
 interface will simultaneously start as many tasks as possible
 up to some maximum number of processes per host. Here we
 specify that a maximum of two processes per host may run
 simultaneously and then submit the list of tasks to the PVM:

<tscreen><verb>
   pvm_ms_set_num_processes_per_host (2);
   exit_status = pvm_ms_run_master (pgm_argvs);
</verb></tscreen>

 As each slave process is completed, its exit status is
 recorded along with any messages printed to <tt>stdout</tt>
 during the execution. When the entire list of tasks is
 complete, an array of structures is returned containing status
 information for each task that was executed. In this example,
 the <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="master"></#if><#unless output=html>master</#unless> process simply prints out this information.

<sect1>The <tt>slave</tt> program<p>

 The <#if output=html><url url="http://space.mit.edu/cxc/software/slang/modules/pvm/examples/master" name="slave"></#if><#unless output=html>slave</#unless> process in this example is relatively simple.
 Its command line arguments provide the task to be completed.
 These arguments are then passed to <tt>pvm_ms_run_slave</tt>
<tscreen><verb>
  pvm_ms_run_slave (__argv[[1:]]);
</verb></tscreen>
 which spawns a subshell, runs the specified command,
 communicates the task completion status to the parent process
 and exits.

<chapt>Master-Slave Function Reference<p>

<sect><bf>pvm_ms_kill</bf><label id="pvm_ms_kill"><p><descrip>
<tag> Synopsis </tag> Send a "task complete" message to a specific task
<tag> Usage </tag> <tt>pvm_ms_kill (Int_Type mtid, Int_Type stid)</tt>
<tag> Description </tag>
  This function may be used to send a "task complete" message
  to a specific PVM process.  The first argument gives
  the task identifier of the destination process.  The second
  argument gives the task identifier of the sending process.
<tag> Example </tag>
<tscreen><verb>
  tid = pvm_mytid ();
  ptid = pvm_parent ();
  pvm_ms_kill (ptid, tid);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_slave_exit" name="pvm_ms_slave_exit"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_num_processes_per_host</bf><label id="pvm_ms_set_num_processes_per_host"><p><descrip>
<tag> Synopsis </tag> Set the maximum number of simultaneous processes per host
<tag> Usage </tag> <tt>pvm_ms_set_num_processes_per_host (Int_Type num_processes)</tt>
<tag> Description </tag>
  This function is used to set the maximum number of simultaneous
  processes per host.  The master process normally runs as many
  simultaneous processes as possible;  by setting the maximum
  number of simultaneous processes per host, one can limit the
  processing load per host.
<tag> Example </tag>
<tscreen><verb>
  pvm_ms_set_num_processes_per_host (2);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_run_master" name="pvm_ms_run_master"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_debug</bf><label id="pvm_ms_set_debug"><p><descrip>
<tag> Synopsis </tag> Set the debug flag
<tag> Usage </tag> <tt>pvm_ms_set_debug (Int_Type debug)</tt>
<tag> Description </tag>
  This function may be used to control whether debugging
  information is printed out during execution.  Debugging
  information is printed if the flag is non-zero.
<tag> Example </tag>
<tscreen><verb>
  pvm_ms_set_debug (1);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_set_num_processes_per_host" name="pvm_ms_set_num_processes_per_host"></tt>
</descrip><p>

<sect><bf>pvm_ms_slave_exit</bf><label id="pvm_ms_slave_exit"><p><descrip>
<tag> Synopsis </tag> Cause a normal exit of a slave process from the PVM
<tag> Usage </tag> <tt>pvm_ms_slave_exit (Int_Type exit_status)</tt>
<tag> Description </tag>
  To exit the PVM, a slave process calls this function to
  send its exit status to the parent process and to notify
  the local <tt>pvmd</tt> of its exit.
<tag> Example </tag>
<tscreen><verb>
    pvm_ms_slave_exit (exit_status);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_run_slave" name="pvm_ms_run_slave"></tt>
</descrip><p>

<sect><bf>pvm_ms_run_slave</bf><label id="pvm_ms_run_slave"><p><descrip>
<tag> Synopsis </tag> Execute the slave's assigned task in a subshell, then exit the PVM
<tag> Usage </tag> <tt>pvm_ms_run_slave (String_Type argv[])</tt>
<tag> Description </tag>
   A slave process calls this function to run a command in a
   subshell and then exit the PVM.  The command line is
   constructed by concatenting the elements of an array of
   strings, <tt>argv</tt>, delimited by spaces. The integer return
   value from the <tt>system</tt> call provides the exit status
   for the slave process.  After sending this value to its
   parent process, the slave notifies the PVM and exits.
<tag> Example </tag>
<tscreen><verb>
   pvm_ms_run_slave (argv);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_slave_exit" name="pvm_ms_slave_exit"></tt>
</descrip><p>

<sect><bf>pvm_ms_run_master</bf><label id="pvm_ms_run_master"><p><descrip>
<tag> Synopsis </tag> Submit a list of tasks to the PVM
<tag> Usage </tag> <tt>Struct_Type exit_status[] = pvm_ms_run_master (String_Type pgms[])</tt>
<tag> Description </tag>
  This function is used to submit a managed list of tasks to
  the PVM.  The task list manager will try to ensure that all
  tasks are completed and, upon completion of the task list,
  will return an array of structures containing information
  about the results of each task.

<tag> Example </tag>
  To run the Unix command <it>ps xu</it> on a number of different
  hosts:
<tscreen><verb>
    variable slave_argv = Array_Type[n];
    slave_argv[*] = ["ps", "axu"];
    exit_status = pvm_ms_run_master (slave_argv);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_add_new_slave" name="pvm_ms_add_new_slave"></tt>
</descrip><p>

<sect><bf>pvm_ms_add_new_slave</bf><label id="pvm_ms_add_new_slave"><p><descrip>
<tag> Synopsis </tag> Add a new slave to the managed list
<tag> Usage </tag> <tt>pvm_ms_add_new_slave (String_Type argv[])</tt>
<tag> Description </tag>
 This function may be used to add a new slave process
 while pvm_ms_run_master() is running, usually as a result
 of handling a message.
<tag> Example </tag>
<tscreen><verb>
    pvm_ms_add_new_slave ("vex");
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_run_master" name="pvm_ms_run_master"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_message_callback</bf><label id="pvm_ms_set_message_callback"><p><descrip>
<tag> Synopsis </tag> Set a callback for handling user-defined messages
<tag> Usage </tag> <tt>pvm_ms_set_message_callback (Ref_Type func)</tt>
<tag> Description </tag>
 This function may be used to handle user-defined messages
 be sent from slave processes back to the master process.
<tag> Example </tag>
<tscreen><verb>

 static define handle_user_message (msgid, tid)
 {
    switch (msgid)
      {
       case USER_SLAVE_RESULT:
           recv_results (tid);
           start_task (tid);
      }
      {
       case USER_SLAVE_READY:
           start_task (tid);
      }
      {
         % default:
           return 0;
      }
    return 1;
 }

 pvm_ms_set_message_callback (&amp;handle_user_message);

</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_ms_set_idle_host_callback" name="pvm_ms_set_idle_host_callback">, <ref id="pvm_ms_set_slave_exit_failed_callback" name="pvm_ms_set_slave_exit_failed_callback"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_slave_exit_failed_callback</bf><label id="pvm_ms_set_slave_exit_failed_callback"><p><descrip>
<tag> Synopsis </tag> Set a hook to be called when a slave exits on failure
<tag> Usage </tag> <tt>pvm_ms_set_slave_exit_failed_callback (Ref_Type func)</tt>
<tag> Description </tag>

 This function may be used to have the master process perform a
 specified action whenever a slave process exits without having
 completed its assigned task.

 This is primarily useful in the context where each command-line
 submitted to <tt>pvm_ms_run_master</tt> represents a task which
 itself communicates with the PVM, performing potentially many
 additional tasks which are independently managed by the
 process that called <tt>pvm_ms_run_master</tt>.

 For example, consider a case in which initialization of slave
 processes is very expensive but, once initialized, a single
 slave process may perform many tasks.  In this case, the
 master process may spawn a small number of slaves and then
 repeatedly send each slave a task to perform.  Each slave
 performs its task, sends the result to the master, and then
 waits for another task. The managing process must keep track
 of which tasks have been completed and which remain. If a
 slave exits while working on a task, it is important that the
 manager process be notified that that task in progress was not
 completed and that it should be reassigned to another slave.

<tag> Example </tag>

<tscreen><verb>
   static define slave_exit_failed_callback (msgid, tid)
   {
      variable t = find_task_tid (tid);

      if (orelse {t == NULL} {t.status == FINISHED})
        return;

      % mark the unfinished task "READY" so that it will
      % be assigned to another slave

      t.tid = -1;
      t.status = READY;
   }

   pvm_ms_set_slave_exit_failed_callback (&amp;slave_exit_failed_callback);
</verb></tscreen>

<tag> See Also </tag> <tt><ref id="pvm_ms_set_message_callback" name="pvm_ms_set_message_callback"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_slave_spawned_callback</bf><label id="pvm_ms_set_slave_spawned_callback"><p><descrip>
<tag> Synopsis </tag> Set the slave spawned callback hook
<tag> Usage </tag> <tt>pvm_ms_set_slave_spawned_callback (Ref_Type func)</tt>
<tag> Description </tag>

 This function may be used to specify a callback function to be
 called whenever a slave process has been spawned.  The callback
 function will be called with three arguments: the slave task
 id, the name of the host running the slave process, and an
 array of strings representing the argument list passed to the
 slave.

<tag> Example </tag>

<tscreen><verb>
   static define slave_spawned_callback (tid, host, argv)
   {
      vmessage ("Slave running %s spawned on %s with task-id %d",
                argv[0], host, tid);
   }
   pvm_ms_set_slave_spawned_callback (&amp;slave_spawned_callback);
</verb></tscreen>

<tag> See Also </tag> <tt><ref id="pvm_ms_set_message_callback" name="pvm_ms_set_message_callback"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_idle_host_callback</bf><label id="pvm_ms_set_idle_host_callback"><p><descrip>
<tag> Synopsis </tag> Set the idle host hook
<tag> Usage </tag> <tt>pvm_ms_set_idle_host_callback (Ref_Type func)</tt>
<tag> Description </tag>
 This function may be used to specify a callback function to be
 called whenever a new host is added to the virtual machine.
<tag> Example </tag>

<tscreen><verb>
 static define idle_host_callback ()
 {
    loop (Max_Num_Processes_Per_Host)
      {
         variable slave_argv = build_slave_argv (0);
         pvm_ms_add_new_slave (slave_argv);
      }
 }
 pvm_ms_set_idle_host_callback (&amp;idle_host_callback);
</verb></tscreen>

<tag> See Also </tag> <tt><ref id="pvm_ms_set_message_callback" name="pvm_ms_set_message_callback"></tt>
</descrip><p>

<sect><bf>pvm_ms_set_hosts</bf><label id="pvm_ms_set_hosts"><p><descrip>
<tag> Synopsis </tag> Set list of hosts to use
<tag> Usage </tag> <tt>pvm_ms_set_hosts (String_Type hosts[])</tt>
<tag> Description </tag>
  This function may be used to specify which hosts will be used
  to perform distributed calculations.  The default is to use
  all hosts in the current PVM.
<tag> Example </tag>
<tscreen><verb>
      pvm_ms_set_hosts (["vex", "pirx", "aluche"]);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_addhosts" name="pvm_addhosts"></tt>
</descrip><p>


<chapt>PVM Module Function Reference<p>

<sect><bf>pvm_send_obj</bf><label id="pvm_send_obj"><p><descrip>
<tag> Synopsis </tag> Pack and send data objects
<tag> Usage </tag> <tt>pvm_send (Int_Type tid, Int_Type msgid, object [,...])</tt>
<tag> Description </tag>
  This function is much like <tt>pvm_psend</tt> except that it
  sends additional type information with each object. Using
  this function paired with <tt>pvm_recv_obj</tt> simplifies
  sending aggregate data objects such as structures and removes
  the need for the receiver to specify datatypes explicitly.
<tag> Example </tag>

  To send a <bf>S-lang</bf> structure to another process:
<tscreen><verb>
  variable obj = struct {name, x, y, data};
  ...
  pvm_send_obj (tid, msgid, obj);
</verb></tscreen>

<tag> See Also </tag> <tt><ref id="pvm_recv_obj" name="pvm_recv_obj">, <ref id="pvm_psend" name="pvm_psend">, <ref id="pvm_unpack" name="pvm_unpack"></tt>
</descrip><p>

<sect><bf>pvm_recv_obj</bf><label id="pvm_recv_obj"><p><descrip>
<tag> Synopsis </tag> Receive data objects from <tt>pvm_send_obj</tt>
<tag> Usage </tag> <tt>obj = pvm_recv_obj ()</tt>
<tag> Description </tag>
  This function receives an object sent by <tt>pvm_send_obj</tt>
  and returns a slang object of the same type that was sent.
  It simplifies sending aggregate data types such as structures.
<tag> Example </tag>

  To receive a <bf>S-lang</bf> object sent by another process
  via <tt>pvm_send_obj</tt>:
<tscreen><verb>
  obj = pvm_recv_obj ();
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_send_obj" name="pvm_send_obj">, <ref id="pvm_psend" name="pvm_psend">, <ref id="pvm_unpack" name="pvm_unpack"></tt>
</descrip><p>

<sect><bf>pvm_config</bf><label id="pvm_config"><p><descrip>
<tag> Synopsis </tag> Returns information about the present virtual machine configuration
<tag> Usage </tag> <tt>Struct_Type = pvm_config ()</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  h = pvm_config ();
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_kill" name="pvm_kill"></tt>
</descrip><p>

<sect><bf>pvm_kill</bf><label id="pvm_kill"><p><descrip>
<tag> Synopsis </tag> Terminates a specified PVM process
<tag> Usage </tag> <tt>pvm_kill (Int_Type tid)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  pvm_kill (tid);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_config" name="pvm_config"></tt>
</descrip><p>

<sect><bf>pvm_initsend</bf><label id="pvm_initsend"><p><descrip>
<tag> Synopsis </tag> Clear default send buffer and specify message encoding
<tag> Usage </tag> <tt>bufid = pvm_initsend (Int_Type encoding)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  bufid = pvm_initsend (PvmDataDefault);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_send" name="pvm_send"></tt>
</descrip><p>

<sect><bf>pvm_pack</bf><label id="pvm_pack"><p><descrip>
<tag> Synopsis </tag> Pack the active message buffer with arrays of prescribed data type
<tag> Usage </tag> <tt>pvm_pack (object)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  pvm_pack (x);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_unpack" name="pvm_unpack"></tt>
</descrip><p>

<sect><bf>pvm_send</bf><label id="pvm_send"><p><descrip>
<tag> Synopsis </tag> Immediately sends the data in the active message buffer
<tag> Usage </tag> <tt>pvm_send (Int_Type, tid, Int_Type msgid)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  pvm_send (tid, msgid);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_recv" name="pvm_recv"></tt>
</descrip><p>

<sect><bf>pvm_recv</bf><label id="pvm_recv"><p><descrip>
<tag> Synopsis </tag> Receive a message
<tag> Usage </tag> <tt>bufid = pvm_recv (Int_Type tid, Int_Type msgtag)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
   bufid = pvm_recv (tid, msgtag);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_send" name="pvm_send"></tt>
</descrip><p>

<sect><bf>pvm_unpack</bf><label id="pvm_unpack"><p><descrip>
<tag> Synopsis </tag> Unpack the active message buffer into arrays of prescribed data type
<tag> Usage </tag> <tt>item = pvm_unpack (Int_Type type_id, Int_Type num)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  item = pvm_unpack (type, num);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_pack" name="pvm_pack"></tt>
</descrip><p>

<sect><bf>pvm_psend</bf><label id="pvm_psend"><p><descrip>
<tag> Synopsis </tag> Pack and send data
<tag> Usage </tag> <tt>pvm_psend (Int_Type tid, Int_Type msgid, object [,...])</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  pvm_psend (tid, msgid, data);
</verb></tscreen>
<tag> Notes </tag>
  Unlike the <tt>pvm_send</tt> function in the PVM library, this function
  does not operate asynchronously.
<tag> See Also </tag> <tt><ref id="pvm_send" name="pvm_send">, <ref id="pvm_initsend" name="pvm_initsend">, <ref id="pvm_pack" name="pvm_pack">, <ref id="pvm_recv" name="pvm_recv"></tt>
</descrip><p>

<sect><bf>pvm_addhosts</bf><label id="pvm_addhosts"><p><descrip>
<tag> Synopsis </tag> Add one or more hosts to the PVM server
<tag> Usage </tag> <tt>Int_Type[] = pvm_addhosts (String_Type[] hosts)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  tids = pvm_addhosts (["vex", "verus", "aluche"]);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_addhosts" name="pvm_addhosts">, <ref id="pvm_config" name="pvm_config">, <ref id="pvm_delhosts" name="pvm_delhosts"></tt>
</descrip><p>

<sect><bf>pvm_delhosts</bf><label id="pvm_delhosts"><p><descrip>
<tag> Synopsis </tag> Delete one or more hosts from the PVM server
<tag> Usage </tag> <tt>pvm_delhosts (String_Type[] hosts)</tt>
<tag> Description </tag>
  See the PVM documentation.
<tag> Example </tag>
<tscreen><verb>
  pvm_delhosts (["vex", "verus"]);
</verb></tscreen>
<tag> See Also </tag> <tt><ref id="pvm_delhosts" name="pvm_delhosts">, <ref id="pvm_config" name="pvm_config">, <ref id="pvm_kill" name="pvm_kill"></tt>
</descrip><p>


<chapt>Module Symbols Lacking Documentation<p>

Although many more low-level PVM intrinsic functions are
provided by the S-Lang module, not all of S-Lang interfaces
have been documented. See the PVM documentation for information
on the following functions:

<tscreen><verb>
    pvm_delhost
    pvm_export
    pvm_freebuf
    pvm_freecontext
    pvm_getcontext
    pvm_newcontext
    pvm_setcontext
    pvm_getopt
    pvm_nrecv
    pvm_sendsig
    pvm_tidtohost
    pvm_setopt
    pvm_config
    pvm_getrbuf
    pvm_getsbuf
    pvm_halt
    pvm_tasks
    pvm_kill
    pvm_mstat
    pvm_pstat
    pvm_mcast
    pvm_addhost
    pvm_archcode
    pvm_probe
    pvm_bufinfo
    pvm_notify
    pvm_unpack
    pvm_send
    pvm_recv
    pvm_pack
    pvm_initsend
    pvm_exit
    pvm_mytid
    pvm_parent
    pvm_spawn
    pvm_barrier
    pvm_getinst
    pvm_bcast
    pvm_gettid
    pvm_gsize
    pvm_joingroup
    pvm_lvgroup
    pvm_settmask
    pvm_tev_mask_init
    pvm_tev_mask_set
    pvm_sigterm_enable
</verb></tscreen>

Similarly, the following PVM intrinsic constants are provided
by the S-Lang module but are documented only through the
PVM documentation.

<tscreen><verb>
    PvmDataDefault
    PvmDataRaw
    PvmDataInPlace
    PvmDataTrace
    PvmTaskDefault
    PvmTaskHost
    PvmTaskArch
    PvmTaskDebug
    PvmTaskTrace
    PvmMppFront
    PvmHostCompl
    PvmNoSpawnParent
    PvmTaskExit
    PvmHostDelete
    PvmHostAdd
    PvmRouteAdd
    PvmRouteDelete
    PvmNotifyCancel
    PvmRoute
    PvmDontRoute
    PvmAllowDirect
    PvmRouteDirect
    PvmDebugMask
    PvmAutoErr
    PvmOutputTid
    PvmOutputCode
    PvmTraceTid
    PvmTraceCode
    PvmTraceBuffer
    PvmTraceOptions
    PvmTraceFull
    PvmTraceTime
    PvmTraceCount
    PvmFragSize
    PvmResvTids
    PvmSelfOutputTid
    PvmSelfOutputCode
    PvmSelfTraceTid
    PvmSelfTraceCode
    PvmSelfTraceBuffer
    PvmSelfTraceOptions
    PvmShowTids
    PvmPollType
    PvmPollConstant
    PvmPollSleep
    PvmPollTime
    PvmOutputContext
    PvmTraceContext
    PvmSelfOutputContext
    PvmSelfTraceContext
    PvmNoReset
    PvmTaskSelf
    PvmTaskChild
    PvmBaseContext
    PvmMboxDefault
    PvmMboxPersistent
    PvmMboxMultiInstance
    PvmMboxOverWritable
    PvmMboxFirstAvail
    PvmMboxReadAndDelete
    PvmMboxWaitForInfo
    PvmOk
    PvmBadParam
    PvmMismatch
    PvmOverflow
    PvmNoData
    PvmNoHost
    PvmNoFile
    PvmDenied
    PvmNoMem
    PvmBadMsg
    PvmSysErr
    PvmNoBuf
    PvmNoSuchBuf
    PvmNullGroup
    PvmDupGroup
    PvmNoGroup
    PvmNotInGroup
    PvmNoInst
    PvmHostFail
    PvmNoParent
    PvmNotImpl
    PvmDSysErr
    PvmBadVersion
    PvmOutOfRes
    PvmDupHost
    PvmCantStart
    PvmAlready
    PvmNoTask
    PvmNotFound
    PvmExists
    PvmHostrNMstr
    PvmParentNotSet
    PvmNoEntry
    PvmDupEntry
    TEV_MCAST
    TEV_SEND
    TEV_RECV
    TEV_NRECV
</verb></tscreen>

</book>
