[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. Writing `TOP-C' Applications

This chapter assumes a knowledge of the basic concepts in 3. Overview of `TOP-C/C++'. In particular, recall 3.1.1 Structure of a TOP-C Program.

4.1 The Main TOP-C Library Calls  
4.2 Callback Functions for TOPC_master_slave()  
4.3 Actions Returned by CheckTaskResult()  
4.4 TOP-C Utilities  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.1 The Main TOP-C Library Calls

Every `TOP-C' application must include a `topc.h' header, open with TOPC_init(), call TOPC_master_slave() one or more times, and then close with TOPC_finalize().

 
#include <topc.h>
      Required at head of any file using TOPC library calls.

Function: void TOPC_init ( int *argc, char ***argv )
Required before first occurrence of TOPC_master_slave(); Recommended to place this as first executable statement in main(). It will strip off extra `TOP-C' and communication layer arguments such as `--TOPC-stats', which are added by `TOP-C'.
Function: void TOPC_finalize ( void )
Placed after last `TOP-C' command.
Function: void TOPC_master_slave
( TOPC_BUF (*generate_task_input)(),
   TOPC_BUF (*do_task)(void *input),
   TOPC_ACTION (*check_task_result)(void *input, void *output),
   void (*update_shared_data)(void *input, void *output)
)
Primary call, passed four application callbacks to `TOP-C'. One can have multiple calls to TOPC_master_slave(), each invoking different callback functions, between TOPC_init() and TOPC_finalize().

A task input or task output is simply a buffer of bytes, specified by TOPC_MSG().

Function: TOPC_BUF TOPC_MSG ( void *buf, int buf_size )
Must be returned by GenerateTaskInput() and DoTask(). Specifies arbitrary user data structure. `TOP-C' will make a copy of buf in `TOP-C' space. It remains the responsibility of the application to free or reuse the space of the original buffer buf. If TOPC_MSG(NULL, 0) is called, a NULL pointer will be received at the destination. (See section 8.3.2 Using TOPC_MSG_PTR() to Avoid Copying Large Buffers, for TOPC_MSG_PTR, to avoid copying very large buffers, where the overhead is unacceptable.)

EXAMPLE:
 
    TOPC_BUF convert_string_to_msg( char *mystring ) {
        if (mystring == NULL) return TOPC_MSG(NULL,0);
        else return TOPC_MSG(mystring, strlen(mystring)+1);
    }


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2 Callback Functions for TOPC_master_slave()

The application writer must define the following four callback functions (although the last can be NULL). The callback terminology is based on C concepts. In a more object-oriented style, one would view user callbacks as instantiation of abstract methods in a user-defined subclass. The first two functions return a TOPC_BUF, which is produced by TOPC_MSG().

Function: TOPC_BUF GenerateTaskInput ( void )
executes on master; returns a data structure specified by TOPC_MSG(buf, buf_size). It should return NOTASK, when there are no more tasks, and it should be prepared to return NOTASK again if invoked again.
Function: TOPC_BUF DoTask ( void *input )
executes on slave; operates on the result of GenerateTaskInput(); returns a data structure specified by TOPC_MSG(buf, buf_size). buf must be a static or global user buffer.
Function: TOPC_ACTION CheckTaskResult ( void *input, void *output)
executes on master; operates on the result of DoTask(); returns an ACTION that determines what happens to the task next. The terminology result refers to an `(input, output)' pair. An easy way to write CheckTaskResult() appears in the example for the utility TOPC_is_up_to_date(). When returning the action UPDATE, it works to first modify the input and output buffers. UpdateSharedData() will then be invoked with the modified buffers. See 4.4 TOP-C Utilities, for more details.
Function: void UpdateSharedData ( void *input, void *output )
executes on master and all slaves; operates on the result of DoTask(), and the original task returned by GenerateTaskInput(); called only if CheckTaskResult() returned UPDATE; useful for updating global variables in all processes; The pointer argument, update_shared_data, of TOPC_master_slave() may be NULL if an application never requests an UPDATE action. In a shared memory environment, only the master calls UpdateSharedData(). See 8.4 Optimizing TOP-C Code for the Shared Memory Model, for more details.

Note that in defining the above callback functions, C allows one to replace the (void *) declaration of the arguments by specific pointer types. Note that the buffers of any message parameters (input and output) of DoTask() or CheckTaskResult() are part of TOP-C space. Such buffers may be freed by TOP-C on exit from the callback function. An application wishing to use the buffer after the callback exits must explicitly save a copy into the application's own space.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.3 Actions Returned by CheckTaskResult()

A TOP-C result is an (input, output) pair corresponding to an invocation of DoTask(). `TOP-C' passes the result to CheckTaskResult(). The return value allows the application to tell `TOP-C' what further actions to take. The actions returned by CheckTaskResult() are:

Action: TOPC_ACTION NO_ACTION
C constant, causing no further action for task
Action: TOPC_ACTION UPDATE
C constant, invoking UpdateSharedData( void *input, void *output) (see below) also updates bookkeeping for sake of TOPC_is_up_to_date() (see section 4.4 TOP-C Utilities)
Action: TOPC_ACTION REDO
Invoke DoTask() on original task input again, and on the same slave that previously executed the task; useful if shared data has changed since original invocation of DoTask() (see TOPC_is_up_to_date(), below). See 7.2 Strategies for Greater Concurrency, for slave strategies to efficiently process a REDO action.
Action: TOPC_ACTION CONTINUATION ( void *next_input )
CONTINUATION(next_input) is a parametrized action that may be returned by CheckTaskResult(), after which DoTask( next_input ) is called on the original slave. This is useful if only the master can decide whether task is complete, or if the master wishes to supply additional input messages needed for the task. Note that REDO is essentially equivalent to CONTINUATION( original_task_input ). Note that any pending calls to UpdateSharedData() will have occurred on the slave before the new call to DoTask(). Hence, this allows an extended conversation between master and slave, in which the slave continues to receive updates of the shared data before each new input from the master. Note also that even though a CONTINUATION action returns to the original slave, any previous pointers to input buffers on that slave (and pointers to output buffers from intervening UPDATE actions) will no longer be valid. Useful data from previous buffers should have been copied into global variables on the slave. In the case of the shared memory model, those global variables must be thread-private. (see section 8.4.2 Thread-Private Global Variables)

It is possible for CheckTaskResult(input, output) to modify the buffer data in its two arguments, input and output, in which case the modifications will be visible to any further callback functions processing the current task. This practice makes the code more difficult to maintain, and is not recommended when other solutions are available.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.4 TOP-C Utilities

`TOP-C' also defines some utilities.

Function: TOPC_BOOL TOPC_is_up_to_date ( void )
returns TRUE or FALSE (1 or 0); returns TRUE if and only if CheckTaskResult() has not returned the result UPDATE (invoking UpdateSharedData()) between the time when GenerateTaskInput() was originally called on the current task, and the time when the corresponding CheckTaskResult() was called. Typical usage:
 
          TOPC_ACTION CheckTaskResult( void *input, void *output )
          { if (input == NULL) return NO_ACTION;
            else if (TOPC_is_up_to_date()) return UPDATE;
            else return REDO;
          } 
Function: int TOPC_rank ( void )
Unique ID of process or thread. Master always has rank 0. Slaves have contiguous ranks, beginning at 1.
Function: TOPC_BOOL TOPC_is_master ( void )
Returns boolean, 0 or 1, depending on if this is master. Equivalent to TOPC_rank() == 0.
Function: int TOPC_num_slaves ( void )
Total number of slaves.
Function: int TOPC_num_idle_slaves ( void )
Total number of idle slaves (not doing task, update or other action).
Function: int TOPC_node_count ( void )
Total number of processes or threads. Equivalent to TOPC_num_slaves() + 1.

Function: TOPC_BOOL TOPC_is_REDO ( void )
Function: TOPC_BOOL TOPC_is_CONTINUATION ( void )
Function: void TOPC_abort_tasks ( void )
Function: TOPC_BOOL TOPC_is_abort_pending ( void )
See 8. Advanced Features of `TOP-C' for descriptions.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Gene Cooperman on October, 6 2004 using texi2html