[ParGAP] 2 Slave Listener

[Up] [Previous] [Next] [Index]

# 2 Slave Listener

### Sections

1. Slave Listener Commands

ParGAP implements a model of a slave process as a slave listener. This means that the slave is running a simple program:

      (1) Read message from master [as string]
      (2) Evaluate message and return result
      (3) Send message to master with result [as string]
      (4) Goto step 1

An example using this interactive style is contained in section Extended Example.

Some enhancements to this simple model should also be noted. The reply message from the slave will wait in a queue until the master process decides to read it. If unwanted messages accumulate in the queue, the master can execute `FlushAllMsgs()` (see FlushAllMsgs). If a slave process prints to the standard output, this will be visible at the console of the master process. If a slave process executes an `Error` and goes into a break loop, then it will automatically return to the top level, return any error message to the master process, and wait for another message from the master process. If a slave process goes into an infinite loop, the master process can call `ParReset();` (see ParReset) to interrupt all slave processes and return them to their top level loop as a slave listener.

At this point, you may wish to review the commands by looking again at the extended example in section Extended Example. Note also some naming conventions:

`MPI_...`:
  A command prefix of `MPI_` signifies a GAP binding of an MPI function. These functions are low level functions on which the rest of ParGAP is built. They can be safely ignored by the casual user. (Recall that MPI, Message Passing Interface, is a standard for message passing.) In ParGAP, type `MPI_<`tab`>` for a list of all such functions.

`UNIX_...`:
  Commands with prefix `UNIX_` are additional system commands that were not present in the unmodified GAP kernel. They are typically GAP versions of UNIX commands that make life easier. `UNIX_Nice()` is an example. In ParGAP, type `UNIX_<`tab`>` for a list of all such functions.

`Par...`:
  Commands beginning with `Par` are ``parallel'' commands that should only be called by the master process. Such commands invoke all slave processes to do their work. In ParGAP, type `Par<`tab`>` for a list of all such functions.

## 2.1 Slave Listener Commands

The slave listener commands are implementd in `slavelist.g` in ParGAP's `lib` directory. Most procedures are short, and can also be read online by using GAP's `Print` command, e.g. try: `Print(SendMsg, "\n");` (the newline is needed only to get back to a clean ```gap>` '' prompt). The code of `SlaveListener` and `CloseSlaveListener` (try: `Print(SlaveListener, "\n");` and `Print(CloseSlaveListener, "\n");`) is also instructive and should provide some insights into the behavior of the slave listener. Examples of slave listener commands can be found in context in the section Extended Example. Some of these commands are based on MPI. Further information on basic concepts of MPI can be found in section Tutorial introduction to the MPI C library, but that section can be safely ignored on a first reading.

- `SendMsg(` command`[,` dest`[,` tag`]] ) F`

  sends command to dest (a non-negative integer that is the ``rank'' of the destination process); command should normally be a string (otherwise it is evaluated on the master before being passed to dest which almost certainly will defeat the purpose of using `SendMsg()`). If dest is omitted it defaults to 1 (the rank of the first slave) on the master process (i.e. if `IsMaster()` is `true`), or to 0 (the rank of the master) on a slave process (i.e. if `IsMaster()` is `false`). The argument tag, if given, should be a positive integer less than 1000. The default value of tag is 1. Tags of value 1000 and above are reserved for use by ParGAP itself, and should not be used by application routines.

- `RecvMsg( [`source`] ) F`

  gets a response from a command. The default value of source is `MPI_ANY_SOURCE`, which receives the next available message from any source. `GetLastMsgSource()` (see GetLastMsgSource) allows one to determine the source in such cases. `GetLastMsgTag()` (see GetLastMsgTag) always allows one to determine the tag, although most applications can ignore the tag. Tags are applied to commands by `SendMsg()` or `SendRecvMsg()` (see SendMsg).

- `GetLastMsgSource() F`

  returns the source of the last message that was either received (e.g. by `RecvMsg()`; see RecvMsg) or simply probed (e.g. by `ProbeMsg()`; see ProbeMsg).

- `GetLastMsgTag() F`

  returns the tag (see SendMsg) of the last message that was either received (e.g. by `RecvMsg()`; see RecvMsg) or simply probed (e.g. by `ProbeMsg()`; see ProbeMsg).

- `SendRecvMsg(` command`[,` dest`[,` tag`]] ) F`

  This command is equivalent to `SendMsg(` command`[,` dest`[,` tag`]] ); RecvMsg([`dest`]);` (see SendMsg and RecvMsg), except that even if dest is omitted the source for the `RecvMsg()` part of the command always matches the destination to which command is sent.

  Note: The response obtained will not be the response of the command itself if there are messages waiting to be received at the destination of command at the time `SendRecvMsg()` is called.

  Also note that tag values of 1000 and higher are reserved for use by ParGAP.

