[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are instances when tasks are most naturally generated deep
inside nested loops. Often, this occurs in parallelizing existing
sequential applications.
In such circumstances, it may be difficult to
re-write the code to create a function GenerateTaskInput()
, since
that would require turning the loops inside out. (If you don't know what this
refers to, then you probably don't need the raw interface.)
On a first reading, you may wish to first look at the example for either a `for' loop or `while' loop, depending on the type of loop that you are parallelizing. Then return to the formal descriptions of the `TOP-C' raw functions. This chapter assumes familiarity with the basic concepts of 3. Overview of `TOP-C/C++' and 4. Writing `TOP-C' Applications.
9.1 `TOP-C' raw functions 9.2 Parallelizing `for' Loops 9.3 Parallelizing `while' Loops
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
TOPC_raw_submit_task_input(input)
serving
the role of GenerateTaskInput()
. The slave blocks inside
TOPC_raw_begin_master_slave()
and executes `do_task()' and
`update_shared_data()' until the master executes
TOPC_raw_end_master_slave()
. At that time, the slave
unblocks. The slave does nothing inside
TOPC_raw_end_master_slave()
.
TOPC_raw_begin_master_slave()
and TOPC_raw_end_master_slave()
; Typical usage is:
|
GenerateTaskInput()
in the routine TOPC_master_slave()
.
input will be processed by DoTask()
and its siblings,
just as in TOPC_master_slave()
).
There can be multiple occurrences of
TOPC_raw_submit_task_input()
.
TOPC_raw_begin_master_slave()
and
TOPC_raw_end_master_slave()
;
If no tasks are outstanding, returns false immediately. Otherwise, it
blocks until a task does return. It calls application
callback, CheckTaskResult()
, and then returns true.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Assume that we are parallelizing a code fragment of the following form.
The variables i
and j
will be the input to
DoTask()
, and any data structures indexed by i
and
j
(for example array
in array[i][j]
) will be
part of the shared data.
float array[ROWS][COLS]; ... for ( i = 0; i < 10; i++ ) { for ( j = 0; j < 10; j++ ) { /* do_task: */ ... /* update: */ array[i][j] = ...; } } |
Assume that the labels do_task
and update
above
correspond to the callback functions DoTask()
and
UpdateSharedData()
. Then the code is parallelized below.
float array[ROWS][COLS]; typedef struct {int i_val; int j_val;} input_t; void *DoTask(input_t *buf) { int i = (*buf).i_val, j = (*buf).j_val; /* do_task: */ ... } void *CheckTaskResult(input_t *buf, output_t *buf2) { /* update: */ array[i][j] = ...; return NO_ACTION; } main(int argc, char **argv) { TOPC_init( &argc, &argv ); TOPC_raw_begin_master_slave(DoTask, CheckTaskResult, UpdateSharedData); if (TOPC_is_master()) { for ( i = 0; i < 10; i++ ) { for ( j = 0; j < 10; j++ ) { input_t input; input.i_val = i; input.j_val = j; TOPC_raw_submit_task_input( TOPC_MSG(&input, sizeof(input)) ); } } } TOPC_raw_end_master_slave(); TOPC_finalize(); } |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Assume that we are parallelizing a code fragment of the following form
and input
is a pointer.
while ( (input = next_input()) != NULL ) { /* do_task: */ ... /* update: */ ... } |
Assume that the labels do_task
and update
above
correspond to the callback functions DoTask()
and
UpdateSharedData()
. Then the code is parallelized below,
where input_size
must be specified by the application before it
is used.
TOPC_init( &argc, &argv ); TOPC_raw_begin_master_slave(DoTask, CheckTaskResult, UpdateSharedData); if (TOPC_is_master()) { while ( (input = next_input()) != NULL || TOPC_raw_wait_for_task_result() ) { TOPC_raw_submit_task_input( TOPC_MSG(input, input_size) ); } } TOPC_raw_end_master_slave(); TOPC_finalize(); |
Note that the code inside the raw begin/end block is executed only by the master in the code above.
If the buffer, input
, contains pointers to other data, then you
will need to marshal the data before calling TOPC_MSG()
.
See section Marshaling and Heterogeneous Architectures.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |