Compare commits
4 Commits
ompstream-
...
master
Author | SHA1 | Date |
---|---|---|
Thomas Preud'homme | c1f0f59491 | |
Thomas Preud'homme | 8eb6e4a338 | |
Thomas Preud'homme | 7545a6222c | |
Thomas Preud'homme | 57ff7e16b6 |
|
@ -210,12 +210,21 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_END, "GOMP_single_copy_end",
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_STREAM,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_STREAM,
|
||||||
"GOMP_stream_create_stream",
|
"GOMP_stream_create_stream",
|
||||||
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_CREATE_STREAM,
|
||||||
|
"GOMP_batchQ_create_stream",
|
||||||
|
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_READ_VIEW,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_READ_VIEW,
|
||||||
"GOMP_stream_create_read_view",
|
"GOMP_stream_create_read_view",
|
||||||
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_CREATE_READ_VIEW,
|
||||||
|
"GOMP_batchQ_create_read_view",
|
||||||
|
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_WRITE_VIEW,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_WRITE_VIEW,
|
||||||
"GOMP_stream_create_write_view",
|
"GOMP_stream_create_write_view",
|
||||||
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_CREATE_WRITE_VIEW,
|
||||||
|
"GOMP_batchQ_create_write_view",
|
||||||
|
BT_FN_PTR_SIZE_SIZE, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_TASK,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CREATE_TASK,
|
||||||
"GOMP_stream_create_task",
|
"GOMP_stream_create_task",
|
||||||
BT_FN_PTR, ATTR_NOTHROW_LIST)
|
BT_FN_PTR, ATTR_NOTHROW_LIST)
|
||||||
|
@ -234,6 +243,9 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS,
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CONNECT_VIEW,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_CONNECT_VIEW,
|
||||||
"GOMP_stream_connect_view",
|
"GOMP_stream_connect_view",
|
||||||
BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
|
BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_CONNECT_VIEW,
|
||||||
|
"GOMP_batchQ_connect_view",
|
||||||
|
BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_WAIT_UNTIL_CONNECTED,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_WAIT_UNTIL_CONNECTED,
|
||||||
"GOMP_stream_wait_until_connected",
|
"GOMP_stream_wait_until_connected",
|
||||||
BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
||||||
|
@ -242,12 +254,20 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_GET_AVAILABLE_WORK,
|
||||||
BT_FN_ULL_PTR_ULL, ATTR_NOTHROW_LIST)
|
BT_FN_ULL_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_UPDATE, "GOMP_stream_update",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_UPDATE, "GOMP_stream_update",
|
||||||
BT_FN_PTR_PTR_ULL_ULL, ATTR_NOTHROW_LIST)
|
BT_FN_PTR_PTR_ULL_ULL, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_UPDATE, "GOMP_batchQ_update",
|
||||||
|
BT_FN_PTR_PTR_ULL_ULL, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_STALL, "GOMP_stream_stall",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_STALL, "GOMP_stream_stall",
|
||||||
BT_FN_PTR_PTR_ULL_ULL, ATTR_NOTHROW_LIST)
|
BT_FN_PTR_PTR_ULL_ULL, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_STALL, "GOMP_batchQ_stall",
|
||||||
|
BT_FN_PTR_PTR_ULL_ULL, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_RELEASE, "GOMP_stream_release",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_RELEASE, "GOMP_stream_release",
|
||||||
BT_FN_VOID_PTR_ULL, ATTR_NOTHROW_LIST)
|
BT_FN_VOID_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_RELEASE, "GOMP_batchQ_release",
|
||||||
|
BT_FN_VOID_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_COMMIT, "GOMP_stream_commit",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_COMMIT, "GOMP_stream_commit",
|
||||||
BT_FN_VOID_PTR_ULL, ATTR_NOTHROW_LIST)
|
BT_FN_VOID_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_COMMIT, "GOMP_batchQ_commit",
|
||||||
|
BT_FN_VOID_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_TASK_EXIT, "GOMP_stream_task_exit",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_TASK_EXIT, "GOMP_stream_task_exit",
|
||||||
BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
||||||
|
|
||||||
|
@ -275,6 +295,8 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_EXIT, "GOMP_stream_exit",
|
||||||
BT_FN_VOID, ATTR_NOTHROW_LIST)
|
BT_FN_VOID, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_PRE, "GOMP_stream_pre",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_PRE, "GOMP_stream_pre",
|
||||||
BT_FN_PTR_PTR_ULL, ATTR_NOTHROW_LIST)
|
BT_FN_PTR_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BATCHQ_PRE, "GOMP_batchQ_pre",
|
||||||
|
BT_FN_PTR_PTR_ULL, ATTR_NOTHROW_LIST)
|
||||||
|
|
||||||
|
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_PUSH_STUB, "GOMP_stream_push_stub",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_STREAM_PUSH_STUB, "GOMP_stream_push_stub",
|
||||||
|
|
352
gcc/omp-low.c
352
gcc/omp-low.c
|
@ -78,6 +78,8 @@ Supported types are currently:
|
||||||
#include "optabs.h"
|
#include "optabs.h"
|
||||||
#include "cfgloop.h"
|
#include "cfgloop.h"
|
||||||
|
|
||||||
|
#define BATCHQ_ENABLED
|
||||||
|
|
||||||
/* Return the entry edge of a conditional block (true branch). */
|
/* Return the entry edge of a conditional block (true branch). */
|
||||||
|
|
||||||
static edge
|
static edge
|
||||||
|
@ -434,6 +436,11 @@ typedef struct stream
|
||||||
/* Used for traversals */
|
/* Used for traversals */
|
||||||
bool visit;
|
bool visit;
|
||||||
|
|
||||||
|
#ifdef BATCHQ_ENABLED
|
||||||
|
/* Used for BatchQ */
|
||||||
|
bool use_batchQ;
|
||||||
|
#endif
|
||||||
|
|
||||||
} stream_t;
|
} stream_t;
|
||||||
|
|
||||||
#define TYPE_SIZE_HAS_INT(TYPE) \
|
#define TYPE_SIZE_HAS_INT(TYPE) \
|
||||||
|
@ -4792,7 +4799,38 @@ expand_steaming_taskreg_in_outer_context (omp_region_p region,
|
||||||
/* Create firstprivate views and pass the pointers as well. */
|
/* Create firstprivate views and pass the pointers as well. */
|
||||||
for (i = 0; VEC_iterate (view_p, sinfo->fpviews, i, view); ++i)
|
for (i = 0; VEC_iterate (view_p, sinfo->fpviews, i, view); ++i)
|
||||||
{
|
{
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_WRITE_VIEW];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
int j, nb_associated_views = 0;
|
||||||
|
view_p aview;
|
||||||
|
|
||||||
|
for (j = 0; VEC_iterate (view_p, view->stream->rviews, j, aview); ++j)
|
||||||
|
{
|
||||||
|
if (INTEGER_CST_CHECK(aview->sinfo->num_instances))
|
||||||
|
nb_associated_views += TREE_INT_CST_LOW(aview->sinfo->num_instances);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Ensure we use generic functions */
|
||||||
|
nb_associated_views ++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Pretty sure this for loop is useless */
|
||||||
|
for (j = 0; VEC_iterate (view_p, view->stream->wviews, j, aview); ++j)
|
||||||
|
{
|
||||||
|
if (INTEGER_CST_CHECK(aview->sinfo->num_instances))
|
||||||
|
nb_associated_views += TREE_INT_CST_LOW(aview->sinfo->num_instances);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Ensure we use generic functions */
|
||||||
|
nb_associated_views ++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nb_associated_views == 1)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CREATE_WRITE_VIEW];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_WRITE_VIEW];
|
||||||
stmt = gimple_build_call (fn, 2, view->view_size, get_view_burst_size (view, &gsi));
|
stmt = gimple_build_call (fn, 2, view->view_size, get_view_burst_size (view, &gsi));
|
||||||
gimple_call_set_lhs (stmt, view->view);
|
gimple_call_set_lhs (stmt, view->view);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
@ -4926,12 +4964,22 @@ expand_steaming_taskreg_in_outer_context (omp_region_p region,
|
||||||
|
|
||||||
/* COMMIT */
|
/* COMMIT */
|
||||||
gsi = gsi_last_bb (commit_bb);
|
gsi = gsi_last_bb (commit_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_COMMIT];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_COMMIT];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_COMMIT];
|
||||||
stmt = gimple_build_call (fn, 2, view_decl, task->local_activation_index);
|
stmt = gimple_build_call (fn, 2, view_decl, task->local_activation_index);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
/* STALL */
|
/* STALL */
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_STALL];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_STALL];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_STALL];
|
||||||
stmt = gimple_build_call (fn, 3, view_decl, task->local_activation_index,
|
stmt = gimple_build_call (fn, 3, view_decl, task->local_activation_index,
|
||||||
task->local_activation_index_next);
|
task->local_activation_index_next);
|
||||||
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
||||||
|
@ -5057,7 +5105,12 @@ handle_nested_streaming_tasks (omp_region_p region,
|
||||||
|
|
||||||
/* STALL */
|
/* STALL */
|
||||||
gsi = gsi_last_bb (initialization_bb);
|
gsi = gsi_last_bb (initialization_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_STALL];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_STALL];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_STALL];
|
||||||
stmt = gimple_build_call (fn, 3, view_decl, task->local_activation_index,
|
stmt = gimple_build_call (fn, 3, view_decl, task->local_activation_index,
|
||||||
task->local_activation_index_next);
|
task->local_activation_index_next);
|
||||||
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
||||||
|
@ -5065,7 +5118,12 @@ handle_nested_streaming_tasks (omp_region_p region,
|
||||||
|
|
||||||
/* COMMIT */
|
/* COMMIT */
|
||||||
gsi = gsi_last_bb (finalization_bb);
|
gsi = gsi_last_bb (finalization_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_COMMIT];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_COMMIT];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_COMMIT];
|
||||||
stmt = gimple_build_call (fn, 2, view_decl, task->local_activation_index);
|
stmt = gimple_build_call (fn, 2, view_decl, task->local_activation_index);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
}
|
}
|
||||||
|
@ -7633,26 +7691,46 @@ build_task_control_loop (streamization_info_p task)
|
||||||
for (i = 0; VEC_iterate (view_p, task->rviews, i, view); ++i)
|
for (i = 0; VEC_iterate (view_p, task->rviews, i, view); ++i)
|
||||||
{
|
{
|
||||||
gsi = gsi_last_bb (loop_acquire_bb);
|
gsi = gsi_last_bb (loop_acquire_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_UPDATE];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_UPDATE];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_UPDATE];
|
||||||
stmt = gimple_build_call (fn, 3, view->view, act_idx_start_reg, act_idx_end_reg);
|
stmt = gimple_build_call (fn, 3, view->view, act_idx_start_reg, act_idx_end_reg);
|
||||||
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
gsi = gsi_last_bb (loop_release_bb);
|
gsi = gsi_last_bb (loop_release_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_RELEASE];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_RELEASE];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_RELEASE];
|
||||||
stmt = gimple_build_call (fn, 2, view->view, act_idx_end_reg);
|
stmt = gimple_build_call (fn, 2, view->view, act_idx_end_reg);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
}
|
}
|
||||||
for (i = 0; VEC_iterate (view_p, task->wviews, i, view); ++i)
|
for (i = 0; VEC_iterate (view_p, task->wviews, i, view); ++i)
|
||||||
{
|
{
|
||||||
gsi = gsi_last_bb (loop_acquire_bb);
|
gsi = gsi_last_bb (loop_acquire_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_STALL];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_STALL];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_STALL];
|
||||||
stmt = gimple_build_call (fn, 3, view->view, act_idx_start_reg, act_idx_end_reg);
|
stmt = gimple_build_call (fn, 3, view->view, act_idx_start_reg, act_idx_end_reg);
|
||||||
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
gsi = gsi_last_bb (loop_release_bb);
|
gsi = gsi_last_bb (loop_release_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_COMMIT];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_COMMIT];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_COMMIT];
|
||||||
stmt = gimple_build_call (fn, 2, view->view, act_idx_end_reg);
|
stmt = gimple_build_call (fn, 2, view->view, act_idx_end_reg);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
}
|
}
|
||||||
|
@ -7789,72 +7867,205 @@ prepare_streaming_context (omp_region_p region)
|
||||||
parallel region. */
|
parallel region. */
|
||||||
for (i = 0; VEC_iterate (stream_p, sinfo->streams, i, stream); ++i)
|
for (i = 0; VEC_iterate (stream_p, sinfo->streams, i, stream); ++i)
|
||||||
{
|
{
|
||||||
tree type_size = TYPE_SIZE_UNIT (stream->element_type);
|
int nb_views = 0, nb_rviews = 0, nb_wviews = 0;
|
||||||
tree horizon_size = build_int_cst (size_type_node,
|
|
||||||
HORIZON);
|
|
||||||
|
|
||||||
gsi = gsi_last_bb (sinfo->initialization_bb);
|
#ifdef BATCHQ_ENABLED
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_STREAM];
|
stream->use_batchQ = 0;
|
||||||
stmt = gimple_build_call (fn, 2, type_size, horizon_size);
|
#endif
|
||||||
gimple_call_set_lhs (stmt, stream->stream);
|
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
|
||||||
|
|
||||||
/* FIXME: this needs to take into account
|
|
||||||
replication as well ... we may want to move this
|
|
||||||
in the task call itself if we want dynamic values
|
|
||||||
as well. */
|
|
||||||
for (j = 0; VEC_iterate (view_p, stream->rviews, j, view); ++j)
|
for (j = 0; VEC_iterate (view_p, stream->rviews, j, view); ++j)
|
||||||
{
|
{
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
if (INTEGER_CST_CHECK(view->sinfo->num_instances))
|
||||||
stmt = gimple_build_call (fn, 4, stream->stream,
|
{
|
||||||
view->sinfo->num_instances,
|
nb_views += TREE_INT_CST_LOW(view->sinfo->num_instances);
|
||||||
integer_zero_node,
|
nb_rviews += TREE_INT_CST_LOW(view->sinfo->num_instances);
|
||||||
boolean_false_node);
|
}
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
else
|
||||||
|
{
|
||||||
|
/* Ensure we use generic functions */
|
||||||
|
nb_views += 2;
|
||||||
|
nb_rviews += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (j = 0; VEC_iterate (view_p, stream->wviews, j, view); ++j)
|
for (j = 0; VEC_iterate (view_p, stream->wviews, j, view); ++j)
|
||||||
{
|
{
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
if (INTEGER_CST_CHECK(view->sinfo->num_instances))
|
||||||
stmt = gimple_build_call (fn, 4, stream->stream,
|
{
|
||||||
integer_zero_node,
|
nb_views += TREE_INT_CST_LOW(view->sinfo->num_instances);
|
||||||
view->sinfo->num_instances,
|
nb_wviews += TREE_INT_CST_LOW(view->sinfo->num_instances);
|
||||||
boolean_false_node);
|
}
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
else
|
||||||
|
{
|
||||||
|
/* Ensure we use generic functions */
|
||||||
|
nb_views += 2;
|
||||||
|
nb_wviews += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect any firstprivate write views on this
|
/* Connect any firstprivate write views on this
|
||||||
stream. As these are the master views, they only
|
stream. As these are the master views, they only
|
||||||
get one instance. */
|
get one instance. */
|
||||||
for (j = 0; VEC_iterate (view_p, stream->fpviews, j, view); ++j)
|
for (j = 0; VEC_iterate (view_p, stream->fpviews, j, view); ++j)
|
||||||
{
|
{
|
||||||
tree view_decl = lookup_var (view->view, sinfo->stmt);
|
|
||||||
|
|
||||||
/* Only one firstprivate view per stream possible. */
|
/* Only one firstprivate view per stream possible. */
|
||||||
gcc_assert (j == 0);
|
gcc_assert (j == 0);
|
||||||
/* If there are firstprivate views, there should be no write views. */
|
/* If there are firstprivate views, there should be no write views. */
|
||||||
gcc_assert (VEC_empty (view_p, stream->wviews));
|
gcc_assert (VEC_empty (view_p, stream->wviews));
|
||||||
|
nb_views ++;
|
||||||
|
nb_wviews ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (nb_views == 2)
|
||||||
|
stream->use_batchQ = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tree type_size = TYPE_SIZE_UNIT (stream->element_type);
|
||||||
|
tree horizon_size;
|
||||||
|
tree read_burst_size, write_burst_size, burst_size;
|
||||||
|
view_p rview, wview;
|
||||||
|
|
||||||
|
gsi = gsi_last_bb (sinfo->initialization_bb);
|
||||||
|
horizon_size = create_tmp_var (size_type_node,
|
||||||
|
"horizon_size");
|
||||||
|
burst_size = create_tmp_var (size_type_node,
|
||||||
|
"burst_size");
|
||||||
|
rview = VEC_index(view_p, stream->rviews, 0);
|
||||||
|
read_burst_size = get_view_burst_size (rview, &gsi);
|
||||||
|
if (VEC_empty (view_p, stream->wviews))
|
||||||
|
wview = VEC_index(view_p, stream->fpviews, 0);
|
||||||
|
else
|
||||||
|
wview = VEC_index(view_p, stream->wviews, 0);
|
||||||
|
write_burst_size = get_view_burst_size (wview, &gsi);
|
||||||
|
stmt = gimple_build_assign_with_ops (MAX_EXPR,
|
||||||
|
burst_size,
|
||||||
|
read_burst_size,
|
||||||
|
write_burst_size);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
/* MAX(read_burst_size, write_burst_size) / type_size */
|
||||||
|
stmt = gimple_build_assign_with_ops (CEIL_DIV_EXPR,
|
||||||
|
horizon_size,
|
||||||
|
burst_size,
|
||||||
|
type_size);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CREATE_STREAM];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
tree aggregation_factor, nbwviewscst, nbrviewscst;
|
||||||
|
tree max_nbviews;
|
||||||
|
|
||||||
|
aggregation_factor = build_int_cst (size_type_node,
|
||||||
|
AGGREGATION_FACTOR);
|
||||||
|
nbwviewscst = build_int_cst (size_type_node, nb_wviews);
|
||||||
|
nbrviewscst = build_int_cst (size_type_node, nb_rviews);
|
||||||
|
max_nbviews = create_tmp_var (size_type_node,
|
||||||
|
"max_nbviews");
|
||||||
|
stmt = gimple_build_assign_with_ops (MAX_EXPR,
|
||||||
|
max_nbviews,
|
||||||
|
nbrviewscst,
|
||||||
|
nbrviewscst);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
stmt = gimple_build_assign_with_ops (MULT_EXPR,
|
||||||
|
horizon_size,
|
||||||
|
horizon_size,
|
||||||
|
max_nbviews);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
stmt = gimple_build_assign_with_ops (MULT_EXPR,
|
||||||
|
horizon_size,
|
||||||
|
horizon_size,
|
||||||
|
aggregation_factor);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_STREAM];
|
||||||
|
#ifdef BATCHQ_ENABLED
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
stmt = gimple_build_call (fn, 2, type_size, horizon_size);
|
||||||
|
gimple_call_set_lhs (stmt, stream->stream);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
|
/* FIXME: this needs to take into account
|
||||||
|
replication as well ... we may want to move this
|
||||||
|
in the task call itself if we want dynamic values
|
||||||
|
as well. */
|
||||||
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (stream->use_batchQ)
|
||||||
|
{
|
||||||
|
/* Connect any firstprivate write views on this
|
||||||
|
stream. As these are the master views, they only
|
||||||
|
get one instance. */
|
||||||
|
for (j = 0; VEC_iterate (view_p, stream->fpviews, j, view); ++j)
|
||||||
|
{
|
||||||
|
tree view_decl = lookup_var (view->view, sinfo->stmt);
|
||||||
|
|
||||||
|
/* Only one firstprivate view per stream possible. */
|
||||||
|
gcc_assert (j == 0);
|
||||||
|
/* If there are firstprivate views, there should be no write views. */
|
||||||
|
gcc_assert (VEC_empty (view_p, stream->wviews));
|
||||||
|
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CONNECT_VIEW];
|
||||||
|
stmt = gimple_build_call (fn, 3, task_decl, stream->stream, view_decl);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (j = 0; VEC_iterate (view_p, stream->rviews, j, view); ++j)
|
||||||
|
{
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
||||||
|
stmt = gimple_build_call (fn, 4, stream->stream,
|
||||||
|
view->sinfo->num_instances,
|
||||||
|
integer_zero_node,
|
||||||
|
boolean_false_node);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
}
|
||||||
|
for (j = 0; VEC_iterate (view_p, stream->wviews, j, view); ++j)
|
||||||
|
{
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
||||||
|
stmt = gimple_build_call (fn, 4, stream->stream,
|
||||||
|
integer_zero_node,
|
||||||
|
view->sinfo->num_instances,
|
||||||
|
boolean_false_node);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect any firstprivate write views on this
|
||||||
|
stream. As these are the master views, they only
|
||||||
|
get one instance. */
|
||||||
|
for (j = 0; VEC_iterate (view_p, stream->fpviews, j, view); ++j)
|
||||||
|
{
|
||||||
|
tree view_decl = lookup_var (view->view, sinfo->stmt);
|
||||||
|
|
||||||
|
/* Only one firstprivate view per stream possible. */
|
||||||
|
gcc_assert (j == 0);
|
||||||
|
/* If there are firstprivate views, there should be no write views. */
|
||||||
|
gcc_assert (VEC_empty (view_p, stream->wviews));
|
||||||
|
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
||||||
|
stmt = gimple_build_call (fn, 4, stream->stream,
|
||||||
|
integer_zero_node,
|
||||||
|
integer_one_node,
|
||||||
|
boolean_false_node);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CONNECT_VIEW];
|
||||||
|
stmt = gimple_build_call (fn, 3, task_decl, stream->stream, view_decl);
|
||||||
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the final count flag for the number of
|
||||||
|
expected views. */
|
||||||
|
gsi = gsi_last_bb (sinfo->post_initialization_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
||||||
stmt = gimple_build_call (fn, 4, stream->stream,
|
stmt = gimple_build_call (fn, 4, stream->stream,
|
||||||
integer_zero_node,
|
integer_zero_node,
|
||||||
integer_one_node,
|
integer_zero_node,
|
||||||
boolean_false_node);
|
boolean_true_node);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
|
||||||
|
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CONNECT_VIEW];
|
|
||||||
stmt = gimple_build_call (fn, 3, task_decl, stream->stream, view_decl);
|
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the final count flag for the number of
|
|
||||||
expected views. */
|
|
||||||
gsi = gsi_last_bb (sinfo->post_initialization_bb);
|
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_ADD_EXPECTED_VIEWS];
|
|
||||||
stmt = gimple_build_call (fn, 4, stream->stream,
|
|
||||||
integer_zero_node,
|
|
||||||
integer_zero_node,
|
|
||||||
boolean_true_node);
|
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Issue wait until connected call in the parallel
|
/* Issue wait until connected call in the parallel
|
||||||
|
@ -7972,7 +8183,12 @@ prepare_streaming_context (omp_region_p region)
|
||||||
single threaded code before the other producer or any
|
single threaded code before the other producer or any
|
||||||
consumer can start. */
|
consumer can start. */
|
||||||
gsi = gsi_last_bb (task->initialization_bb);
|
gsi = gsi_last_bb (task->initialization_bb);
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_PRE];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_PRE];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_PRE];
|
||||||
stmt = gimple_build_call (fn, 2, view->stream->stream, get_view_burst_size (view, &gsi));
|
stmt = gimple_build_call (fn, 2, view->stream->stream, get_view_burst_size (view, &gsi));
|
||||||
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
gimple_call_set_lhs (stmt, view->buffer_pointer);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
@ -8078,12 +8294,22 @@ prepare_streaming_context (omp_region_p region)
|
||||||
gsi = gsi_last_bb (task->initialization_bb);
|
gsi = gsi_last_bb (task->initialization_bb);
|
||||||
for (i = 0; VEC_iterate (view_p, task->rviews, i, view); ++i)
|
for (i = 0; VEC_iterate (view_p, task->rviews, i, view); ++i)
|
||||||
{
|
{
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_READ_VIEW];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CREATE_READ_VIEW];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_READ_VIEW];
|
||||||
stmt = gimple_build_call (fn, 2, view->view_size, get_view_burst_size (view, &gsi));
|
stmt = gimple_build_call (fn, 2, view->view_size, get_view_burst_size (view, &gsi));
|
||||||
gimple_call_set_lhs (stmt, view->view);
|
gimple_call_set_lhs (stmt, view->view);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CONNECT_VIEW];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CONNECT_VIEW];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CONNECT_VIEW];
|
||||||
stmt = gimple_build_call (fn, 3, task_decl, view->stream->stream, view->view);
|
stmt = gimple_build_call (fn, 3, task_decl, view->stream->stream, view->view);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
|
@ -8091,12 +8317,22 @@ prepare_streaming_context (omp_region_p region)
|
||||||
|
|
||||||
for (i = 0; VEC_iterate (view_p, task->wviews, i, view); ++i)
|
for (i = 0; VEC_iterate (view_p, task->wviews, i, view); ++i)
|
||||||
{
|
{
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_WRITE_VIEW];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CREATE_WRITE_VIEW];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CREATE_WRITE_VIEW];
|
||||||
stmt = gimple_build_call (fn, 2, view->view_size, get_view_burst_size (view, &gsi));
|
stmt = gimple_build_call (fn, 2, view->view_size, get_view_burst_size (view, &gsi));
|
||||||
gimple_call_set_lhs (stmt, view->view);
|
gimple_call_set_lhs (stmt, view->view);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CONNECT_VIEW];
|
#ifdef BATCHQ_ENABLED
|
||||||
|
if (view->stream->use_batchQ)
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_BATCHQ_CONNECT_VIEW];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fn = built_in_decls[BUILT_IN_GOMP_STREAM_CONNECT_VIEW];
|
||||||
stmt = gimple_build_call (fn, 3, task_decl, view->stream->stream, view->view);
|
stmt = gimple_build_call (fn, 3, task_decl, view->stream->stream, view->view);
|
||||||
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,20 +168,28 @@ GOMP_2.0 {
|
||||||
GOMP_loop_ull_static_next;
|
GOMP_loop_ull_static_next;
|
||||||
GOMP_loop_ull_static_start;
|
GOMP_loop_ull_static_start;
|
||||||
GOMP_stream_create_stream;
|
GOMP_stream_create_stream;
|
||||||
|
GOMP_batchQ_create_stream;
|
||||||
GOMP_stream_create_read_view;
|
GOMP_stream_create_read_view;
|
||||||
|
GOMP_batchQ_create_read_view;
|
||||||
GOMP_stream_create_write_view;
|
GOMP_stream_create_write_view;
|
||||||
|
GOMP_batchQ_create_write_view;
|
||||||
GOMP_stream_create_task;
|
GOMP_stream_create_task;
|
||||||
GOMP_stream_get_task_activation_counter;
|
GOMP_stream_get_task_activation_counter;
|
||||||
GOMP_stream_set_task_termination_flag;
|
GOMP_stream_set_task_termination_flag;
|
||||||
GOMP_stream_task_add_instance;
|
GOMP_stream_task_add_instance;
|
||||||
GOMP_stream_add_expected_views;
|
GOMP_stream_add_expected_views;
|
||||||
GOMP_stream_connect_view;
|
GOMP_stream_connect_view;
|
||||||
|
GOMP_batchQ_connect_view;
|
||||||
GOMP_stream_wait_until_connected;
|
GOMP_stream_wait_until_connected;
|
||||||
GOMP_stream_get_available_work;
|
GOMP_stream_get_available_work;
|
||||||
GOMP_stream_update;
|
GOMP_stream_update;
|
||||||
|
GOMP_batchQ_update;
|
||||||
GOMP_stream_stall;
|
GOMP_stream_stall;
|
||||||
|
GOMP_batchQ_stall;
|
||||||
GOMP_stream_release;
|
GOMP_stream_release;
|
||||||
|
GOMP_batchQ_release;
|
||||||
GOMP_stream_commit;
|
GOMP_stream_commit;
|
||||||
|
GOMP_batchQ_commit;
|
||||||
GOMP_stream_task_exit;
|
GOMP_stream_task_exit;
|
||||||
GOMP_stream_create_control_stream;
|
GOMP_stream_create_control_stream;
|
||||||
GOMP_stream_control_stream_set_eos;
|
GOMP_stream_control_stream_set_eos;
|
||||||
|
@ -191,5 +199,6 @@ GOMP_2.0 {
|
||||||
GOMP_stream_init;
|
GOMP_stream_init;
|
||||||
GOMP_stream_exit;
|
GOMP_stream_exit;
|
||||||
GOMP_stream_pre;
|
GOMP_stream_pre;
|
||||||
|
GOMP_batchQ_pre;
|
||||||
} GOMP_1.0;
|
} GOMP_1.0;
|
||||||
|
|
||||||
|
|
|
@ -109,12 +109,17 @@ int omp_get_active_level (void) __GOMP_NOTHROW;
|
||||||
|
|
||||||
extern void *GOMP_stream_create_stream (size_t, size_t)
|
extern void *GOMP_stream_create_stream (size_t, size_t)
|
||||||
__GOMP_NOTHROW;
|
__GOMP_NOTHROW;
|
||||||
|
extern void *GOMP_batchQ_create_stream (size_t, size_t)
|
||||||
|
__GOMP_NOTHROW;
|
||||||
extern void *GOMP_stream_create_read_view (size_t, size_t) __GOMP_NOTHROW;
|
extern void *GOMP_stream_create_read_view (size_t, size_t) __GOMP_NOTHROW;
|
||||||
|
extern void *GOMP_batchQ_create_read_view (size_t, size_t) __GOMP_NOTHROW;
|
||||||
extern void *GOMP_stream_create_write_view (size_t, size_t) __GOMP_NOTHROW;
|
extern void *GOMP_stream_create_write_view (size_t, size_t) __GOMP_NOTHROW;
|
||||||
|
extern void *GOMP_batchQ_create_write_view (size_t, size_t) __GOMP_NOTHROW;
|
||||||
extern void *GOMP_stream_create_task (void) __GOMP_NOTHROW;
|
extern void *GOMP_stream_create_task (void) __GOMP_NOTHROW;
|
||||||
extern void GOMP_stream_add_expected_views (void *, int, int, int)
|
extern void GOMP_stream_add_expected_views (void *, int, int, int)
|
||||||
__GOMP_NOTHROW;
|
__GOMP_NOTHROW;
|
||||||
extern void GOMP_stream_connect_view (void *, void *, void *) __GOMP_NOTHROW;
|
extern void GOMP_stream_connect_view (void *, void *, void *) __GOMP_NOTHROW;
|
||||||
|
extern void GOMP_batchQ_connect_view (void *, void *, void *) __GOMP_NOTHROW;
|
||||||
extern void GOMP_stream_wait_until_connected (void *) __GOMP_NOTHROW;
|
extern void GOMP_stream_wait_until_connected (void *) __GOMP_NOTHROW;
|
||||||
extern unsigned long long GOMP_stream_get_available_work (void *,
|
extern unsigned long long GOMP_stream_get_available_work (void *,
|
||||||
unsigned long long *)
|
unsigned long long *)
|
||||||
|
@ -123,13 +128,24 @@ extern void *GOMP_stream_update (void *,
|
||||||
const unsigned long long,
|
const unsigned long long,
|
||||||
const unsigned long long)
|
const unsigned long long)
|
||||||
__GOMP_NOTHROW;
|
__GOMP_NOTHROW;
|
||||||
|
extern void *GOMP_batchQ_update (void *,
|
||||||
|
const unsigned long long,
|
||||||
|
const unsigned long long)
|
||||||
|
__GOMP_NOTHROW;
|
||||||
extern void *GOMP_stream_stall (void *, const unsigned long long,
|
extern void *GOMP_stream_stall (void *, const unsigned long long,
|
||||||
const unsigned long long)
|
const unsigned long long)
|
||||||
__GOMP_NOTHROW;
|
__GOMP_NOTHROW;
|
||||||
|
extern void *GOMP_batchQ_stall (void *, const unsigned long long,
|
||||||
|
const unsigned long long)
|
||||||
|
__GOMP_NOTHROW;
|
||||||
extern void GOMP_stream_release (void *, const unsigned long long)
|
extern void GOMP_stream_release (void *, const unsigned long long)
|
||||||
__GOMP_NOTHROW;
|
__GOMP_NOTHROW;
|
||||||
|
extern void GOMP_batchQ_release (void *, const unsigned long long)
|
||||||
|
__GOMP_NOTHROW;
|
||||||
extern void GOMP_stream_commit (void *, const unsigned long long)
|
extern void GOMP_stream_commit (void *, const unsigned long long)
|
||||||
__GOMP_NOTHROW;
|
__GOMP_NOTHROW;
|
||||||
|
extern void GOMP_batchQ_commit (void *, const unsigned long long)
|
||||||
|
__GOMP_NOTHROW;
|
||||||
extern void GOMP_stream_task_exit (void *) __GOMP_NOTHROW;
|
extern void GOMP_stream_task_exit (void *) __GOMP_NOTHROW;
|
||||||
|
|
||||||
#endif /* OMP_H */
|
#endif /* OMP_H */
|
||||||
|
|
353
libgomp/stream.c
353
libgomp/stream.c
|
@ -1,5 +1,6 @@
|
||||||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
Contributed by Antoniu Pop <antoniu.pop@gmail.com>.
|
Contributed by Antoniu Pop <antoniu.pop@gmail.com>
|
||||||
|
and Thomas Preud'homme <thomas.preud-homme@lip6.fr>.
|
||||||
|
|
||||||
This file is part of the GNU OpenMP Library (libgomp).
|
This file is part of the GNU OpenMP Library (libgomp).
|
||||||
|
|
||||||
|
@ -30,6 +31,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
#include "sem.h"
|
#include "sem.h"
|
||||||
|
@ -38,14 +43,23 @@
|
||||||
|
|
||||||
#define AGGREGATION_FACTOR 32
|
#define AGGREGATION_FACTOR 32
|
||||||
|
|
||||||
//#define debug_log_init(S, V1, V2) printf (S, V1, V2); fflush (stdout)
|
#define ENSURE_BUFSIZE
|
||||||
#define debug_log_init(S, V1, V2)
|
//#define OMP_STREAM_DEBUG
|
||||||
|
#ifdef OMP_STREAM_DEBUG
|
||||||
//#define debug_log_init3(S, V1, V2, V3) printf (S, V1, V2, V3); fflush (stdout)
|
#define debug_log_init(S, V1, V2) printf (S, V1, V2); fflush (stdout)
|
||||||
#define debug_log_init3(S, V1, V2, V3)
|
#define debug_log_init3(S, V1, V2, V3) printf (S, V1, V2, V3); fflush (stdout)
|
||||||
|
#define debug_log(S, V1, V2) printf (S, V1, V2); fflush (stdout)
|
||||||
//#define debug_log(S, V1, V2) printf (S, V1, V2); fflush (stdout)
|
#define debug_log3(S, V1, V2, V3) printf (S, V1, V2, V3); fflush (stdout)
|
||||||
#define debug_log(S, V1, V2)
|
#define debug_log4(S, V1, V2, V3, V4) printf (S, V1, V2, V3, V4); fflush (stdout)
|
||||||
|
#define debug_log5(S, V1, V2, V3, V4, V5) printf (S, V1, V2, V3, V4, V5); fflush (stdout)
|
||||||
|
#else
|
||||||
|
#define debug_log_init(S, V1, V2)
|
||||||
|
#define debug_log_init3(S, V1, V2, V3)
|
||||||
|
#define debug_log(S, V1, V2)
|
||||||
|
#define debug_log3(S, V1, V2, V3)
|
||||||
|
#define debug_log4(S, V1, V2, V3, V4)
|
||||||
|
#define debug_log5(S, V1, V2, V3, V4, V5)
|
||||||
|
#endif
|
||||||
|
|
||||||
gomp_barrier_t gomp_stream_tasks_wait_until_connected_barrier;
|
gomp_barrier_t gomp_stream_tasks_wait_until_connected_barrier;
|
||||||
gomp_barrier_t gomp_stream_tasks_exit_barrier;
|
gomp_barrier_t gomp_stream_tasks_exit_barrier;
|
||||||
|
@ -126,6 +140,89 @@ GOMP_stream_create_stream (size_t element_size, size_t buffer_size)
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
GOMP_batchQ_create_stream (size_t element_size, size_t buffer_size)
|
||||||
|
{
|
||||||
|
#define BASE_SHM_NAME "/channel"
|
||||||
|
#define ROUNDUP(size) ((size + page_size) & ~(page_size - 1))
|
||||||
|
int ret, shm_fd;
|
||||||
|
static int chan_idx = 0;
|
||||||
|
char shm_name[NAME_MAX];
|
||||||
|
struct gomp_batchQ *stream;
|
||||||
|
size_t buffer_realsize, bq_size;
|
||||||
|
unsigned int page_size;
|
||||||
|
|
||||||
|
buffer_size *= element_size * AGGREGATION_FACTOR;
|
||||||
|
buffer_realsize = 1;
|
||||||
|
while(buffer_realsize < buffer_size)
|
||||||
|
buffer_realsize <<= 1;
|
||||||
|
|
||||||
|
/* Beginning of BatchQueue code */
|
||||||
|
stream = NULL;
|
||||||
|
ret = sysconf(_SC_PAGESIZE);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
perror("BatchQueue init sysconf");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
page_size = ret;
|
||||||
|
bq_size = ROUNDUP(sizeof(gomp_batchQ_t) - 1 + buffer_realsize * 2);
|
||||||
|
ret = snprintf(shm_name, NAME_MAX, BASE_SHM_NAME"%d\n", chan_idx);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "BatchQueue init snprintf failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (ret >= NAME_MAX)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Too many streams created: impossible to ");
|
||||||
|
fprintf(stderr, "create a stream named "BASE_SHM_NAME);
|
||||||
|
fprintf(stderr, "%d\n", chan_idx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
shm_fd = shm_open(shm_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
if (shm_fd == -1)
|
||||||
|
{
|
||||||
|
perror("BatchQueue init shm_open failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = ftruncate(shm_fd, bq_size);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
perror("BatchQueue init ftruncate failed");
|
||||||
|
goto close_file;
|
||||||
|
}
|
||||||
|
stream = mmap(NULL, bq_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, shm_fd, 0);
|
||||||
|
if (stream == MAP_FAILED)
|
||||||
|
{
|
||||||
|
perror("Batchqueue init mmap failed");
|
||||||
|
stream = NULL;
|
||||||
|
goto close_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->state = 0;
|
||||||
|
|
||||||
|
stream->sender_ptr = stream->buf;
|
||||||
|
stream->receiver_ptr = stream->buf;
|
||||||
|
|
||||||
|
stream->buf_start1 = stream->buf;
|
||||||
|
stream->buf_start2 = stream->buf + buffer_realsize;
|
||||||
|
stream->sender_buf = stream->buf_start1;
|
||||||
|
stream->receiver_buf = stream->buf_start1;
|
||||||
|
|
||||||
|
stream->buffer_size = buffer_realsize;
|
||||||
|
stream->buffer_mask = buffer_realsize - 1;
|
||||||
|
|
||||||
|
stream->pre_shift = 0;
|
||||||
|
|
||||||
|
|
||||||
|
close_file:
|
||||||
|
shm_unlink(shm_name);
|
||||||
|
return stream;
|
||||||
|
#undef BASE_SHM_NAME
|
||||||
|
#undef ROUNDUP
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate and initialize a generic GOMP_STREAM_VIEW that can be
|
/* Allocate and initialize a generic GOMP_STREAM_VIEW that can be
|
||||||
connected to any stream to give either read or write access
|
connected to any stream to give either read or write access
|
||||||
depending on its TYPE. Returns a pointer to the newly allocated
|
depending on its TYPE. Returns a pointer to the newly allocated
|
||||||
|
@ -151,6 +248,22 @@ gomp_stream_create_view (int type, size_t view_size, size_t burst_size)
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
gomp_batchQ_create_view (int type, size_t view_size, size_t burst_size)
|
||||||
|
{
|
||||||
|
gomp_batchQ_view_p view =
|
||||||
|
(gomp_batchQ_view_p) gomp_malloc (sizeof(gomp_batchQ_view_t));
|
||||||
|
|
||||||
|
view->stream = NULL;
|
||||||
|
view->type = type | BATCHQ_VIEW;
|
||||||
|
view->view_size = view_size;
|
||||||
|
view->burst_size = burst_size;
|
||||||
|
view->pxxk_size = view_size - burst_size;
|
||||||
|
view->termination_flag = false;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrapper for creating a READ view . */
|
/* Wrapper for creating a READ view . */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -160,6 +273,13 @@ GOMP_stream_create_read_view (size_t view_size, size_t burst_size)
|
||||||
return gomp_stream_create_view (READ_VIEW, view_size, burst_size);
|
return gomp_stream_create_view (READ_VIEW, view_size, burst_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
GOMP_batchQ_create_read_view (size_t view_size, size_t burst_size)
|
||||||
|
{
|
||||||
|
debug_log_init ("GOMP_stream_create_read_view %zu %zu\n", view_size, burst_size);
|
||||||
|
return gomp_batchQ_create_view(READ_VIEW, view_size, burst_size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrapper for creating a WRITE view. */
|
/* Wrapper for creating a WRITE view. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -169,6 +289,13 @@ GOMP_stream_create_write_view (size_t view_size, size_t burst_size)
|
||||||
return gomp_stream_create_view (WRITE_VIEW, view_size, burst_size);
|
return gomp_stream_create_view (WRITE_VIEW, view_size, burst_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
GOMP_batchQ_create_write_view (size_t view_size, size_t burst_size)
|
||||||
|
{
|
||||||
|
debug_log_init ("GOMP_stream_create_write_view %zu %zu\n", view_size, burst_size);
|
||||||
|
return gomp_batchQ_create_view(WRITE_VIEW, view_size, burst_size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate and initialize a GOMP_STREAM_TASK data structure. */
|
/* Allocate and initialize a GOMP_STREAM_TASK data structure. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -182,11 +309,19 @@ GOMP_stream_create_task ()
|
||||||
task->read_view_list.nr_views = 0;
|
task->read_view_list.nr_views = 0;
|
||||||
task->read_view_list.size = 0;
|
task->read_view_list.size = 0;
|
||||||
gomp_mutex_init (&task->read_view_list.connect_view_mutex);
|
gomp_mutex_init (&task->read_view_list.connect_view_mutex);
|
||||||
|
task->batchQ_read_view_list.views = NULL;
|
||||||
|
task->batchQ_read_view_list.nr_views = 0;
|
||||||
|
task->batchQ_read_view_list.size = 0;
|
||||||
|
gomp_mutex_init (&task->batchQ_read_view_list.connect_view_mutex);
|
||||||
|
|
||||||
task->write_view_list.views = NULL;
|
task->write_view_list.views = NULL;
|
||||||
task->write_view_list.nr_views = 0;
|
task->write_view_list.nr_views = 0;
|
||||||
task->write_view_list.size = 0;
|
task->write_view_list.size = 0;
|
||||||
gomp_mutex_init (&task->write_view_list.connect_view_mutex);
|
gomp_mutex_init (&task->write_view_list.connect_view_mutex);
|
||||||
|
task->batchQ_write_view_list.views = NULL;
|
||||||
|
task->batchQ_write_view_list.nr_views = 0;
|
||||||
|
task->batchQ_write_view_list.size = 0;
|
||||||
|
gomp_mutex_init (&task->batchQ_write_view_list.connect_view_mutex);
|
||||||
|
|
||||||
task->activation_counter = 0;
|
task->activation_counter = 0;
|
||||||
task->termination_flag = false;
|
task->termination_flag = false;
|
||||||
|
@ -210,8 +345,22 @@ GOMP_stream_get_task_activation_counter (void *t)
|
||||||
void
|
void
|
||||||
GOMP_stream_set_task_termination_flag (void *t)
|
GOMP_stream_set_task_termination_flag (void *t)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
gomp_stream_view_list_p task_list;
|
||||||
gomp_stream_task_p task = (gomp_stream_task_p) t;
|
gomp_stream_task_p task = (gomp_stream_task_p) t;
|
||||||
|
int num_batchQ_read_views = task->batchQ_read_view_list.nr_views;
|
||||||
|
int num_batchQ_write_views = task->batchQ_write_view_list.nr_views;
|
||||||
|
|
||||||
|
task_list = &task->batchQ_read_view_list;
|
||||||
|
gomp_mutex_lock (&task_list->connect_view_mutex);
|
||||||
|
for (i = 0; i < num_batchQ_read_views; ++i)
|
||||||
|
((gomp_batchQ_view_p) task_list->views[i])->termination_flag = true;
|
||||||
|
gomp_mutex_unlock (&task_list->connect_view_mutex);
|
||||||
|
task_list = &task->batchQ_write_view_list;
|
||||||
|
gomp_mutex_lock (&task_list->connect_view_mutex);
|
||||||
|
for (i = 0; i < num_batchQ_write_views; ++i)
|
||||||
|
((gomp_batchQ_view_p) task_list->views[i])->termination_flag = true;
|
||||||
|
gomp_mutex_unlock (&task_list->connect_view_mutex);
|
||||||
task->termination_flag = true;
|
task->termination_flag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,10 +439,10 @@ GOMP_stream_connect_view (void *t, void *s, void *v)
|
||||||
gomp_stream_p stream = (gomp_stream_p) s;
|
gomp_stream_p stream = (gomp_stream_p) s;
|
||||||
gomp_stream_view_p view = (gomp_stream_view_p) v;
|
gomp_stream_view_p view = (gomp_stream_view_p) v;
|
||||||
|
|
||||||
gomp_stream_view_handle_p vh = (view->type == READ_VIEW) ?
|
gomp_stream_view_handle_p vh = ((view->type & VIEW_TYPE_MASK) == READ_VIEW) ?
|
||||||
&stream->read_views : &stream->write_views;
|
&stream->read_views : &stream->write_views;
|
||||||
gomp_stream_view_list_p stream_list = &vh->view_list;
|
gomp_stream_view_list_p stream_list = &vh->view_list;
|
||||||
gomp_stream_view_list_p task_list = (view->type == READ_VIEW) ?
|
gomp_stream_view_list_p task_list = ((view->type & VIEW_TYPE_MASK) == READ_VIEW) ?
|
||||||
&task->read_view_list : &task->write_view_list;
|
&task->read_view_list : &task->write_view_list;
|
||||||
|
|
||||||
view->stream = stream;
|
view->stream = stream;
|
||||||
|
@ -302,7 +451,7 @@ GOMP_stream_connect_view (void *t, void *s, void *v)
|
||||||
stream is initially empty. This is equivalent to releasing the
|
stream is initially empty. This is equivalent to releasing the
|
||||||
original buffer_size elements. A write view will start with
|
original buffer_size elements. A write view will start with
|
||||||
buffer_size free space. */
|
buffer_size free space. */
|
||||||
if (view->type == READ_VIEW)
|
if ((view->type & VIEW_TYPE_MASK) == READ_VIEW)
|
||||||
view->lower_index = stream->buffer_size;
|
view->lower_index = stream->buffer_size;
|
||||||
else
|
else
|
||||||
view->local_min_value = stream->buffer_size;
|
view->local_min_value = stream->buffer_size;
|
||||||
|
@ -321,6 +470,32 @@ GOMP_stream_connect_view (void *t, void *s, void *v)
|
||||||
gomp_stream_add_view_to_list (view, stream_list);
|
gomp_stream_add_view_to_list (view, stream_list);
|
||||||
gomp_mutex_unlock (&vh->view_list.connect_view_mutex);
|
gomp_mutex_unlock (&vh->view_list.connect_view_mutex);
|
||||||
__sync_fetch_and_add (&vh->nr_registered_views, 1);
|
__sync_fetch_and_add (&vh->nr_registered_views, 1);
|
||||||
|
debug_log5 ("GOMP_stream_connect_view %p %lu %p %s %p\n", stream,
|
||||||
|
pthread_self(), view, ((view->type & VIEW_TYPE_MASK) == READ_VIEW) ? "In" : "Out",
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GOMP_batchQ_connect_view (void *t, void *s, void *v)
|
||||||
|
{
|
||||||
|
gomp_stream_task_p task = (gomp_stream_task_p) t;
|
||||||
|
gomp_batchQ_p stream = (gomp_batchQ_p) s;
|
||||||
|
gomp_batchQ_view_p view = (gomp_batchQ_view_p) v;
|
||||||
|
|
||||||
|
gomp_stream_view_list_p task_list = ((view->type & VIEW_TYPE_MASK) == READ_VIEW) ?
|
||||||
|
&task->batchQ_read_view_list : &task->batchQ_write_view_list;
|
||||||
|
|
||||||
|
/* Register the view with the TASK to which it belongs. This
|
||||||
|
operation is local to the task, so there is no need to
|
||||||
|
synchronize. */
|
||||||
|
gomp_mutex_lock (&task_list->connect_view_mutex);
|
||||||
|
gomp_stream_add_view_to_list ((gomp_stream_view_p) view, task_list);
|
||||||
|
gomp_mutex_unlock (&task_list->connect_view_mutex);
|
||||||
|
|
||||||
|
view->stream = stream;
|
||||||
|
debug_log5 ("GOMP_batchQ_connect_view %p %lu %p %s %p\n", stream,
|
||||||
|
pthread_self(), view, ((view->type & VIEW_TYPE_MASK) == READ_VIEW) ? "In" : "Out",
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether all the expected views on STREAM have already
|
/* Check whether all the expected views on STREAM have already
|
||||||
|
@ -362,8 +537,12 @@ GOMP_stream_wait_until_connected (void *t)
|
||||||
|
|
||||||
gomp_mutex_lock (&task->read_view_list.connect_view_mutex);
|
gomp_mutex_lock (&task->read_view_list.connect_view_mutex);
|
||||||
for (i = 0; i < task->read_view_list.nr_views; ++i)
|
for (i = 0; i < task->read_view_list.nr_views; ++i)
|
||||||
if (!gomp_stream_check_connected (task->read_view_list.views[i]->stream))
|
{
|
||||||
done = false;
|
if (task->read_view_list.views[i]->type & BATCHQ_VIEW)
|
||||||
|
continue;
|
||||||
|
if (!gomp_stream_check_connected (task->read_view_list.views[i]->stream))
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
gomp_mutex_unlock (&task->read_view_list.connect_view_mutex);
|
gomp_mutex_unlock (&task->read_view_list.connect_view_mutex);
|
||||||
|
|
||||||
gomp_mutex_lock (&task->write_view_list.connect_view_mutex);
|
gomp_mutex_lock (&task->write_view_list.connect_view_mutex);
|
||||||
|
@ -490,7 +669,7 @@ GOMP_stream_update (void *v, const unsigned long long act_start,
|
||||||
gomp_stream_p stream = view->stream;
|
gomp_stream_p stream = view->stream;
|
||||||
void *buffer_pointer;
|
void *buffer_pointer;
|
||||||
|
|
||||||
debug_log ("GOMP_stream_update [in] %llu %llu\n", act_start, act_end);
|
debug_log4 ("GOMP_stream_update [in] %p %zd %llu %llu\n", stream, view->burst_size, act_start, act_end);
|
||||||
|
|
||||||
/* This update requests access to the buffer in [low_idx,up_idx[.
|
/* This update requests access to the buffer in [low_idx,up_idx[.
|
||||||
We will release up to low_idx-1 and acquire up to up_idx-1. */
|
We will release up to low_idx-1 and acquire up to up_idx-1. */
|
||||||
|
@ -532,11 +711,41 @@ GOMP_stream_update (void *v, const unsigned long long act_start,
|
||||||
guaranteed access to all the requested data. */
|
guaranteed access to all the requested data. */
|
||||||
buffer_pointer = stream->buffer + low_idx_loc;
|
buffer_pointer = stream->buffer + low_idx_loc;
|
||||||
|
|
||||||
debug_log ("GOMP_stream_update [out] %llu %llu\n", act_start, act_end);
|
debug_log4 ("GOMP_stream_update [out] %p %zd %llu %llu\n", stream, view->burst_size, act_start, act_end);
|
||||||
|
|
||||||
return buffer_pointer;
|
return buffer_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
GOMP_batchQ_update (void *v, const unsigned long long act_start,
|
||||||
|
const unsigned long long act_end)
|
||||||
|
{
|
||||||
|
unsigned long long low_idx, up_idx;
|
||||||
|
gomp_batchQ_view_p view = (gomp_batchQ_view_p) v;
|
||||||
|
gomp_batchQ_p stream = view->stream;
|
||||||
|
|
||||||
|
/* This update requests access to the buffer in [low_idx,up_idx[.
|
||||||
|
We will release up to low_idx-1 and acquire up to up_idx-1. */
|
||||||
|
low_idx = act_start * view->burst_size;
|
||||||
|
up_idx = act_end * view->burst_size + view->pxxk_size - 1;
|
||||||
|
|
||||||
|
#ifdef ENSURE_BUFSIZE
|
||||||
|
if (up_idx - low_idx + 1 != stream->buffer_size)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
if (up_idx - low_idx + 1 > stream->buffer_size)
|
||||||
|
gomp_fatal ("GOMP_batchQ: update requested access to more than buffer_size data.");
|
||||||
|
#ifdef ENSURE_BUFSIZE
|
||||||
|
else if (!view->termination_flag)
|
||||||
|
gomp_fatal ("GOMP_batchQ: update requested access to less than buffer_size data.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (!stream->state);
|
||||||
|
|
||||||
|
return (void *) stream->receiver_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Request write access for the view V to the stream up to INDEX. */
|
/* Request write access for the view V to the stream up to INDEX. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -548,7 +757,7 @@ GOMP_stream_stall (void *v, const unsigned long long act_start,
|
||||||
gomp_stream_p stream = view->stream;
|
gomp_stream_p stream = view->stream;
|
||||||
void *buffer_pointer;
|
void *buffer_pointer;
|
||||||
|
|
||||||
debug_log ("GOMP_stream_stall [in] %llu %llu\n", act_start, act_end);
|
debug_log4 ("GOMP_stream_stall [in] %p %zd %llu %llu\n", stream, view->burst_size, act_start, act_end);
|
||||||
|
|
||||||
/* This update requests access to the buffer in [low_idx,up_idx[.
|
/* This update requests access to the buffer in [low_idx,up_idx[.
|
||||||
We will release up to low_idx-1 and acquire up to up_idx-1. */
|
We will release up to low_idx-1 and acquire up to up_idx-1. */
|
||||||
|
@ -574,11 +783,41 @@ GOMP_stream_stall (void *v, const unsigned long long act_start,
|
||||||
|
|
||||||
buffer_pointer = stream->buffer + (low_idx & stream->buffer_mask);
|
buffer_pointer = stream->buffer + (low_idx & stream->buffer_mask);
|
||||||
|
|
||||||
debug_log ("GOMP_stream_stall [out] %llu %llu\n", act_start, act_end);
|
debug_log4 ("GOMP_stream_stall [out] %p %zd %llu %llu\n", stream, view->burst_size, act_start, act_end);
|
||||||
|
|
||||||
return buffer_pointer;
|
return buffer_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
GOMP_batchQ_stall (void *v, const unsigned long long act_start,
|
||||||
|
const unsigned long long act_end)
|
||||||
|
{
|
||||||
|
unsigned long long low_idx, up_idx;
|
||||||
|
gomp_batchQ_view_p view = (gomp_batchQ_view_p) v;
|
||||||
|
gomp_batchQ_p stream = view->stream;
|
||||||
|
|
||||||
|
/* This update requests access to the buffer in [low_idx,up_idx[.
|
||||||
|
We will release up to low_idx-1 and acquire up to up_idx-1. */
|
||||||
|
low_idx = act_start * view->burst_size + stream->pre_shift;
|
||||||
|
up_idx = act_end * view->burst_size + view->pxxk_size + stream->pre_shift - 1;
|
||||||
|
|
||||||
|
#ifdef ENSURE_BUFSIZE
|
||||||
|
if (up_idx - low_idx + 1 != stream->buffer_size)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
if (up_idx - low_idx + 1 > stream->buffer_size)
|
||||||
|
{
|
||||||
|
gomp_fatal ("GOMP_batchQ: stall requested access to more than buffer_size.");
|
||||||
|
}
|
||||||
|
#ifdef ENSURE_BUFSIZE
|
||||||
|
else if (!view->termination_flag)
|
||||||
|
gomp_fatal ("GOMP_stream: stall requested access to less than buffer_size.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (void *) stream->sender_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Relinquish read access for the view V to the stream up to
|
/* Relinquish read access for the view V to the stream up to
|
||||||
INDEX. */
|
INDEX. */
|
||||||
|
|
||||||
|
@ -590,6 +829,25 @@ GOMP_stream_release (void *v, const unsigned long long act_idx)
|
||||||
debug_log ("GOMP_stream_release %llu %llu\n", act_idx, act_idx);
|
debug_log ("GOMP_stream_release %llu %llu\n", act_idx, act_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GOMP_batchQ_release (void *v, const unsigned long long act_idx)
|
||||||
|
{
|
||||||
|
gomp_batchQ_view_p view = (gomp_batchQ_view_p) v;
|
||||||
|
gomp_batchQ_p stream = view->stream;
|
||||||
|
|
||||||
|
stream->state = 0;
|
||||||
|
if (stream->receiver_buf == stream->buf_start1)
|
||||||
|
{
|
||||||
|
stream->receiver_ptr = stream->buf_start2;
|
||||||
|
stream->receiver_buf = stream->buf_start2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream->receiver_ptr = stream->buf_start1;
|
||||||
|
stream->receiver_buf = stream->buf_start1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Relinquish write access for the view V to the stream up to
|
/* Relinquish write access for the view V to the stream up to
|
||||||
INDEX. */
|
INDEX. */
|
||||||
|
|
||||||
|
@ -622,6 +880,26 @@ GOMP_stream_commit (void *v, const unsigned long long act_idx)
|
||||||
debug_log ("GOMP_stream_commit %llu %llu\n", act_idx, act_idx);
|
debug_log ("GOMP_stream_commit %llu %llu\n", act_idx, act_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GOMP_batchQ_commit (void *v, const unsigned long long act_idx)
|
||||||
|
{
|
||||||
|
gomp_batchQ_view_p view = (gomp_batchQ_view_p) v;
|
||||||
|
gomp_batchQ_p stream = view->stream;
|
||||||
|
|
||||||
|
while (stream->state);
|
||||||
|
stream->state = 1;
|
||||||
|
if (stream->sender_buf == stream->buf_start1)
|
||||||
|
{
|
||||||
|
stream->sender_ptr = stream->buf_start2;
|
||||||
|
stream->sender_buf = stream->buf_start2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream->sender_ptr = stream->buf_start1;
|
||||||
|
stream->sender_buf = stream->buf_start1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Finalization and destruction of the streaming data structures. */
|
/* Finalization and destruction of the streaming data structures. */
|
||||||
|
|
||||||
/* Disconnects VIEW from the stream to which it is connected and free
|
/* Disconnects VIEW from the stream to which it is connected and free
|
||||||
|
@ -632,7 +910,7 @@ gomp_stream_unregister_view (gomp_stream_view_p view)
|
||||||
{
|
{
|
||||||
gomp_stream_p stream = view->stream;
|
gomp_stream_p stream = view->stream;
|
||||||
gomp_stream_view_handle_p vh =
|
gomp_stream_view_handle_p vh =
|
||||||
(view->type == READ_VIEW) ? &stream->read_views : &stream->write_views;
|
((view->type & VIEW_TYPE_MASK) == READ_VIEW) ? &stream->read_views : &stream->write_views;
|
||||||
int unregistered_views;
|
int unregistered_views;
|
||||||
|
|
||||||
__sync_fetch_and_add (&(vh->nr_unregistered_views), 1);
|
__sync_fetch_and_add (&(vh->nr_unregistered_views), 1);
|
||||||
|
@ -641,7 +919,7 @@ gomp_stream_unregister_view (gomp_stream_view_p view)
|
||||||
|
|
||||||
/* Make sure that when multiple views access a stream, the finished
|
/* Make sure that when multiple views access a stream, the finished
|
||||||
views do not hinder the others in the min computation. */
|
views do not hinder the others in the min computation. */
|
||||||
if (view->type == READ_VIEW)
|
if ((view->type & VIEW_TYPE_MASK) == READ_VIEW)
|
||||||
GOMP_stream_release (view, GOMP_STREAM_MAX_INDEX);
|
GOMP_stream_release (view, GOMP_STREAM_MAX_INDEX);
|
||||||
/* The last producer exiting will set the eos_p flag and allow the
|
/* The last producer exiting will set the eos_p flag and allow the
|
||||||
consumers to read up to the highest committed index. */
|
consumers to read up to the highest committed index. */
|
||||||
|
@ -674,6 +952,12 @@ gomp_stream_unregister_view (gomp_stream_view_p view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
static inline void
|
||||||
|
gomp_batchQ_unregister_view (gomp_stream_view_p view)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* Invoked before terminating a stream TASK, this disconnects all the
|
/* Invoked before terminating a stream TASK, this disconnects all the
|
||||||
views and for all streams for which it is the last one to
|
views and for all streams for which it is the last one to
|
||||||
disconnect from, it frees up all data structures. */
|
disconnect from, it frees up all data structures. */
|
||||||
|
@ -683,7 +967,9 @@ GOMP_stream_task_exit (void *t)
|
||||||
{
|
{
|
||||||
gomp_stream_task_p task = (gomp_stream_task_p) t;
|
gomp_stream_task_p task = (gomp_stream_task_p) t;
|
||||||
int num_read_views = task->read_view_list.nr_views;
|
int num_read_views = task->read_view_list.nr_views;
|
||||||
|
int num_batchQ_read_views = task->batchQ_read_view_list.nr_views;
|
||||||
int num_write_views = task->write_view_list.nr_views;
|
int num_write_views = task->write_view_list.nr_views;
|
||||||
|
int num_batchQ_write_views = task->batchQ_write_view_list.nr_views;
|
||||||
int i, res;
|
int i, res;
|
||||||
debug_log_init ("GOMP_stream_task_exit %zu %zu\n", (size_t) t, (size_t) t);
|
debug_log_init ("GOMP_stream_task_exit %zu %zu\n", (size_t) t, (size_t) t);
|
||||||
|
|
||||||
|
@ -694,11 +980,19 @@ GOMP_stream_task_exit (void *t)
|
||||||
for (i = 0; i < num_read_views; ++i)
|
for (i = 0; i < num_read_views; ++i)
|
||||||
gomp_stream_unregister_view (task->read_view_list.views[i]);
|
gomp_stream_unregister_view (task->read_view_list.views[i]);
|
||||||
|
|
||||||
|
for (i = 0; i < num_batchQ_read_views; ++i)
|
||||||
|
gomp_batchQ_unregister_view (task->batchQ_read_view_list.views[i]);
|
||||||
|
|
||||||
for (i = 0; i < num_write_views; ++i)
|
for (i = 0; i < num_write_views; ++i)
|
||||||
gomp_stream_unregister_view (task->write_view_list.views[i]);
|
gomp_stream_unregister_view (task->write_view_list.views[i]);
|
||||||
|
|
||||||
|
for (i = 0; i < num_batchQ_write_views; ++i)
|
||||||
|
gomp_batchQ_unregister_view (task->batchQ_write_view_list.views[i]);
|
||||||
|
|
||||||
free (task->read_view_list.views);
|
free (task->read_view_list.views);
|
||||||
|
free (task->batchQ_read_view_list.views);
|
||||||
free (task->write_view_list.views);
|
free (task->write_view_list.views);
|
||||||
|
free (task->batchQ_write_view_list.views);
|
||||||
free (task);
|
free (task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -748,6 +1042,8 @@ GOMP_stream_get_available_work (void *t, unsigned long long *start_idx)
|
||||||
return AGGREGATION_FACTOR;
|
return AGGREGATION_FACTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO? GOMP_batchQ_get_available_work */
|
||||||
|
|
||||||
|
|
||||||
/* Initialize streaming in this region. */
|
/* Initialize streaming in this region. */
|
||||||
|
|
||||||
|
@ -760,6 +1056,8 @@ GOMP_stream_init ()
|
||||||
gomp_barrier_init (&gomp_stream_tasks_exit_barrier, gomp_stream_tasks_count);
|
gomp_barrier_init (&gomp_stream_tasks_exit_barrier, gomp_stream_tasks_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No GOMP_batchQ_init */
|
||||||
|
|
||||||
/* Wait until all streaming threads complete. */
|
/* Wait until all streaming threads complete. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -768,6 +1066,8 @@ GOMP_stream_exit ()
|
||||||
gomp_barrier_wait (&gomp_stream_tasks_exit_barrier);
|
gomp_barrier_wait (&gomp_stream_tasks_exit_barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No GOMP_batchQ_exit */
|
||||||
|
|
||||||
/* Request SIZE bytes for a PRE operator on stream S. Return a
|
/* Request SIZE bytes for a PRE operator on stream S. Return a
|
||||||
pointer where data should be stored. */
|
pointer where data should be stored. */
|
||||||
void *
|
void *
|
||||||
|
@ -783,6 +1083,19 @@ GOMP_stream_pre (void *s, const unsigned long long size)
|
||||||
return stream->buffer;
|
return stream->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
GOMP_batchQ_pre (void *s, const unsigned long long size)
|
||||||
|
{
|
||||||
|
gomp_batchQ_p stream = (gomp_batchQ_p) s;
|
||||||
|
|
||||||
|
debug_log_init ("GOMP_stream_pre %zu \t %llu\n", (size_t) s, size);
|
||||||
|
|
||||||
|
gomp_fatal ("GOMP_batchQ_pre not supported now: missing code in GOMP_batchQ_commit and GOMP_batchQ_stall\n");
|
||||||
|
stream->pre_shift = size;
|
||||||
|
|
||||||
|
return (void *) stream->sender_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is a pthread_create entry point for streaming
|
/* This function is a pthread_create entry point for streaming
|
||||||
tasks. */
|
tasks. */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
Contributed by Antoniu Pop <antoniu.pop@gmail.com>.
|
Contributed by Antoniu Pop <antoniu.pop@gmail.com>
|
||||||
|
and Thomas Preud'homme <thomas.preud-homme@lip6.fr>.
|
||||||
|
|
||||||
This file is part of the GNU OpenMP Library (libgomp).
|
This file is part of the GNU OpenMP Library (libgomp).
|
||||||
|
|
||||||
|
@ -56,10 +57,13 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
READ_VIEW,
|
READ_VIEW = 0,
|
||||||
WRITE_VIEW
|
WRITE_VIEW
|
||||||
} gomp_stream_view_type_t;
|
} gomp_stream_view_type_t;
|
||||||
|
|
||||||
|
#define VIEW_TYPE_MASK 1
|
||||||
|
#define BATCHQ_VIEW 2
|
||||||
|
|
||||||
struct gomp_stream;
|
struct gomp_stream;
|
||||||
struct gomp_stream_task;
|
struct gomp_stream_task;
|
||||||
|
|
||||||
|
@ -106,6 +110,19 @@ typedef struct gomp_stream_view
|
||||||
|
|
||||||
} gomp_stream_view_t, *gomp_stream_view_p;
|
} gomp_stream_view_t, *gomp_stream_view_p;
|
||||||
|
|
||||||
|
struct gomp_batchQ;
|
||||||
|
|
||||||
|
typedef struct gomp_batchQ_view
|
||||||
|
{
|
||||||
|
/* Type of this view (read or write). */
|
||||||
|
gomp_stream_view_type_t type;
|
||||||
|
size_t view_size;
|
||||||
|
size_t burst_size;
|
||||||
|
size_t pxxk_size;
|
||||||
|
struct gomp_batchQ *stream;
|
||||||
|
volatile bool termination_flag;
|
||||||
|
} gomp_batchQ_view_t, *gomp_batchQ_view_p;
|
||||||
|
|
||||||
/* List of GOMP_STREAM_VIEWs. As this list is only modified in the
|
/* List of GOMP_STREAM_VIEWs. As this list is only modified in the
|
||||||
initialization phase and we never remove items, we'll use an
|
initialization phase and we never remove items, we'll use an
|
||||||
array. */
|
array. */
|
||||||
|
@ -202,6 +219,25 @@ typedef struct gomp_stream
|
||||||
#endif
|
#endif
|
||||||
} gomp_stream_t, *gomp_stream_p;
|
} gomp_stream_t, *gomp_stream_p;
|
||||||
|
|
||||||
|
#define CACHE_LINE_SIZE 64
|
||||||
|
typedef struct gomp_batchQ
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
char volatile *buf_start1 __attribute__ ((aligned (CACHE_LINE_SIZE)));
|
||||||
|
char volatile *buf_start2;
|
||||||
|
size_t buffer_size;
|
||||||
|
size_t buffer_mask;
|
||||||
|
size_t pre_shift;
|
||||||
|
volatile unsigned int state:1;
|
||||||
|
|
||||||
|
char volatile *sender_ptr __attribute__ ((aligned (CACHE_LINE_SIZE)));
|
||||||
|
char volatile *sender_buf; /* Which buffer is sender using? */
|
||||||
|
char volatile *receiver_ptr __attribute__ ((aligned (CACHE_LINE_SIZE)));
|
||||||
|
char volatile *receiver_buf; /* Which buffer is receiver using? */
|
||||||
|
};
|
||||||
|
/* 0 would not conform to C99 section 6.7.5.2 §1 */
|
||||||
|
volatile char buf[1] __attribute__ ((aligned (CACHE_LINE_SIZE)));
|
||||||
|
} gomp_batchQ_t, *gomp_batchQ_p;
|
||||||
|
|
||||||
/* GOMP_STREAM_TASK data structure. Runtime node in the task
|
/* GOMP_STREAM_TASK data structure. Runtime node in the task
|
||||||
graph. */
|
graph. */
|
||||||
|
@ -210,7 +246,9 @@ typedef struct gomp_stream_task
|
||||||
{
|
{
|
||||||
/* Lists of views on streams used by this task. */
|
/* Lists of views on streams used by this task. */
|
||||||
gomp_stream_view_list_t read_view_list;
|
gomp_stream_view_list_t read_view_list;
|
||||||
|
gomp_stream_view_list_t batchQ_read_view_list;
|
||||||
gomp_stream_view_list_t write_view_list;
|
gomp_stream_view_list_t write_view_list;
|
||||||
|
gomp_stream_view_list_t batchQ_write_view_list;
|
||||||
|
|
||||||
/* The following are used directly in the generated code and should
|
/* The following are used directly in the generated code and should
|
||||||
only be read here. A memory fence is guaranteed before the
|
only be read here. A memory fence is guaranteed before the
|
||||||
|
|
Loading…
Reference in New Issue