void __kmp_pop_sync( int gtid, enum cons_type ct, ident_t const * ident ) { int tos; struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; tos = p->stack_top; KE_TRACE( 10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid() ) ); if ( tos == 0 || p->s_top == 0 ) { __kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct, ident ); }; if ( tos != p->s_top || p->stack_data[ tos ].type != ct ) { __kmp_check_null_func(); __kmp_error_construct2( kmp_i18n_msg_CnsExpectedEnd, ct, ident, & p->stack_data[ tos ] ); }; if ( gtid < 0 ) { __kmp_check_null_func(); }; KE_TRACE( 100, ( POP_MSG( p ) ) ); p->s_top = p->stack_data[ tos ].prev; p->stack_data[ tos ].type = ct_none; p->stack_data[ tos ].ident = NULL; p->stack_top = tos - 1; KE_DUMP( 1000, dump_cons_stack( gtid, p ) ); }
enum cons_type __kmp_pop_workshare( int gtid, enum cons_type ct, ident_t const * ident ) { int tos; struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; tos = p->stack_top; KE_TRACE( 10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) ); if ( tos == 0 || p->w_top == 0 ) { __kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct, ident ); } if ( tos != p->w_top || ( p->stack_data[ tos ].type != ct && /* below are two exceptions to the rule that construct types must match */ ! ( p->stack_data[ tos ].type == ct_pdo_ordered && ct == ct_pdo ) && ! ( p->stack_data[ tos ].type == ct_task_ordered && ct == ct_task ) ) ) { __kmp_check_null_func(); __kmp_error_construct2( kmp_i18n_msg_CnsExpectedEnd, ct, ident, & p->stack_data[ tos ] ); } KE_TRACE( 100, ( POP_MSG( p ) ) ); p->w_top = p->stack_data[ tos ].prev; p->stack_data[ tos ].type = ct_none; p->stack_data[ tos ].ident = NULL; p->stack_top = tos - 1; KE_DUMP( 1000, dump_cons_stack( gtid, p ) ); return p->stack_data[ p->w_top ].type; }
void __kmp_check_barrier( int gtid, enum cons_type ct, ident_t const * ident ) { struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KE_TRACE( 10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid, __kmp_get_gtid() ) ); if ( ident != 0 ) { __kmp_check_null_func(); } if ( p->w_top > p->p_top ) { /* we are already in a WORKSHARING construct for this PARALLEL region */ __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->w_top ] ); } if (p->s_top > p->p_top) { /* we are already in a SYNC construct for this PARALLEL region */ __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->s_top ] ); } }
void __kmp_push_workshare( int gtid, enum cons_type ct, ident_t const * ident ) { int tos; struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KE_TRACE( 10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) ); __kmp_check_workshare( gtid, ct, ident ); KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) ); tos = ++p->stack_top; p->stack_data[ tos ].type = ct; p->stack_data[ tos ].prev = p->w_top; p->stack_data[ tos ].ident = ident; p->stack_data[ tos ].name = NULL; p->w_top = tos; KE_DUMP( 1000, dump_cons_stack( gtid, p ) ); }
void __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck ) { int tos; struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KMP_ASSERT( gtid == __kmp_get_gtid() ); KE_TRACE( 10, ("__kmp_push_sync (gtid=%d)\n", gtid ) ); __kmp_check_sync( gtid, ct, ident, lck ); KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) ); tos = ++ p->stack_top; p->stack_data[ tos ].type = ct; p->stack_data[ tos ].prev = p->s_top; p->stack_data[ tos ].ident = ident; p->stack_data[ tos ].name = lck; p->s_top = tos; KE_DUMP( 1000, dump_cons_stack( gtid, p ) ); }
void __kmp_push_parallel( int gtid, ident_t const * ident ) { int tos; struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KMP_DEBUG_ASSERT( __kmp_threads[ gtid ]-> th.th_cons ); KE_TRACE( 10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid() ) ); KE_TRACE( 100, ( PUSH_MSG( ct_parallel, ident ) ) ); if ( p->stack_top >= p->stack_size ) { __kmp_expand_cons_stack( gtid, p ); }; // if tos = ++p->stack_top; p->stack_data[ tos ].type = ct_parallel; p->stack_data[ tos ].prev = p->p_top; p->stack_data[ tos ].ident = ident; p->stack_data[ tos ].name = NULL; p->p_top = tos; KE_DUMP( 1000, dump_cons_stack( gtid, p ) ); }
struct cons_header * __kmp_allocate_cons_stack( int gtid ) { struct cons_header *p; /* TODO for monitor perhaps? */ if ( gtid < 0 ) { __kmp_check_null_func(); }; // if KE_TRACE( 10, ("allocate cons_stack (%d)\n", gtid ) ); p = (struct cons_header *) __kmp_allocate( sizeof( struct cons_header ) ); p->p_top = p->w_top = p->s_top = 0; p->stack_data = (struct cons_data *) __kmp_allocate( sizeof( struct cons_data ) * (MIN_STACK+1) ); p->stack_size = MIN_STACK; p->stack_top = 0; p->stack_data[ 0 ].type = ct_none; p->stack_data[ 0 ].prev = 0; p->stack_data[ 0 ].ident = NULL; return p; }
void __kmp_check_workshare( int gtid, enum cons_type ct, ident_t const * ident ) { struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KMP_DEBUG_ASSERT( __kmp_threads[ gtid ]-> th.th_cons ); KE_TRACE( 10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) ); if ( p->stack_top >= p->stack_size ) { __kmp_expand_cons_stack( gtid, p ); }; // if if ( p->w_top > p->p_top && !(IS_CONS_TYPE_TASKQ(p->stack_data[ p->w_top ].type) && IS_CONS_TYPE_TASKQ(ct))) { // We are already in a WORKSHARE construct for this PARALLEL region. __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->w_top ] ); }; // if if ( p->s_top > p->p_top ) { // We are already in a SYNC construct for this PARALLEL region. __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->s_top ] ); }; // if }
static void __kmp_expand_cons_stack( int gtid, struct cons_header *p ) { int i; struct cons_data *d; /* TODO for monitor perhaps? */ if (gtid < 0) __kmp_check_null_func(); KE_TRACE( 10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid() ) ); d = p->stack_data; p->stack_size = (p->stack_size * 2) + 100; /* TODO free the old data */ p->stack_data = (struct cons_data *) __kmp_allocate( sizeof( struct cons_data ) * (p->stack_size+1) ); for (i = p->stack_top; i >= 0; --i) p->stack_data[i] = d[i]; /* NOTE: we do not free the old stack_data */ }
static void __kmp_for_static_init( ident_t *loc, kmp_int32 global_tid, kmp_int32 schedtype, kmp_int32 *plastiter, T *plower, T *pupper, typename traits_t< T >::signed_t *pstride, typename traits_t< T >::signed_t incr, typename traits_t< T >::signed_t chunk ) { KMP_COUNT_BLOCK(OMP_FOR_static); typedef typename traits_t< T >::unsigned_t UT; typedef typename traits_t< T >::signed_t ST; /* this all has to be changed back to TID and such.. */ register kmp_int32 gtid = global_tid; register kmp_uint32 tid; register kmp_uint32 nth; register UT trip_count; register kmp_team_t *team; register kmp_info_t *th = __kmp_threads[ gtid ]; #if OMPT_SUPPORT && OMPT_TRACE ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); ompt_task_info_t *task_info = __ompt_get_taskinfo(0); #endif KMP_DEBUG_ASSERT( plastiter && plower && pupper && pstride ); KE_TRACE( 10, ("__kmpc_for_static_init called (%d)\n", global_tid)); #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," \ " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, global_tid, schedtype, *plastiter, *plower, *pupper, *pstride, incr, chunk ) ); __kmp_str_free( &buff ); } #endif if ( __kmp_env_consistency_check ) { __kmp_push_workshare( global_tid, ct_pdo, loc ); if ( incr == 0 ) { __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); } } /* special handling for zero-trip loops */ if ( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) { if( plastiter != NULL ) *plastiter = FALSE; /* leave pupper and plower set to entire iteration space */ *pstride = incr; /* value should never be used */ // *plower = *pupper - incr; // let compiler bypass the illegal loop (like for(i=1;i<10;i--)) THIS LINE CAUSED shape2F/h_tests_1.f TO HAVE A FAILURE ON A ZERO-TRIP LOOP (lower=1,\ upper=0,stride=1) - JPH June 23, 2009. #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init:(ZERO TRIP) liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>, loc = %%s\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride, loc->psource ) ); __kmp_str_free( &buff ); } #endif KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); #if OMPT_SUPPORT && OMPT_TRACE if ((ompt_status == ompt_status_track_callback) && ompt_callbacks.ompt_callback(ompt_event_loop_begin)) { ompt_callbacks.ompt_callback(ompt_event_loop_begin)( team_info->parallel_id, task_info->task_id, team_info->microtask); } #endif return; } #if OMP_40_ENABLED if ( schedtype > kmp_ord_upper ) { // we are in DISTRIBUTE construct schedtype += kmp_sch_static - kmp_distribute_static; // AC: convert to usual schedule type tid = th->th.th_team->t.t_master_tid; team = th->th.th_team->t.t_parent; } else #endif { tid = __kmp_tid_from_gtid( global_tid ); team = th->th.th_team; } /* determine if "for" loop is an active worksharing construct */ if ( team -> t.t_serialized ) { /* serialized parallel, each thread executes whole iteration space */ if( plastiter != NULL ) *plastiter = TRUE; /* leave pupper and plower set to entire iteration space */ *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec ); KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) ); __kmp_str_free( &buff ); } #endif KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); #if OMPT_SUPPORT && OMPT_TRACE if ((ompt_status == ompt_status_track_callback) && ompt_callbacks.ompt_callback(ompt_event_loop_begin)) { ompt_callbacks.ompt_callback(ompt_event_loop_begin)( team_info->parallel_id, task_info->task_id, team_info->microtask); } #endif return; } nth = team->t.t_nproc; if ( nth == 1 ) { if( plastiter != NULL ) *plastiter = TRUE; *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec ); KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) ); __kmp_str_free( &buff ); } #endif KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); #if OMPT_SUPPORT && OMPT_TRACE if ((ompt_status == ompt_status_track_callback) && ompt_callbacks.ompt_callback(ompt_event_loop_begin)) { ompt_callbacks.ompt_callback(ompt_event_loop_begin)( team_info->parallel_id, task_info->task_id, team_info->microtask); } #endif return; } /* compute trip count */ if ( incr == 1 ) { trip_count = *pupper - *plower + 1; } else if (incr == -1) { trip_count = *plower - *pupper + 1; } else { if ( incr > 1 ) { // the check is needed for unsigned division when incr < 0 trip_count = (*pupper - *plower) / incr + 1; } else { trip_count = (*plower - *pupper) / ( -incr ) + 1; } } if ( __kmp_env_consistency_check ) { /* tripcount overflow? */ if ( trip_count == 0 && *pupper != *plower ) { __kmp_error_construct( kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo, loc ); } } /* compute remaining parameters */ switch ( schedtype ) { case kmp_sch_static: { if ( trip_count < nth ) { KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy || \ __kmp_static == kmp_sch_static_balanced ); // Unknown static scheduling type. if ( tid < trip_count ) { *pupper = *plower = *plower + tid * incr; } else { *plower = *pupper + incr; } if( plastiter != NULL ) *plastiter = ( tid == trip_count - 1 ); } else { if ( __kmp_static == kmp_sch_static_balanced ) { register UT small_chunk = trip_count / nth; register UT extras = trip_count % nth; *plower += incr * ( tid * small_chunk + ( tid < extras ? tid : extras ) ); *pupper = *plower + small_chunk * incr - ( tid < extras ? 0 : incr ); if( plastiter != NULL ) *plastiter = ( tid == nth - 1 ); } else { register T big_chunk_inc_count = ( trip_count/nth + ( ( trip_count % nth ) ? 1 : 0) ) * incr; register T old_upper = *pupper; KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy ); // Unknown static scheduling type. *plower += tid * big_chunk_inc_count; *pupper = *plower + big_chunk_inc_count - incr; if ( incr > 0 ) { if( *pupper < *plower ) *pupper = i_maxmin< T >::mx; if( plastiter != NULL ) *plastiter = *plower <= old_upper && *pupper > old_upper - incr; if ( *pupper > old_upper ) *pupper = old_upper; // tracker C73258 } else { if( *pupper > *plower ) *pupper = i_maxmin< T >::mn; if( plastiter != NULL ) *plastiter = *plower >= old_upper && *pupper < old_upper - incr; if ( *pupper < old_upper ) *pupper = old_upper; // tracker C73258 } } } break; } case kmp_sch_static_chunked: { register ST span; if ( chunk < 1 ) { chunk = 1; } span = chunk * incr; *pstride = span * nth; *plower = *plower + (span * tid); *pupper = *plower + span - incr; if( plastiter != NULL ) *plastiter = (tid == ((trip_count - 1)/( UT )chunk) % nth); break; } default: KMP_ASSERT2( 0, "__kmpc_for_static_init: unknown scheduling type" ); break; } #if USE_ITT_BUILD // Report loop metadata if ( KMP_MASTER_TID(tid) && __itt_metadata_add_ptr && __kmp_forkjoin_frames_mode == 3 && #if OMP_40_ENABLED th->th.th_teams_microtask == NULL && #endif team->t.t_active_level == 1 ) { kmp_uint64 cur_chunk = chunk; // Calculate chunk in case it was not specified; it is specified for kmp_sch_static_chunked if ( schedtype == kmp_sch_static ) { cur_chunk = trip_count / nth + ( ( trip_count % nth ) ? 1 : 0); } // 0 - "static" schedule __kmp_itt_metadata_loop(loc, 0, trip_count, cur_chunk); } #endif #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init: liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) ); __kmp_str_free( &buff ); } #endif KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); #if OMPT_SUPPORT && OMPT_TRACE if ((ompt_status == ompt_status_track_callback) && ompt_callbacks.ompt_callback(ompt_event_loop_begin)) { ompt_callbacks.ompt_callback(ompt_event_loop_begin)( team_info->parallel_id, task_info->task_id, team_info->microtask); } #endif return; }
static void __kmp_team_static_init( ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, T *p_lb, T *p_ub, typename traits_t< T >::signed_t *p_st, typename traits_t< T >::signed_t incr, typename traits_t< T >::signed_t chunk ) { // The routine returns the first chunk distributed to the team and // stride for next chunks calculation. // Last iteration flag set for the team that will execute // the last iteration of the loop. // The routine is called for dist_schedue(static,chunk) only. typedef typename traits_t< T >::unsigned_t UT; typedef typename traits_t< T >::signed_t ST; kmp_uint32 team_id; kmp_uint32 nteams; UT trip_count; T lower; T upper; ST span; kmp_team_t *team; kmp_info_t *th; KMP_DEBUG_ASSERT( p_last && p_lb && p_ub && p_st ); KE_TRACE( 10, ("__kmp_team_static_init called (%d)\n", gtid)); #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmp_team_static_init enter: T#%%d liter=%%d "\ "iter=(%%%s, %%%s, %%%s) chunk %%%s; signed?<%s>\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, gtid, *p_last, *p_lb, *p_ub, *p_st, chunk ) ); __kmp_str_free( &buff ); } #endif lower = *p_lb; upper = *p_ub; if( __kmp_env_consistency_check ) { if( incr == 0 ) { __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); } if( incr > 0 ? (upper < lower) : (lower < upper) ) { // The loop is illegal. // Some zero-trip loops maintained by compiler, e.g.: // for(i=10;i<0;++i) // lower >= upper - run-time check // for(i=0;i>10;--i) // lower <= upper - run-time check // for(i=0;i>10;++i) // incr > 0 - compile-time check // for(i=10;i<0;--i) // incr < 0 - compile-time check // Compiler does not check the following illegal loops: // for(i=0;i<10;i+=incr) // where incr<0 // for(i=10;i>0;i-=incr) // where incr<0 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc ); } } th = __kmp_threads[gtid]; KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct team = th->th.th_team; #if OMP_40_ENABLED nteams = th->th.th_teams_size.nteams; #endif team_id = team->t.t_master_tid; KMP_DEBUG_ASSERT(nteams == team->t.t_parent->t.t_nproc); // compute trip count if( incr == 1 ) { trip_count = upper - lower + 1; } else if(incr == -1) { trip_count = lower - upper + 1; } else { trip_count = (ST)(upper - lower) / incr + 1; // cast to signed to cover incr<0 case } if( chunk < 1 ) chunk = 1; span = chunk * incr; *p_st = span * nteams; *p_lb = lower + (span * team_id); *p_ub = *p_lb + span - incr; if ( p_last != NULL ) *p_last = (team_id == ((trip_count - 1)/(UT)chunk) % nteams); // Correct upper bound if needed if( incr > 0 ) { if( *p_ub < *p_lb ) // overflow? *p_ub = i_maxmin< T >::mx; if( *p_ub > upper ) *p_ub = upper; // tracker C73258 } else { // incr < 0 if( *p_ub > *p_lb ) *p_ub = i_maxmin< T >::mn; if( *p_ub < upper ) *p_ub = upper; // tracker C73258 } #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmp_team_static_init exit: T#%%d team%%u liter=%%d "\ "iter=(%%%s, %%%s, %%%s) chunk %%%s\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< ST >::spec ); KD_TRACE(100, ( buff, gtid, team_id, *p_last, *p_lb, *p_ub, *p_st, chunk ) ); __kmp_str_free( &buff ); } #endif }
static void __kmp_dist_for_static_init( ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, T *plower, T *pupper, T *pupperDist, typename traits_t< T >::signed_t *pstride, typename traits_t< T >::signed_t incr, typename traits_t< T >::signed_t chunk ) { KMP_COUNT_BLOCK(OMP_DISTR_FOR_static); typedef typename traits_t< T >::unsigned_t UT; typedef typename traits_t< T >::signed_t ST; register kmp_uint32 tid; register kmp_uint32 nth; register kmp_uint32 team_id; register kmp_uint32 nteams; register UT trip_count; register kmp_team_t *team; kmp_info_t * th; KMP_DEBUG_ASSERT( plastiter && plower && pupper && pupperDist && pstride ); KE_TRACE( 10, ("__kmpc_dist_for_static_init called (%d)\n", gtid)); #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_dist_for_static_init: T#%%d schedLoop=%%d liter=%%d "\ "iter=(%%%s, %%%s, %%%s) chunk=%%%s signed?<%s>\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, gtid, schedule, *plastiter, *plower, *pupper, incr, chunk ) ); __kmp_str_free( &buff ); } #endif if( __kmp_env_consistency_check ) { __kmp_push_workshare( gtid, ct_pdo, loc ); if( incr == 0 ) { __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); } if( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) { // The loop is illegal. // Some zero-trip loops maintained by compiler, e.g.: // for(i=10;i<0;++i) // lower >= upper - run-time check // for(i=0;i>10;--i) // lower <= upper - run-time check // for(i=0;i>10;++i) // incr > 0 - compile-time check // for(i=10;i<0;--i) // incr < 0 - compile-time check // Compiler does not check the following illegal loops: // for(i=0;i<10;i+=incr) // where incr<0 // for(i=10;i>0;i-=incr) // where incr<0 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc ); } } tid = __kmp_tid_from_gtid( gtid ); th = __kmp_threads[gtid]; KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct nth = th->th.th_team_nproc; team = th->th.th_team; #if OMP_40_ENABLED nteams = th->th.th_teams_size.nteams; #endif team_id = team->t.t_master_tid; KMP_DEBUG_ASSERT(nteams == team->t.t_parent->t.t_nproc); // compute global trip count if( incr == 1 ) { trip_count = *pupper - *plower + 1; } else if(incr == -1) { trip_count = *plower - *pupper + 1; } else { trip_count = (ST)(*pupper - *plower) / incr + 1; // cast to signed to cover incr<0 case } *pstride = *pupper - *plower; // just in case (can be unused) if( trip_count <= nteams ) { KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy || \ __kmp_static == kmp_sch_static_balanced ); // Unknown static scheduling type. // only masters of some teams get single iteration, other threads get nothing if( team_id < trip_count && tid == 0 ) { *pupper = *pupperDist = *plower = *plower + team_id * incr; } else { *pupperDist = *pupper; *plower = *pupper + incr; // compiler should skip loop body } if( plastiter != NULL ) *plastiter = ( tid == 0 && team_id == trip_count - 1 ); } else { // Get the team's chunk first (each team gets at most one chunk) if( __kmp_static == kmp_sch_static_balanced ) { register UT chunkD = trip_count / nteams; register UT extras = trip_count % nteams; *plower += incr * ( team_id * chunkD + ( team_id < extras ? team_id : extras ) ); *pupperDist = *plower + chunkD * incr - ( team_id < extras ? 0 : incr ); if( plastiter != NULL ) *plastiter = ( team_id == nteams - 1 ); } else { register T chunk_inc_count = ( trip_count / nteams + ( ( trip_count % nteams ) ? 1 : 0) ) * incr; register T upper = *pupper; KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy ); // Unknown static scheduling type. *plower += team_id * chunk_inc_count; *pupperDist = *plower + chunk_inc_count - incr; // Check/correct bounds if needed if( incr > 0 ) { if( *pupperDist < *plower ) *pupperDist = i_maxmin< T >::mx; if( plastiter != NULL ) *plastiter = *plower <= upper && *pupperDist > upper - incr; if( *pupperDist > upper ) *pupperDist = upper; // tracker C73258 if( *plower > *pupperDist ) { *pupper = *pupperDist; // no iterations available for the team goto end; } } else { if( *pupperDist > *plower ) *pupperDist = i_maxmin< T >::mn; if( plastiter != NULL ) *plastiter = *plower >= upper && *pupperDist < upper - incr; if( *pupperDist < upper ) *pupperDist = upper; // tracker C73258 if( *plower < *pupperDist ) { *pupper = *pupperDist; // no iterations available for the team goto end; } } } // Get the parallel loop chunk now (for thread) // compute trip count for team's chunk if( incr == 1 ) { trip_count = *pupperDist - *plower + 1; } else if(incr == -1) { trip_count = *plower - *pupperDist + 1; } else { trip_count = (ST)(*pupperDist - *plower) / incr + 1; } KMP_DEBUG_ASSERT( trip_count ); switch( schedule ) { case kmp_sch_static: { if( trip_count <= nth ) { KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy || \ __kmp_static == kmp_sch_static_balanced ); // Unknown static scheduling type. if( tid < trip_count ) *pupper = *plower = *plower + tid * incr; else *plower = *pupper + incr; // no iterations available if( plastiter != NULL ) if( *plastiter != 0 && !( tid == trip_count - 1 ) ) *plastiter = 0; } else { if( __kmp_static == kmp_sch_static_balanced ) { register UT chunkL = trip_count / nth; register UT extras = trip_count % nth; *plower += incr * (tid * chunkL + (tid < extras ? tid : extras)); *pupper = *plower + chunkL * incr - (tid < extras ? 0 : incr); if( plastiter != NULL ) if( *plastiter != 0 && !( tid == nth - 1 ) ) *plastiter = 0; } else { register T chunk_inc_count = ( trip_count / nth + ( ( trip_count % nth ) ? 1 : 0) ) * incr; register T upper = *pupperDist; KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy ); // Unknown static scheduling type. *plower += tid * chunk_inc_count; *pupper = *plower + chunk_inc_count - incr; if( incr > 0 ) { if( *pupper < *plower ) *pupper = i_maxmin< T >::mx; if( plastiter != NULL ) if( *plastiter != 0 && !(*plower <= upper && *pupper > upper - incr) ) *plastiter = 0; if( *pupper > upper ) *pupper = upper;//tracker C73258 } else { if( *pupper > *plower ) *pupper = i_maxmin< T >::mn; if( plastiter != NULL ) if( *plastiter != 0 && !(*plower >= upper && *pupper < upper - incr) ) *plastiter = 0; if( *pupper < upper ) *pupper = upper;//tracker C73258 } } } break; } case kmp_sch_static_chunked: { register ST span; if( chunk < 1 ) chunk = 1; span = chunk * incr; *pstride = span * nth; *plower = *plower + (span * tid); *pupper = *plower + span - incr; if( plastiter != NULL ) if( *plastiter != 0 && !(tid == ((trip_count - 1) / ( UT )chunk) % nth) ) *plastiter = 0; break; } default: KMP_ASSERT2( 0, "__kmpc_dist_for_static_init: unknown loop scheduling type" ); break; } } end:; #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_dist_for_static_init: last=%%d lo=%%%s up=%%%s upDist=%%%s "\ "stride=%%%s signed?<%s>\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pupperDist, *pstride ) ); __kmp_str_free( &buff ); } #endif KE_TRACE( 10, ("__kmpc_dist_for_static_init: T#%d return\n", gtid ) ); return; }
__kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck ) #endif { struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KE_TRACE( 10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid() ) ); if (p->stack_top >= p->stack_size) __kmp_expand_cons_stack( gtid, p ); if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo || ct == ct_ordered_in_taskq ) { if (p->w_top <= p->p_top) { /* we are not in a worksharing construct */ #ifdef BUILD_PARALLEL_ORDERED /* do not report error messages for PARALLEL ORDERED */ KMP_ASSERT( ct == ct_ordered_in_parallel ); #else __kmp_error_construct( kmp_i18n_msg_CnsBoundToWorksharing, ct, ident ); #endif /* BUILD_PARALLEL_ORDERED */ } else { /* inside a WORKSHARING construct for this PARALLEL region */ if (!IS_CONS_TYPE_ORDERED(p->stack_data[ p->w_top ].type)) { if (p->stack_data[ p->w_top ].type == ct_taskq) { __kmp_error_construct2( kmp_i18n_msg_CnsNotInTaskConstruct, ct, ident, & p->stack_data[ p->w_top ] ); } else { __kmp_error_construct2( kmp_i18n_msg_CnsNoOrderedClause, ct, ident, & p->stack_data[ p->w_top ] ); } } } if (p->s_top > p->p_top && p->s_top > p->w_top) { /* inside a sync construct which is inside a worksharing construct */ int index = p->s_top; enum cons_type stack_type; stack_type = p->stack_data[ index ].type; if (stack_type == ct_critical || ( ( stack_type == ct_ordered_in_parallel || stack_type == ct_ordered_in_pdo || stack_type == ct_ordered_in_taskq ) && /* C doesn't allow named ordered; ordered in ordered gets error */ p->stack_data[ index ].ident != NULL && (p->stack_data[ index ].ident->flags & KMP_IDENT_KMPC ))) { /* we are in ORDERED which is inside an ORDERED or CRITICAL construct */ __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ index ] ); } } } else if ( ct == ct_critical ) { #if KMP_USE_DYNAMIC_LOCK if ( lck != NULL && __kmp_get_user_lock_owner( lck, seq ) == gtid ) { /* this same thread already has lock for this critical section */ #else if ( lck != NULL && __kmp_get_user_lock_owner( lck ) == gtid ) { /* this same thread already has lock for this critical section */ #endif int index = p->s_top; struct cons_data cons = { NULL, ct_critical, 0, NULL }; /* walk up construct stack and try to find critical with matching name */ while ( index != 0 && p->stack_data[ index ].name != lck ) { index = p->stack_data[ index ].prev; } if ( index != 0 ) { /* found match on the stack (may not always because of interleaved critical for Fortran) */ cons = p->stack_data[ index ]; } /* we are in CRITICAL which is inside a CRITICAL construct of the same name */ __kmp_error_construct2( kmp_i18n_msg_CnsNestingSameName, ct, ident, & cons ); } } else if ( ct == ct_master || ct == ct_reduce ) { if (p->w_top > p->p_top) { /* inside a WORKSHARING construct for this PARALLEL region */ __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->w_top ] ); } if (ct == ct_reduce && p->s_top > p->p_top) { /* inside a another SYNC construct for this PARALLEL region */ __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->s_top ] ); }; // if }; // if } void #if KMP_USE_DYNAMIC_LOCK __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq ) #else __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck ) #endif { int tos; struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons; KMP_ASSERT( gtid == __kmp_get_gtid() ); KE_TRACE( 10, ("__kmp_push_sync (gtid=%d)\n", gtid ) ); #if KMP_USE_DYNAMIC_LOCK __kmp_check_sync( gtid, ct, ident, lck, seq ); #else __kmp_check_sync( gtid, ct, ident, lck ); #endif KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) ); tos = ++ p->stack_top; p->stack_data[ tos ].type = ct; p->stack_data[ tos ].prev = p->s_top; p->stack_data[ tos ].ident = ident; p->stack_data[ tos ].name = lck; p->s_top = tos; KE_DUMP( 1000, dump_cons_stack( gtid, p ) ); }
static void __kmp_for_static_init( ident_t *loc, kmp_int32 global_tid, kmp_int32 schedtype, kmp_int32 *plastiter, T *plower, T *pupper, typename traits_t< T >::signed_t *pstride, typename traits_t< T >::signed_t incr, typename traits_t< T >::signed_t chunk ) { typedef typename traits_t< T >::unsigned_t UT; typedef typename traits_t< T >::signed_t ST; /* this all has to be changed back to TID and such.. */ register kmp_int32 gtid = global_tid; register kmp_uint32 tid; register kmp_uint32 nth; register UT trip_count; register kmp_team_t *team; KE_TRACE( 10, ("__kmpc_for_static_init called (%d)\n", global_tid)); #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," \ " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, global_tid, schedtype, *plastiter, *plower, *pupper, *pstride, incr, chunk ) ); __kmp_str_free( &buff ); } #endif if ( __kmp_env_consistency_check ) { __kmp_push_workshare( global_tid, ct_pdo, loc ); if ( incr == 0 ) { __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); } } /* special handling for zero-trip loops */ if ( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) { *plastiter = FALSE; /* leave pupper and plower set to entire iteration space */ *pstride = incr; /* value should never be used */ // *plower = *pupper - incr; // let compiler bypass the illegal loop (like for(i=1;i<10;i--)) THIS LINE CAUSED shape2F/h_tests_1.f TO HAVE A FAILURE ON A ZERO-TRIP LOOP (lower=1,\ upper=0,stride=1) - JPH June 23, 2009. #ifdef KMP_DEBUG { const char * buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init:(ZERO TRIP) liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>, loc = %%s\n", traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec ); KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride, loc->psource ) ); __kmp_str_free( &buff ); } #endif KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); return; }
static void __kmp_for_static_init(ident_t *loc, kmp_int32 global_tid, kmp_int32 schedtype, kmp_int32 *plastiter, T *plower, T *pupper, typename traits_t<T>::signed_t *pstride, typename traits_t<T>::signed_t incr, typename traits_t<T>::signed_t chunk #if OMPT_SUPPORT && OMPT_OPTIONAL , void *codeptr #endif ) { KMP_COUNT_BLOCK(OMP_FOR_static); KMP_TIME_PARTITIONED_BLOCK(FOR_static_scheduling); typedef typename traits_t<T>::unsigned_t UT; typedef typename traits_t<T>::signed_t ST; /* this all has to be changed back to TID and such.. */ kmp_int32 gtid = global_tid; kmp_uint32 tid; kmp_uint32 nth; UT trip_count; kmp_team_t *team; kmp_info_t *th = __kmp_threads[gtid]; #if OMPT_SUPPORT && OMPT_OPTIONAL ompt_team_info_t *team_info = NULL; ompt_task_info_t *task_info = NULL; ompt_work_type_t ompt_work_type = ompt_work_loop; static kmp_int8 warn = 0; if (ompt_enabled.ompt_callback_work) { // Only fully initialize variables needed by OMPT if OMPT is enabled. team_info = __ompt_get_teaminfo(0, NULL); task_info = __ompt_get_task_info_object(0); // Determine workshare type if (loc != NULL) { if ((loc->flags & KMP_IDENT_WORK_LOOP) != 0) { ompt_work_type = ompt_work_loop; } else if ((loc->flags & KMP_IDENT_WORK_SECTIONS) != 0) { ompt_work_type = ompt_work_sections; } else if ((loc->flags & KMP_IDENT_WORK_DISTRIBUTE) != 0) { ompt_work_type = ompt_work_distribute; } else { kmp_int8 bool_res = KMP_COMPARE_AND_STORE_ACQ8(&warn, (kmp_int8)0, (kmp_int8)1); if (bool_res) KMP_WARNING(OmptOutdatedWorkshare); } KMP_DEBUG_ASSERT(ompt_work_type); } } #endif KMP_DEBUG_ASSERT(plastiter && plower && pupper && pstride); KE_TRACE(10, ("__kmpc_for_static_init called (%d)\n", global_tid)); #ifdef KMP_DEBUG { char *buff; // create format specifiers before the debug output buff = __kmp_str_format( "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n", traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec, traits_t<ST>::spec, traits_t<ST>::spec, traits_t<T>::spec); KD_TRACE(100, (buff, global_tid, schedtype, *plastiter, *plower, *pupper, *pstride, incr, chunk)); __kmp_str_free(&buff); } #endif if (__kmp_env_consistency_check) { __kmp_push_workshare(global_tid, ct_pdo, loc); if (incr == 0) { __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc); } } /* special handling for zero-trip loops */ if (incr > 0 ? (*pupper < *plower) : (*plower < *pupper)) { if (plastiter != NULL) *plastiter = FALSE; /* leave pupper and plower set to entire iteration space */ *pstride = incr; /* value should never be used */ // *plower = *pupper - incr; // let compiler bypass the illegal loop (like for(i=1;i<10;i--)) // THE LINE COMMENTED ABOVE CAUSED shape2F/h_tests_1.f TO HAVE A FAILURE // ON A ZERO-TRIP LOOP (lower=1, upper=0,stride=1) - JPH June 23, 2009. #ifdef KMP_DEBUG { char *buff; // create format specifiers before the debug output buff = __kmp_str_format("__kmpc_for_static_init:(ZERO TRIP) liter=%%d " "lower=%%%s upper=%%%s stride = %%%s " "signed?<%s>, loc = %%s\n", traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec, traits_t<T>::spec); KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride, loc->psource)); __kmp_str_free(&buff); } #endif KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_work) { ompt_callbacks.ompt_callback(ompt_callback_work)( ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), &(task_info->task_data), 0, codeptr); } #endif KMP_COUNT_VALUE(FOR_static_iterations, 0); return; } #if OMP_40_ENABLED // Although there are schedule enumerations above kmp_ord_upper which are not // schedules for "distribute", the only ones which are useful are dynamic, so // cannot be seen here, since this codepath is only executed for static // schedules. if (schedtype > kmp_ord_upper) { // we are in DISTRIBUTE construct schedtype += kmp_sch_static - kmp_distribute_static; // AC: convert to usual schedule type tid = th->th.th_team->t.t_master_tid; team = th->th.th_team->t.t_parent; } else #endif { tid = __kmp_tid_from_gtid(global_tid); team = th->th.th_team; } /* determine if "for" loop is an active worksharing construct */ if (team->t.t_serialized) { /* serialized parallel, each thread executes whole iteration space */ if (plastiter != NULL) *plastiter = TRUE; /* leave pupper and plower set to entire iteration space */ *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); #ifdef KMP_DEBUG { char *buff; // create format specifiers before the debug output buff = __kmp_str_format("__kmpc_for_static_init: (serial) liter=%%d " "lower=%%%s upper=%%%s stride = %%%s\n", traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec); KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride)); __kmp_str_free(&buff); } #endif KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_work) { ompt_callbacks.ompt_callback(ompt_callback_work)( ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), &(task_info->task_data), *pstride, codeptr); } #endif return; } nth = team->t.t_nproc; if (nth == 1) { if (plastiter != NULL) *plastiter = TRUE; *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); #ifdef KMP_DEBUG { char *buff; // create format specifiers before the debug output buff = __kmp_str_format("__kmpc_for_static_init: (serial) liter=%%d " "lower=%%%s upper=%%%s stride = %%%s\n", traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec); KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride)); __kmp_str_free(&buff); } #endif KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_work) { ompt_callbacks.ompt_callback(ompt_callback_work)( ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), &(task_info->task_data), *pstride, codeptr); } #endif return; } /* compute trip count */ if (incr == 1) { trip_count = *pupper - *plower + 1; } else if (incr == -1) { trip_count = *plower - *pupper + 1; } else if (incr > 0) { // upper-lower can exceed the limit of signed type trip_count = (UT)(*pupper - *plower) / incr + 1; } else { trip_count = (UT)(*plower - *pupper) / (-incr) + 1; } if (__kmp_env_consistency_check) { /* tripcount overflow? */ if (trip_count == 0 && *pupper != *plower) { __kmp_error_construct(kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo, loc); } } KMP_COUNT_VALUE(FOR_static_iterations, trip_count); /* compute remaining parameters */ switch (schedtype) { case kmp_sch_static: { if (trip_count < nth) { KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy || __kmp_static == kmp_sch_static_balanced); // Unknown static scheduling type. if (tid < trip_count) { *pupper = *plower = *plower + tid * incr; } else { *plower = *pupper + incr; } if (plastiter != NULL) *plastiter = (tid == trip_count - 1); } else { if (__kmp_static == kmp_sch_static_balanced) { UT small_chunk = trip_count / nth; UT extras = trip_count % nth; *plower += incr * (tid * small_chunk + (tid < extras ? tid : extras)); *pupper = *plower + small_chunk * incr - (tid < extras ? 0 : incr); if (plastiter != NULL) *plastiter = (tid == nth - 1); } else { T big_chunk_inc_count = (trip_count / nth + ((trip_count % nth) ? 1 : 0)) * incr; T old_upper = *pupper; KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy); // Unknown static scheduling type. *plower += tid * big_chunk_inc_count; *pupper = *plower + big_chunk_inc_count - incr; if (incr > 0) { if (*pupper < *plower) *pupper = traits_t<T>::max_value; if (plastiter != NULL) *plastiter = *plower <= old_upper && *pupper > old_upper - incr; if (*pupper > old_upper) *pupper = old_upper; // tracker C73258 } else { if (*pupper > *plower) *pupper = traits_t<T>::min_value; if (plastiter != NULL) *plastiter = *plower >= old_upper && *pupper < old_upper - incr; if (*pupper < old_upper) *pupper = old_upper; // tracker C73258 } } } *pstride = trip_count; break; } case kmp_sch_static_chunked: { ST span; if (chunk < 1) { chunk = 1; } span = chunk * incr; *pstride = span * nth; *plower = *plower + (span * tid); *pupper = *plower + span - incr; if (plastiter != NULL) *plastiter = (tid == ((trip_count - 1) / (UT)chunk) % nth); break; } #if OMP_45_ENABLED case kmp_sch_static_balanced_chunked: { T old_upper = *pupper; // round up to make sure the chunk is enough to cover all iterations UT span = (trip_count + nth - 1) / nth; // perform chunk adjustment chunk = (span + chunk - 1) & ~(chunk - 1); span = chunk * incr; *plower = *plower + (span * tid); *pupper = *plower + span - incr; if (incr > 0) { if (*pupper > old_upper) *pupper = old_upper; } else if (*pupper < old_upper) *pupper = old_upper; if (plastiter != NULL) *plastiter = (tid == ((trip_count - 1) / (UT)chunk)); break; } #endif default: KMP_ASSERT2(0, "__kmpc_for_static_init: unknown scheduling type"); break; } #if USE_ITT_BUILD // Report loop metadata if (KMP_MASTER_TID(tid) && __itt_metadata_add_ptr && __kmp_forkjoin_frames_mode == 3 && #if OMP_40_ENABLED th->th.th_teams_microtask == NULL && #endif team->t.t_active_level == 1) { kmp_uint64 cur_chunk = chunk; // Calculate chunk in case it was not specified; it is specified for // kmp_sch_static_chunked if (schedtype == kmp_sch_static) { cur_chunk = trip_count / nth + ((trip_count % nth) ? 1 : 0); } // 0 - "static" schedule __kmp_itt_metadata_loop(loc, 0, trip_count, cur_chunk); } #endif #ifdef KMP_DEBUG { char *buff; // create format specifiers before the debug output buff = __kmp_str_format("__kmpc_for_static_init: liter=%%d lower=%%%s " "upper=%%%s stride = %%%s signed?<%s>\n", traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec, traits_t<T>::spec); KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride)); __kmp_str_free(&buff); } #endif KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_work) { ompt_callbacks.ompt_callback(ompt_callback_work)( ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), &(task_info->task_data), trip_count, codeptr); } #endif return; }