Skip to content

Commit

Permalink
D9306 omp 4.1 async offload support (partial): code changes
Browse files Browse the repository at this point in the history
llvm-svn: 236753
  • Loading branch information
AndreyChurbanov committed May 7, 2015
1 parent d9d900c commit 535b6fa
Show file tree
Hide file tree
Showing 7 changed files with 426 additions and 23 deletions.
8 changes: 8 additions & 0 deletions openmp/runtime/src/dllexports
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,14 @@ kmpc_set_defaults 224
%endif # OMP_40
%endif

# OpenMP 4.1 entry points
%ifndef stub
%ifdef OMP_41
__kmpc_proxy_task_completed 259
__kmpc_proxy_task_completed_ooo 260
%endif
%endif

# User API entry points that have both lower- and upper- case versions for Fortran.
# Number for lowercase version is indicated. Number for uppercase is obtained by adding 1000.
# User API entry points are entry points that start with 'kmp_' or 'omp_'.
Expand Down
20 changes: 19 additions & 1 deletion openmp/runtime/src/kmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
#define TASK_UNTIED 0
#define TASK_EXPLICIT 1
#define TASK_IMPLICIT 0
#define TASK_PROXY 1
#define TASK_FULL 0

#define KMP_CANCEL_THREADS
#define KMP_THREAD_ATTR
Expand Down Expand Up @@ -1987,7 +1989,12 @@ typedef struct kmp_tasking_flags { /* Total struct must be exactly 32 b
unsigned merged_if0 : 1; /* no __kmpc_task_{begin/complete}_if0 calls in if0 code path */
#if OMP_40_ENABLED
unsigned destructors_thunk : 1; /* set if the compiler creates a thunk to invoke destructors from the runtime */
#if OMP_41_ENABLED
unsigned proxy : 1; /* task is a proxy task (it will be executed outside the context of the RTL) */
unsigned reserved : 11; /* reserved for compiler use */
#else
unsigned reserved : 12; /* reserved for compiler use */
#endif
#else // OMP_40_ENABLED
unsigned reserved : 13; /* reserved for compiler use */
#endif // OMP_40_ENABLED
Expand Down Expand Up @@ -2077,6 +2084,9 @@ typedef struct kmp_base_task_team {
/* TRUE means tt_threads_data is set up and initialized */
kmp_int32 tt_nproc; /* #threads in team */
kmp_int32 tt_max_threads; /* number of entries allocated for threads_data array */
#if OMP_41_ENABLED
kmp_int32 tt_found_proxy_tasks; /* Have we found proxy tasks since last barrier */
#endif

KMP_ALIGN_CACHE
volatile kmp_uint32 tt_unfinished_threads; /* #threads still active */
Expand Down Expand Up @@ -3147,7 +3157,7 @@ int __kmp_execute_tasks_oncore(kmp_info_t *thread, kmp_int32 gtid, kmp_flag_onco
extern void __kmp_reap_task_teams( void );
extern void __kmp_unref_task_team( kmp_task_team_t *task_team, kmp_info_t *thread );
extern void __kmp_wait_to_unref_task_teams( void );
extern void __kmp_task_team_setup ( kmp_info_t *this_thr, kmp_team_t *team, int both );
extern void __kmp_task_team_setup ( kmp_info_t *this_thr, kmp_team_t *team, int both, int always );
extern void __kmp_task_team_sync ( kmp_info_t *this_thr, kmp_team_t *team );
extern void __kmp_task_team_wait ( kmp_info_t *this_thr, kmp_team_t *team
#if USE_ITT_BUILD
Expand Down Expand Up @@ -3302,8 +3312,16 @@ KMP_EXPORT kmp_int32 __kmpc_cancellationpoint(ident_t* loc_ref, kmp_int32 gtid,
KMP_EXPORT kmp_int32 __kmpc_cancel_barrier(ident_t* loc_ref, kmp_int32 gtid);
KMP_EXPORT int __kmp_get_cancellation_status(int cancel_kind);

#if OMP_41_ENABLED

KMP_EXPORT void __kmpc_proxy_task_completed( kmp_int32 gtid, kmp_task_t *ptask );
KMP_EXPORT void __kmpc_proxy_task_completed_ooo ( kmp_task_t *ptask );

#endif

#endif


/*
* Lock interface routines (fast versions with gtid passed in)
*/
Expand Down
27 changes: 25 additions & 2 deletions openmp/runtime/src/kmp_barrier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ __kmp_barrier(enum barrier_type bt, int gtid, int is_split, size_t reduce_size,
if (__kmp_tasking_mode != tskm_immediate_exec) {
__kmp_task_team_wait(this_thr, team
USE_ITT_BUILD_ARG(itt_sync_obj) );
__kmp_task_team_setup(this_thr, team, 0); // use 0 to only setup the current team
__kmp_task_team_setup(this_thr, team, 0, 0); // use 0,0 to only setup the current team if nthreads > 1
}


Expand Down Expand Up @@ -1227,9 +1227,32 @@ __kmp_barrier(enum barrier_type bt, int gtid, int is_split, size_t reduce_size,
} else { // Team is serialized.
status = 0;
if (__kmp_tasking_mode != tskm_immediate_exec) {
#if OMP_41_ENABLED
if ( this_thr->th.th_task_team != NULL ) {
void *itt_sync_obj = NULL;
#if USE_ITT_NOTIFY
if (__itt_sync_create_ptr || KMP_ITT_DEBUG) {
itt_sync_obj = __kmp_itt_barrier_object(gtid, bt, 1);
__kmp_itt_barrier_starting(gtid, itt_sync_obj);
}
#endif

kmp_task_team_t * task_team = this_thr->th.th_task_team;
KMP_DEBUG_ASSERT(task_team->tt.tt_found_proxy_tasks == TRUE);
__kmp_task_team_wait(this_thr, team
USE_ITT_BUILD_ARG(itt_sync_obj));
__kmp_task_team_setup(this_thr, team, 0, 0);

#if USE_ITT_BUILD
if (__itt_sync_create_ptr || KMP_ITT_DEBUG)
__kmp_itt_barrier_finished(gtid, itt_sync_obj);
#endif /* USE_ITT_BUILD */
}
#else
// The task team should be NULL for serialized code (tasks will be executed immediately)
KMP_DEBUG_ASSERT(team->t.t_task_team[this_thr->th.th_task_state] == NULL);
KMP_DEBUG_ASSERT(this_thr->th.th_task_team == NULL);
#endif
}
}
KA_TRACE(15, ("__kmp_barrier: T#%d(%d:%d) is leaving with return value %d\n",
Expand Down Expand Up @@ -1532,7 +1555,7 @@ __kmp_fork_barrier(int gtid, int tid)
#endif

if (__kmp_tasking_mode != tskm_immediate_exec) {
__kmp_task_team_setup(this_thr, team, 1); // 1 indicates setup both task teams
__kmp_task_team_setup(this_thr, team, 1, 0); // 1,0 indicates setup both task teams if nthreads > 1
}

/* The master thread may have changed its blocktime between the join barrier and the
Expand Down
8 changes: 8 additions & 0 deletions openmp/runtime/src/kmp_csupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,14 @@ __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32 global_tid)
this_thr = __kmp_threads[ global_tid ];
serial_team = this_thr->th.th_serial_team;

#if OMP_41_ENABLED
kmp_task_team_t * task_team = this_thr->th.th_task_team;

// we need to wait for the proxy tasks before finishing the thread
if ( task_team != NULL && task_team->tt.tt_found_proxy_tasks )
__kmp_task_team_wait(this_thr, serial_team, NULL ); // is an ITT object needed here?
#endif

KMP_MB();
KMP_DEBUG_ASSERT( serial_team );
KMP_ASSERT( serial_team -> t.t_serialized );
Expand Down
10 changes: 10 additions & 0 deletions openmp/runtime/src/kmp_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -3940,6 +3940,16 @@ __kmp_unregister_root_current_thread( int gtid )

KMP_MB();

#if OMP_41_ENABLED
kmp_info_t * thread = __kmp_threads[gtid];
kmp_team_t * team = thread->th.th_team;
kmp_task_team_t * task_team = thread->th.th_task_team;

// we need to wait for the proxy tasks before finishing the thread
if ( task_team != NULL && task_team->tt.tt_found_proxy_tasks )
__kmp_task_team_wait(thread, team, NULL );
#endif

__kmp_reset_root(gtid, root);

/* free up this thread slot */
Expand Down
24 changes: 21 additions & 3 deletions openmp/runtime/src/kmp_taskdeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,9 @@ __kmpc_omp_task_with_deps( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_ta
kmp_taskdata_t * current_task = thread->th.th_current_task;

bool serial = current_task->td_flags.team_serial || current_task->td_flags.tasking_ser || current_task->td_flags.final;
#if OMP_41_ENABLED
serial = serial && !(new_taskdata->td_flags.proxy == TASK_PROXY);
#endif

if ( !serial && ( ndeps > 0 || ndeps_noalias > 0 )) {
/* if no dependencies have been tracked yet, create the dependence hash */
Expand All @@ -425,11 +428,20 @@ __kmpc_omp_task_with_deps( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_ta
new_taskdata ) );
return TASK_CURRENT_NOT_QUEUED;
}
} else {
#if OMP_41_ENABLED
kmp_task_team_t * task_team = thread->th.th_task_team;
if ( task_team && task_team->tt.tt_found_proxy_tasks )
__kmpc_omp_wait_deps ( loc_ref, gtid, ndeps, dep_list, ndeps_noalias, noalias_dep_list );
else
#endif
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d ignored dependencies for task (serialized)"
"loc=%p task=%p\n", gtid, loc_ref, new_taskdata ) );
}

KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d task had no blocking dependencies : "
"loc=%p task=%p, transferring to __kmpc_omp_task\n", gtid, loc_ref,
new_taskdata ) );
new_taskdata ) );

return __kmpc_omp_task(loc_ref,gtid,new_task);
}
Expand Down Expand Up @@ -460,9 +472,15 @@ __kmpc_omp_wait_deps ( ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps, kmp_de
kmp_taskdata_t * current_task = thread->th.th_current_task;

// We can return immediately as:
// - dependences are not computed in serial teams
// - dependences are not computed in serial teams (except if we have proxy tasks)
// - if the dephash is not yet created it means we have nothing to wait for
if ( current_task->td_flags.team_serial || current_task->td_flags.tasking_ser || current_task->td_flags.final || current_task->td_dephash == NULL ) {
bool ignore = current_task->td_flags.team_serial || current_task->td_flags.tasking_ser || current_task->td_flags.final;
#if OMP_41_ENABLED
ignore = ignore && thread->th.th_task_team->tt.tt_found_proxy_tasks == FALSE;
#endif
ignore = ignore || current_task->td_dephash == NULL;

if ( ignore ) {
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking dependencies : loc=%p\n", gtid, loc_ref) );
return;
}
Expand Down
Loading

0 comments on commit 535b6fa

Please sign in to comment.