- `BroadcastMsg(` command`) F`

  executes command on (all) slaves only. The slaves do not send back a return value.

  Note: this use of the term broadcast is distinct from the MPI usage. In MPI, a broadcast message will be received by every process, including the process sending the message.

- `IsMaster() F`

  returns `true` if at console (i.e. if `MPI_Comm_rank() = 0`), and `false` otherwise.

- `FlushAllMsgs() F`

  flushes all messages that are waiting to be received and returns the number of messages flushed. (If there are no waiting messages 0 is returned.) It is essentially equivalent to executing `RecvMsg();;` until there are no more messages waiting to be received (see RecvMsg), except that it also returns the number of messages flushed.

- `PingSlave(` dest`) F`

  Check if slave dest is alive and listening for messages, where dest is a positive integer.

- `ParEval(` stringCmd`) F`

  Evaluate stringCmd on all processes, where stringCmd is a command inside double quotes so that it is passed as a string (like `BroadcastMsg()` (see BroadcastMsg), but `ParEval()` (see ParEval) also executes on the master and also returns a value based on result on the master.)

- `PrintToString(` object`[, ...] )`

  [Note that `PrintToString("abc") => "abc"` (like `Print()`, NOT `""abc""`) Hence, a useful idiom is: `ParEval( PrintToString( "foo := ", foo ) );` ]

- `ParRead(` filename`) F`
- `ParReread(` filename`) F`

  are parallel analogues of the GAP `Read` and `Reread` functions, respectively (see Read and Reread in the Reference Manual). `ParRead` (resp. `ParReread`) executes `Read` (resp. `Reread`) on all processes. Note that it is redundant (and often incorrect) to call `ParRead` on a file that itself contains `Par...` functions. One should either place sequential functions in a file and call `ParRead` or place `Par...` functions in a file and call `Read` from the master. As an example, in writing this code, the author (after having started ParGAP from its `bin` directory via `pargap.sh`) found it useful to edit `masslave.g` in ParGAP's `lib` directory and then type `ParReread("../lib/masslave.g");`.

- `ParList(` list`,` func`) F`

  is the parallel analogue of GAP's two-argument `List` function. But faster since it also uses the slave processes.

- `ProbeMsg( [`source`] ) F`

  probes for a pending message from source or any source if the argument source is omitted. It will block until such a message appears, and then return `true`. `^C` (interrupt) works to unblock it.

  Note: When the argument source is omitted, `ProbeMsg` sets source to `MPI_ANY_SOURCE` (which is `-1`), which specifies a probe for a message from any source.

- `ProbeMsgNonBlocking( [`source`] ) F`

  Exactly like `ProbeMsg`, but non-blocking. It returns immediately with `true` or `false`, depending on whether a message was present from source. The default value of source is `MPI_ANY_SOURCE`.

- `ParReset() F`

  flushes all pending messages from slaves, resets the slaves, pings the slaves and returns the number of messages flushed.

- `ParBindGlobal(` gvar`,` value`) F`

  Not currently implemented, due to certain technical considerations.

- `ParDeclareGlobalValue(` string`) F`
- `ParDeclareGlobalFunction(` string`) F`

  Similar to corresponding GAP functions. Note that unlike GAP's `DeclareGlobalFunction` and `ParDeclareGlobalValue`, these functions also allow you to re-declare an old function or variable. The net effect is to remove the old value, and allow one to again call `InstallGlobalFunction` and `InstallValue`. This eliminates the necessity for `Reread()` in ParGAP, and it also makes it easier to place the commands in a local file, and using a simple `Read()` instead of `ParRead()`. It also makes it easier to interactively re-declare and re-install functions.

- `ParInstallValue(` gvar`,` value`) F`
- `ParInstallValue(` string`,` value`) F`
- `ParInstallGlobalFunction(` gvar`,` function`) F`
- `ParInstallGlobalFunction(` string`,` function`) F`

  Note that the second version of `ParInstallGlobalFunction` (with string) is equivalent to

  `ParDeclareGlobalFunction(` string`);`
  `ParInstallGlobalFunction(` gvar`,` function`);`

  where gvar is a GAP variable whose name is string.

  Note that `ParInstallValue` is currently implemented only in the version for string, due to certain technical considerations.

  This completes the middle layer of ParGAP. It allows one to easily use parallelism interactively. There are now two choices for further reading. The recommended choice for writing your own parallel applications is to read the next chapter on the TOP-C task-oriented model of parallelism, and the follow-on chapter, containing a tutorial on the TOP-C model. These two chapters should provide enough background to write significant parallel applications. If on the other hand you are interested in MPI and the low-level fundamentals of message passing for parallel applications, then you should read Chapter MPI commands and UNIX system calls in ParGAP.

  [Up] [Previous] [Next] [Index]