From d62fdbdc174693045bdf152cd233830b9bb5cebb Mon Sep 17 00:00:00 2001 From: Jonathan Peyton Date: Mon, 30 Nov 2015 20:14:05 +0000 Subject: [PATCH] Fix honoring of OMP_THREAD_LIMIT in the teams construct Fix for crash in the teams construct in case user sets OMP_THREAD_LIMIT to a number less than the number of processors. Now the number of threads will be silently reduced if the user didn't specify teams parameters or with a warning if the user specified teams parameters conflicting with OMP_THREAD_LIMIT. Differential Revision: http://reviews.llvm.org/D14732 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@254322 91177308-0d34-0410-b5e6-96231b3b80d8 --- runtime/src/kmp_runtime.c | 43 ++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index 0a5c641..0cf34e9 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -5033,7 +5033,7 @@ __kmp_allocate_team( kmp_root_t *root, int new_nproc, int max_nproc, __kmp_initialize_info( team->t.t_threads[ f ], team, f, __kmp_gtid_from_tid( f, team ) ); if (level) { // set th_task_state for new threads in nested hot team // __kmp_initialize_info() no longer zeroes th_task_state, so we should only need to set the - // th_task_state for the new threads. th_task_state for master thread will not be accurate until + // th_task_state for the new threads. th_task_state for master thread will not be accurate until // after this in __kmp_fork_call(), so we look to the master's memo_stack to get the correct value. for (f=old_nproc; f < team->t.t_nproc; ++f) team->t.t_threads[f]->th.th_task_state = team->t.t_threads[0]->th.th_task_state_memo_stack[level]; @@ -5517,7 +5517,7 @@ __kmp_launch_thread( kmp_info_t *this_thr ) this_thr->th.ompt_thread_info.state = ompt_state_work_parallel; // Initialize OMPT task id for implicit task. int tid = __kmp_tid_from_gtid(gtid); - (*pteam)->t.t_implicit_task_taskdata[tid].ompt_task_info.task_id = + (*pteam)->t.t_implicit_task_taskdata[tid].ompt_task_info.task_id = __ompt_task_id_new(tid); } #endif @@ -6955,20 +6955,49 @@ __kmp_push_num_teams( ident_t *id, int gtid, int num_teams, int num_threads ) kmp_info_t *thr = __kmp_threads[gtid]; KMP_DEBUG_ASSERT(num_teams >= 0); KMP_DEBUG_ASSERT(num_threads >= 0); - if( num_teams == 0 ) { + + if( num_teams == 0 ) num_teams = 1; // default number of teams is 1. + if( num_teams > __kmp_max_nth ) { // if too many teams requested? + if ( !__kmp_reserve_warn ) { + __kmp_reserve_warn = 1; + __kmp_msg( + kmp_ms_warning, + KMP_MSG( CantFormThrTeam, num_teams, __kmp_max_nth ), + KMP_HNT( Unset_ALL_THREADS ), + __kmp_msg_null + ); + } + num_teams = __kmp_max_nth; } // Set number of teams (number of threads in the outer "parallel" of the teams) thr->th.th_set_nproc = thr->th.th_teams_size.nteams = num_teams; // Remember the number of threads for inner parallel regions - if( num_threads > 0 ) { - thr->th.th_teams_size.nth = num_threads; - } else { + if( num_threads == 0 ) { if( !TCR_4(__kmp_init_middle) ) __kmp_middle_initialize(); // get __kmp_avail_proc calculated - thr->th.th_teams_size.nth = __kmp_avail_proc / num_teams; + num_threads = __kmp_avail_proc / num_teams; + if( num_teams * num_threads > __kmp_max_nth ) { + // adjust num_threads w/o warning as it is not user setting + num_threads = __kmp_max_nth / num_teams; + } + } else { + if( num_teams * num_threads > __kmp_max_nth ) { + int new_threads = __kmp_max_nth / num_teams; + if ( !__kmp_reserve_warn ) { // user asked for too many threads + __kmp_reserve_warn = 1; // that conflicts with OMP_THREAD_LIMIT + __kmp_msg( + kmp_ms_warning, + KMP_MSG( CantFormThrTeam, num_threads, new_threads ), + KMP_HNT( Unset_ALL_THREADS ), + __kmp_msg_null + ); + } + num_threads = new_threads; + } } + thr->th.th_teams_size.nth = num_threads; }