Exemplo n.º 1
0
void
__kmp_str_fname_free(
    kmp_str_fname_t * fname
) {
    __kmp_str_free( const_cast< char const ** >( & fname->path ) );
    __kmp_str_free( const_cast< char const ** >( & fname->dir  ) );
    __kmp_str_free( const_cast< char const ** >( & fname->base ) );
} // kmp_str_fname_free
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
void
__kmp_msg(
    kmp_msg_severity_t  severity,
    kmp_msg_t           message,
    ...
) {

    va_list        args;
    kmp_i18n_id_t  format;      // format identifier
    kmp_msg_t      fmsg;        // formatted message
    kmp_str_buf_t  buffer;

    if ( severity != kmp_ms_fatal && __kmp_generate_warnings == kmp_warnings_off )
        return; // no reason to form a string in order to not print it

    __kmp_str_buf_init( & buffer );

    // Format the primary message.
    switch ( severity ) {
        case kmp_ms_inform : {
            format = kmp_i18n_fmt_Info;
        } break;
        case kmp_ms_warning : {
            format = kmp_i18n_fmt_Warning;
        } break;
        case kmp_ms_fatal : {
            format = kmp_i18n_fmt_Fatal;
        } break;
        default : {
            KMP_DEBUG_ASSERT( 0 );
        };
    }; // switch
    fmsg = __kmp_msg_format( format, message.num, message.str );
    __kmp_str_free(&message.str);
    __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
    __kmp_str_free(&fmsg.str);

    // Format other messages.
    va_start( args, message );
    for ( ; ; ) {
        message = va_arg( args, kmp_msg_t );
        if ( message.type == kmp_mt_dummy && message.str == NULL ) {
            break;
        }; // if
        if ( message.type == kmp_mt_dummy && message.str == __kmp_msg_empty.str ) {
            continue;
        }; // if
        switch ( message.type ) {
            case kmp_mt_hint : {
                format = kmp_i18n_fmt_Hint;
            } break;
            case kmp_mt_syserr : {
                format = kmp_i18n_fmt_SysErr;
            } break;
            default : {
                KMP_DEBUG_ASSERT( 0 );
            };
        }; // switch
        fmsg = __kmp_msg_format( format, message.num, message.str );
        __kmp_str_free(&message.str);
        __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
        __kmp_str_free(&fmsg.str);
    }; // forever
    va_end( args );

    // Print formatted messages.
    // This lock prevents multiple fatal errors on the same problem.
    // __kmp_acquire_bootstrap_lock( & lock );    // GEH - This lock causing tests to hang on OS X*.
    __kmp_printf( "%s", buffer.str );
    __kmp_str_buf_free( & buffer );

    if ( severity == kmp_ms_fatal ) {
        #if KMP_OS_WINDOWS
        __kmp_thread_sleep( 500 );   /* Delay to give message a chance to appear before reaping */
        #endif
        __kmp_abort_process();
    }; // if

    // __kmp_release_bootstrap_lock( & lock );  // GEH - this lock causing tests to hang on OS X*.

} // __kmp_msg
Exemplo n.º 6
0
void
__kmp_i18n_do_catopen(
) {

    LCID          locale_id = GetThreadLocale();
    WORD          lang_id = LANGIDFROMLCID( locale_id );
    WORD          primary_lang_id = PRIMARYLANGID( lang_id );
    kmp_str_buf_t path;

    KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
    KMP_DEBUG_ASSERT( cat    == KMP_I18N_NULLCAT );

    __kmp_str_buf_init( & path );

    // Do not try to open English catalog because internal messages are
    // exact copy of messages in English catalog.
    if ( primary_lang_id == LANG_ENGLISH ) {
        status = KMP_I18N_ABSENT;  // mark catalog as absent so it will not be re-opened.
        goto end;
    }; // if

    // Construct resource DLL name.
    /*
        Simple
            LoadLibrary( name )
        is not suitable due to security issue (see
        http://www.microsoft.com/technet/security/advisory/2269637.mspx). We have to specify full
        path to the message catalog.
    */
    {

        // Get handle of our DLL first.
        HMODULE handle;
        BOOL brc =
            GetModuleHandleEx(
                GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                reinterpret_cast< LPCSTR >( & __kmp_i18n_do_catopen ),
                & handle
            );
        if ( ! brc ) {    // Error occurred.
            status = KMP_I18N_ABSENT;  // mark catalog as absent so it will not be re-opened.
            goto end;
            // TODO: Enable multiple messages (KMP_MSG) to be passed to __kmp_msg; and print
            // a proper warning.
        }; // if

        // Now get path to the our DLL.
        for ( ; ; ) {
            DWORD drc = GetModuleFileName( handle, path.str, path.size );
            if ( drc == 0 ) {    // Error occurred.
                status = KMP_I18N_ABSENT;
                goto end;
            }; // if
            if ( drc < path.size ) {
                path.used = drc;
                break;
            }; // if
            __kmp_str_buf_reserve( & path, path.size * 2 );
        }; // forever

        // Now construct the name of message catalog.
        kmp_str_fname fname;
        __kmp_str_fname_init( & fname, path.str );
        __kmp_str_buf_clear( & path );
        __kmp_str_buf_print( & path, "%s%lu/%s", fname.dir, (unsigned long)( locale_id ), name );
        __kmp_str_fname_free( & fname );

    }

    // For security reasons, use LoadLibraryEx() and load message catalog as a data file.
    cat = LoadLibraryEx( path.str, NULL, LOAD_LIBRARY_AS_DATAFILE );
    status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );

    if ( status == KMP_I18N_ABSENT ) {
      if (__kmp_generate_warnings > kmp_warnings_low) { // AC: only issue warning in case explicitly asked to
        DWORD error = GetLastError();
        // Infinite recursion will not occur -- status is KMP_I18N_ABSENT now, so
        // __kmp_i18n_catgets() will not try to open catalog but will return default message.
        /*
          If message catalog for another architecture found (e.g. OpenMP RTL
          for IA-32 architecture opens libompui.dll for Intel(R) 64)
          Windows* OS returns error 193 (ERROR_BAD_EXE_FORMAT). However,
          FormatMessage fails to return a message for this error, so user
          will see:

          OMP: Warning #2: Cannot open message catalog "1041\libompui.dll":
          OMP: System error #193: (No system error message available)
          OMP: Info #3: Default messages will be used.

          Issue a hint in this case to let cause of trouble more understandable.
        */
        kmp_msg_t err_code = KMP_SYSERRCODE(error);
        __kmp_msg(
            kmp_ms_warning,
            KMP_MSG( CantOpenMessageCatalog, path.str ),
            err_code,
            ( error == ERROR_BAD_EXE_FORMAT ? KMP_HNT( BadExeFormat, path.str, KMP_ARCH_STR ) : __kmp_msg_null ),
            __kmp_msg_null
        );
        if (__kmp_generate_warnings == kmp_warnings_off) {
            __kmp_str_free(&err_code.str);
        }

        KMP_INFORM( WillUseDefaultMessages );
      }
    } else { // status == KMP_I18N_OPENED

        int section = get_section( kmp_i18n_prp_Version );
        int number  = get_number( kmp_i18n_prp_Version );
        char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
        kmp_str_buf_t version;   // Actual version of the catalog.
        __kmp_str_buf_init( & version );
        __kmp_str_buf_print( & version, "%s", ___catgets( kmp_i18n_prp_Version ) );
            // String returned by catgets is invalid after closing the catalog, so copy it.
        if ( strcmp( version.str, expected ) != 0 ) {
            // Close bad catalog.
            __kmp_i18n_catclose();
            status = KMP_I18N_ABSENT;  // And mark it as absent.
            if (__kmp_generate_warnings > kmp_warnings_low) {
                // And now print a warning using default messages.
                __kmp_msg(
                    kmp_ms_warning,
                    KMP_MSG( WrongMessageCatalog, path.str, version.str, expected ),
                    __kmp_msg_null
                );
                KMP_INFORM( WillUseDefaultMessages );
            } // __kmp_generate_warnings
        }; // if
        __kmp_str_buf_free( & version );

    }; // if
    code_page = get_code_page();

    end:
        __kmp_str_buf_free( & path );
        return;

} // func __kmp_i18n_do_catopen
Exemplo n.º 7
0
void
__kmp_i18n_do_catopen(
) {
    int    english = 0;
    char * lang    = __kmp_env_get( "LANG" );
    // TODO: What about LC_ALL or LC_MESSAGES?

    KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
    KMP_DEBUG_ASSERT( cat    == KMP_I18N_NULLCAT );

    english =
        lang == NULL                       ||  // In all these cases English language is used.
        strcmp( lang, "" )            == 0 ||
        strcmp( lang, " " )           == 0 ||
        // Workaround for Fortran RTL bug DPD200137873 "Fortran runtime resets LANG env var
        // to space if it is not set".
        strcmp( lang, "C" )           == 0 ||
        strcmp( lang, "POSIX" )       == 0;

    if ( ! english ) {  // English language is not yet detected, let us continue.
        // Format of LANG is: [language[_territory][.codeset][@modifier]]
        // Strip all parts except language.
        char * tail = NULL;
        __kmp_str_split( lang, '@', & lang, & tail );
        __kmp_str_split( lang, '.', & lang, & tail );
        __kmp_str_split( lang, '_', & lang, & tail );
        english = ( strcmp( lang, "en" ) == 0 );
    }; // if

    KMP_INTERNAL_FREE( lang );

    // Do not try to open English catalog because internal messages are
    // exact copy of messages in English catalog.
    if ( english ) {
        status = KMP_I18N_ABSENT;  // mark catalog as absent so it will not be re-opened.
        return;
    }

    cat = catopen( name, 0 );
    // TODO: Why do we pass 0 in flags?
    status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );

    if ( status == KMP_I18N_ABSENT ) {
        if (__kmp_generate_warnings > kmp_warnings_low) { // AC: only issue warning in case explicitly asked to
            int    error   = errno; // Save errno immediately.
            char * nlspath = __kmp_env_get( "NLSPATH" );
            char * lang    = __kmp_env_get( "LANG" );

            // Infinite recursion will not occur -- status is KMP_I18N_ABSENT now, so
            // __kmp_i18n_catgets() will not try to open catalog, but will return default message.
            kmp_msg_t err_code = KMP_ERR( error );
            __kmp_msg(
                kmp_ms_warning,
                KMP_MSG( CantOpenMessageCatalog, name ),
                err_code,
                KMP_HNT( CheckEnvVar, "NLSPATH", nlspath ),
                KMP_HNT( CheckEnvVar, "LANG", lang ),
                __kmp_msg_null
            );
            if (__kmp_generate_warnings == kmp_warnings_off) {
                __kmp_str_free(&err_code.str);
            }

            KMP_INFORM( WillUseDefaultMessages );
            KMP_INTERNAL_FREE( nlspath );
            KMP_INTERNAL_FREE( lang );
        }
    } else { // status == KMP_I18N_OPENED

        int section = get_section( kmp_i18n_prp_Version );
        int number  = get_number( kmp_i18n_prp_Version );
        char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
        // Expected version of the catalog.
        kmp_str_buf_t version;   // Actual version of the catalog.
        __kmp_str_buf_init( & version );
        __kmp_str_buf_print( & version, "%s", catgets( cat, section, number, NULL ) );

        // String returned by catgets is invalid after closing the catalog, so copy it.
        if ( strcmp( version.str, expected ) != 0 ) {
            __kmp_i18n_catclose();     // Close bad catalog.
            status = KMP_I18N_ABSENT;  // And mark it as absent.
            if (__kmp_generate_warnings > kmp_warnings_low) { // AC: only issue warning in case explicitly asked to
                // And now print a warning using default messages.
                char const * name    = "NLSPATH";
                char const * nlspath = __kmp_env_get( name );
                __kmp_msg(
                    kmp_ms_warning,
                    KMP_MSG( WrongMessageCatalog, name, version.str, expected ),
                    KMP_HNT( CheckEnvVar, name, nlspath ),
                    __kmp_msg_null
                );
                KMP_INFORM( WillUseDefaultMessages );
                KMP_INTERNAL_FREE( (void *) nlspath );
            } // __kmp_generate_warnings
        }; // if
        __kmp_str_buf_free( & version );

    }; // if

} // func __kmp_i18n_do_catopen
Exemplo n.º 8
0
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;
}
static ompt_start_tool_result_t *
ompt_try_start_tool(unsigned int omp_version, const char *runtime_version) {
  ompt_start_tool_result_t *ret = NULL;
  ompt_start_tool_t start_tool = NULL;
#if KMP_OS_WINDOWS
  // Cannot use colon to describe a list of absolute paths on Windows
  const char *sep = ";";
#else
  const char *sep = ":";
#endif

#if KMP_OS_DARWIN
  // Try in the current address space
  ret = ompt_tool_darwin(omp_version, runtime_version);
#elif OMPT_HAVE_WEAK_ATTRIBUTE
  ret = ompt_start_tool(omp_version, runtime_version);
#elif OMPT_HAVE_PSAPI
  ret = ompt_tool_windows(omp_version, runtime_version);
#else
#error Activation of OMPT is not supported on this platform.
#endif
  if (ret)
    return ret;

  // Try tool-libraries-var ICV
  const char *tool_libs = getenv("OMP_TOOL_LIBRARIES");
  if (tool_libs) {
    char *libs = __kmp_str_format("%s", tool_libs);
    char *buf;
    char *fname = __kmp_str_token(libs, sep, &buf);
    while (fname) {
#if KMP_OS_UNIX
      void *h = dlopen(fname, RTLD_LAZY);
      if (h) {
        start_tool = (ompt_start_tool_t)dlsym(h, "ompt_start_tool");
#elif KMP_OS_WINDOWS
      HMODULE h = LoadLibrary(fname);
      if (h) {
        start_tool = (ompt_start_tool_t)GetProcAddress(h, "ompt_start_tool");
#else
#error Activation of OMPT is not supported on this platform.
#endif
        if (start_tool && (ret = (*start_tool)(omp_version, runtime_version)))
          break;
      }
      fname = __kmp_str_token(NULL, sep, &buf);
    }
    __kmp_str_free(&libs);
  }
  return ret;
}

void ompt_pre_init() {
  //--------------------------------------------------
  // Execute the pre-initialization logic only once.
  //--------------------------------------------------
  static int ompt_pre_initialized = 0;

  if (ompt_pre_initialized)
    return;

  ompt_pre_initialized = 1;

  //--------------------------------------------------
  // Use a tool iff a tool is enabled and available.
  //--------------------------------------------------
  const char *ompt_env_var = getenv("OMP_TOOL");
  tool_setting_e tool_setting = omp_tool_error;

  if (!ompt_env_var || !strcmp(ompt_env_var, ""))
    tool_setting = omp_tool_unset;
  else if (OMPT_STR_MATCH(ompt_env_var, "disabled"))
    tool_setting = omp_tool_disabled;
  else if (OMPT_STR_MATCH(ompt_env_var, "enabled"))
    tool_setting = omp_tool_enabled;

#if OMPT_DEBUG
  printf("ompt_pre_init(): tool_setting = %d\n", tool_setting);
#endif
  switch (tool_setting) {
  case omp_tool_disabled:
    break;

  case omp_tool_unset:
  case omp_tool_enabled:

    //--------------------------------------------------
    // Load tool iff specified in environment variable
    //--------------------------------------------------
    ompt_start_tool_result =
        ompt_try_start_tool(__kmp_openmp_version, ompt_get_runtime_version());

    memset(&ompt_enabled, 0, sizeof(ompt_enabled));
    break;

  case omp_tool_error:
    fprintf(stderr, "Warning: OMP_TOOL has invalid value \"%s\".\n"
                    "  legal values are (NULL,\"\",\"disabled\","
                    "\"enabled\").\n",
            ompt_env_var);
    break;
  }
#if OMPT_DEBUG
  printf("ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled);
#endif
}

void ompt_post_init() {
  //--------------------------------------------------
  // Execute the post-initialization logic only once.
  //--------------------------------------------------
  static int ompt_post_initialized = 0;

  if (ompt_post_initialized)
    return;

  ompt_post_initialized = 1;

  //--------------------------------------------------
  // Initialize the tool if so indicated.
  //--------------------------------------------------
  if (ompt_start_tool_result) {
    ompt_enabled.enabled = !!ompt_start_tool_result->initialize(
        ompt_fn_lookup, &(ompt_start_tool_result->tool_data));

    if (!ompt_enabled.enabled) {
      // tool not enabled, zero out the bitmap, and done
      memset(&ompt_enabled, 0, sizeof(ompt_enabled));
      return;
    }

    ompt_thread_t *root_thread = ompt_get_thread();

    ompt_set_thread_state(root_thread, omp_state_overhead);

    if (ompt_enabled.ompt_callback_thread_begin) {
      ompt_callbacks.ompt_callback(ompt_callback_thread_begin)(
          ompt_thread_initial, __ompt_get_thread_data_internal());
    }
    ompt_data_t *task_data;
    __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL, NULL);
    if (ompt_enabled.ompt_callback_task_create) {
      ompt_callbacks.ompt_callback(ompt_callback_task_create)(
          NULL, NULL, task_data, ompt_task_initial, 0, NULL);
    }

    ompt_set_thread_state(root_thread, omp_state_work_serial);
  }
}

void ompt_fini() {
  if (ompt_enabled.enabled) {
    ompt_start_tool_result->finalize(&(ompt_start_tool_result->tool_data));
  }

  memset(&ompt_enabled, 0, sizeof(ompt_enabled));
}

/*****************************************************************************
 * interface operations
 ****************************************************************************/

/*****************************************************************************
 * state
 ****************************************************************************/

OMPT_API_ROUTINE int ompt_enumerate_states(int current_state, int *next_state,
                                           const char **next_state_name) {
  const static int len = sizeof(omp_state_info) / sizeof(omp_state_info_t);
  int i = 0;

  for (i = 0; i < len - 1; i++) {
    if (omp_state_info[i].state_id == current_state) {
      *next_state = omp_state_info[i + 1].state_id;
      *next_state_name = omp_state_info[i + 1].state_name;
      return 1;
    }
  }

  return 0;
}

OMPT_API_ROUTINE int ompt_enumerate_mutex_impls(int current_impl,
                                                int *next_impl,
                                                const char **next_impl_name) {
  const static int len =
      sizeof(kmp_mutex_impl_info) / sizeof(kmp_mutex_impl_info_t);
  int i = 0;
  for (i = 0; i < len - 1; i++) {
    if (kmp_mutex_impl_info[i].id != current_impl)
      continue;
    *next_impl = kmp_mutex_impl_info[i + 1].id;
    *next_impl_name = kmp_mutex_impl_info[i + 1].name;
    return 1;
  }
  return 0;
}

/*****************************************************************************
 * callbacks
 ****************************************************************************/

OMPT_API_ROUTINE int ompt_set_callback(ompt_callbacks_t which,
                                       ompt_callback_t callback) {
  switch (which) {

#define ompt_event_macro(event_name, callback_type, event_id)                  \
  case event_name:                                                             \
    if (ompt_event_implementation_status(event_name)) {                        \
      ompt_callbacks.ompt_callback(event_name) = (callback_type)callback;      \
      ompt_enabled.event_name = (callback != 0);                               \
    }                                                                          \
    if (callback)                                                              \
      return ompt_event_implementation_status(event_name);                     \
    else                                                                       \
      return ompt_set_always;

    FOREACH_OMPT_EVENT(ompt_event_macro)

#undef ompt_event_macro

  default:
    return ompt_set_error;
  }
}

OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which,
                                       ompt_callback_t *callback) {
  switch (which) {

#define ompt_event_macro(event_name, callback_type, event_id)                  \
  case event_name:                                                             \
    if (ompt_event_implementation_status(event_name)) {                        \
      ompt_callback_t mycb =                                                   \
          (ompt_callback_t)ompt_callbacks.ompt_callback(event_name);           \
      if (mycb) {                                                              \
        *callback = mycb;                                                      \
        return ompt_get_callback_success;                                      \
      }                                                                        \
    }                                                                          \
    return ompt_get_callback_failure;

    FOREACH_OMPT_EVENT(ompt_event_macro)

#undef ompt_event_macro

  default:
    return ompt_get_callback_failure;
  }
}

/*****************************************************************************
 * parallel regions
 ****************************************************************************/

OMPT_API_ROUTINE int ompt_get_parallel_info(int ancestor_level,
                                            ompt_data_t **parallel_data,
                                            int *team_size) {
  return __ompt_get_parallel_info_internal(ancestor_level, parallel_data,
                                           team_size);
}

OMPT_API_ROUTINE omp_state_t ompt_get_state(omp_wait_id_t *wait_id) {
  omp_state_t thread_state = __ompt_get_state_internal(wait_id);

  if (thread_state == omp_state_undefined) {
    thread_state = omp_state_work_serial;
  }

  return thread_state;
}