| [ < ] | [ > ] | [ << ] | [ 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] | [ ? ] |