Final: Adding Parallel Programming Capabilities to C++ Through the PVM

The pvm_probe() routine determines whether a particular message has arrived from the specified sender. The taskid parameter identifies the sender. The messageid parameter identifies the particular message. If the pvm_probe() routine is sees the specified message then the routine returns the buffer number for the new active buffer. If the specified message has not arrived the routine returns a 0 . If an error condition has occurred, the routine will return a value < 0.

Synopsis

#include "pvm3.h"

int pvm_getsbuf(void);

int pvm_getrbuf(void);

int pvm_setsbuf(int bufferid);

int pvm_setrbuf(int bufferid);

int pvm_mkbuf(int Code);

int pvm_freebuf(int bufferid);

There are six useful buffer management routines that can be used for setting, identifying, and dynamically creating the send and receive buffers. The pvm_getsbuf() routine is used to get the number for the active send buffer. If there is no current buffer this routine will return 0 . The pvm_getrbuf() routine is used to get the id number for the active receive buffer. Keep in mind that every time a message is received a new active receive buffer is created and the current receive buffer is cleared. If there is no current receive buffer pvm_getrbuf() will return 0 . The pvm_setsbuf() routine sets the active send buffer to bufferid . Typically a PVM task has only one send buffer. However, sometimes multiple send buffers are required. Although only one send buffer can be active at a time, a PVM task may create additional send buffer using the pvm_mkbuf() routine. The pvm_setsbuf() can be used to set the active buffer to send buffers that have been created at runtime. This routine returns the buffer identifier for the previous active send buffer. The pvm_setrbuf() sets the active receive buffer to bufferid . Remember that the PVM unpack routines work with the active receive buffer. If there is more than one buffer, then the pvm_setrbuf() can be used to set the current buffer to be used by the unpack routines. If the call to pvm_setrbuf() is successful it will return the buffer id of the previous buffer. If the buffer identifier passed to pmv_setrbuf() is not valid or does not exist then the routine can return one of the following error messages: PvmBadParam , or PvmNoSuchbuf . The pvm_mkbuf() routine is used to create a new message buffer. The Code parameter specifies whether the buffer will be setup to contain data encoded as XDR format, native machine format, or pointers and sizes. The Code parameter can be one of three values: If the pvm_mkbuf() routine is successful it will return the buffer id of the new active buffer. If an error occurs the function will return a value < 0.

PvmDataDefault XDR

PvmDataRaw Machine Dependent (no encoding)

PvmDataInPlace Pointers to the data and sizes of data only used

For every call to pvm_mkbuf() there should be a call made to pvm_freebuf() when send buffer is no longer needed. The memory allocated by the pvm_mkbuf() routine is released by the pvm_freebuf() . The pvm_freebuf() should only be used on a buffer that is no longer needed i.e., after the message has been sent.

6.4. Accessing Standard Input (stdin ) and Standard Output (stdout ) within PVM Tasks

A PVM environment ties a collection of machines together and presents them to the program as one logical machine with multiple processors. Which machine in the PVM should act as the console? When a PVM tasks inserts data into the cout ostream object where will the data be displayed? If a PVM task attempts to get data from a keyboard which keyboard will it read the data from? The stdout for each child process is intercepted and sent to a designated PVM task as a PVM message. Each child process inherits information that determines which task will receive information written to stdout and how that information should be identified. Each child process's stdin is tied to /dev/null. Anything written to /dev/null disappears. If /dev/null is opened for reading the equivalent of end-of-file is returned. This means child processes should not be designed to rely on input from stdin (cin) or on sending output to stdout ( cout). When designing input and output processing, this behavior of stdin and stdout in a PVM environment must be considered. However, stdin and stdout for the main or parent task behaves as expected. PVM tasks use messages to communicate. Input may be retrieved from messages, pipes, shared memory, environment variables, command line arguments or files. Output may be written to messages, pipes, shared memory and files.

6.4.1. Retrieving Standard Output (cout ) From a Child Task

Output written to stdout or inserted into cout behaves differently for PVM spawned children. The parent decides what ultimately happens to the output. When output from a spawned child is inserted into cout or cerr it is intercepted by the pvmd for that task and is packaged into standard PVM messages and sent to a TaskId specified by the parent. The parent associates a pair ( TaskId, Code ) to the cout , and cerr of its children. This is done using the pvm_setopt() routine. This routine is called before the children are spawned. If the TaskId is zero the messages will go to the master pvmd, where they will be written to its error log. A spawned child may only set the TaskId to zero, the value inherited from its parent, or its own TaskId. This means the parent ultimately controls where cout or cerr would write to. A child PVM designate other PVM tasks to receive data inserted into cout or cerr . The typical approach is to let the spawning task manage any important data written to stdout or stdin and let the master pvmd take everything else.

Summary

The PVM library is a flexible library that supports the major models of parallel programming. The advantage of PVM environment is its ability to work with heterogeneous collections of computers that may consist of different processor speeds, sizes, and architectures. Besides hardware compatibility, it works nicely with the C++ standard library and with the UNIX/Linux system library. When combined with the C++ template capabilities, object-oriented programming capabilities, and collection of algorithms the power of the PVM environment is increased considerably. The template facility has a nice application to SPMD programming. The containers and algorithms can be used to enhance the MIMD (MPMD) capabilities of the PVM. In Chapter 13, we dig a little deeper into the PVM and show how it can be used to help implement blackboards using C++. The blackboard is one of our primary choices for implementing parallel problem solving.





Sample chapter, summaries, captions, table of contents, code example and listings are provided for your information. Copyright 2003 Addison Wesley. All rights reserved. No part of these materials may be duplicated or reproduced, in any form or by any means, without the written permission of the publisher.