00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include "kmp.h"
00057 #include "kmp_i18n.h"
00058 #include "kmp_str.h"
00059 #include "kmp_error.h"
00060
00061
00062 template< typename T >
00063 struct i_maxmin {
00064 static const T mx;
00065 static const T mn;
00066 };
00067 template<>
00068 struct i_maxmin< int > {
00069 static const int mx = 0x7fffffff;
00070 static const int mn = 0x80000000;
00071 };
00072 template<>
00073 struct i_maxmin< unsigned int > {
00074 static const unsigned int mx = 0xffffffff;
00075 static const unsigned int mn = 0x00000000;
00076 };
00077 template<>
00078 struct i_maxmin< long long > {
00079 static const long long mx = 0x7fffffffffffffffLL;
00080 static const long long mn = 0x8000000000000000LL;
00081 };
00082 template<>
00083 struct i_maxmin< unsigned long long > {
00084 static const unsigned long long mx = 0xffffffffffffffffLL;
00085 static const unsigned long long mn = 0x0000000000000000LL;
00086 };
00087
00088 #ifdef KMP_DEBUG
00089
00090
00091 char const * traits_t< int >::spec = "d";
00092 char const * traits_t< unsigned int >::spec = "u";
00093 char const * traits_t< long long >::spec = "lld";
00094 char const * traits_t< unsigned long long >::spec = "llu";
00095
00096 #endif
00097
00098 template< typename T >
00099 static void
00100 __kmp_for_static_init(
00101 ident_t *loc,
00102 kmp_int32 global_tid,
00103 kmp_int32 schedtype,
00104 kmp_int32 *plastiter,
00105 T *plower,
00106 T *pupper,
00107 typename traits_t< T >::signed_t *pstride,
00108 typename traits_t< T >::signed_t incr,
00109 typename traits_t< T >::signed_t chunk
00110 ) {
00111 typedef typename traits_t< T >::unsigned_t UT;
00112 typedef typename traits_t< T >::signed_t ST;
00113
00114 register kmp_int32 gtid = global_tid;
00115 register kmp_uint32 tid = __kmp_tid_from_gtid( global_tid );
00116 register kmp_uint32 nth;
00117 register UT trip_count;
00118 register kmp_team_t *team = __kmp_threads[ gtid ]->th.th_team;
00119
00120 KE_TRACE( 10, ("__kmpc_for_static_init called (%d)\n", global_tid));
00121 #ifdef KMP_DEBUG
00122 {
00123 const char * buff;
00124
00125 buff = __kmp_str_format(
00126 "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," \
00127 " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n",
00128 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec,
00129 traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec );
00130 KD_TRACE(100, ( buff, global_tid, schedtype, *plastiter,
00131 *plower, *pupper, *pstride, incr, chunk ) );
00132 __kmp_str_free( &buff );
00133 }
00134 #endif
00135
00136 if ( __kmp_env_consistency_check ) {
00137 __kmp_push_workshare( global_tid, ct_pdo, loc );
00138 if ( incr == 0 ) {
00139 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc );
00140
00141 }
00142 }
00143
00144 if ( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) {
00145 *plastiter = FALSE;
00146
00147 *pstride = incr;
00148
00149
00150 #ifdef KMP_DEBUG
00151 {
00152 const char * buff;
00153
00154 buff = __kmp_str_format(
00155 "__kmpc_for_static_init:(ZERO TRIP) liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>, loc = %%s\n",
00156 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec );
00157 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride, loc->psource ) );
00158 __kmp_str_free( &buff );
00159 }
00160 #endif
00161 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
00162 return;
00163 }
00164
00165
00166 if ( team -> t.t_serialized ) {
00167
00168 *plastiter = TRUE;
00169
00170 *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1));
00171
00172 #ifdef KMP_DEBUG
00173 {
00174 const char * buff;
00175
00176 buff = __kmp_str_format(
00177 "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n",
00178 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec );
00179 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) );
00180 __kmp_str_free( &buff );
00181 }
00182 #endif
00183 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
00184 return;
00185 }
00186 nth = team->t.t_nproc;
00187 if ( nth == 1 ) {
00188 *plastiter = TRUE;
00189
00190 #ifdef KMP_DEBUG
00191 {
00192 const char * buff;
00193
00194 buff = __kmp_str_format(
00195 "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n",
00196 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec );
00197 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) );
00198 __kmp_str_free( &buff );
00199 }
00200 #endif
00201 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
00202 return;
00203 }
00204
00205
00206 if ( incr == 1 ) {
00207 trip_count = *pupper - *plower + 1;
00208 } else if (incr == -1) {
00209 trip_count = *plower - *pupper + 1;
00210 } else {
00211 if ( incr > 1 ) {
00212 trip_count = (*pupper - *plower) / incr + 1;
00213 } else {
00214 trip_count = (*plower - *pupper) / ( -incr ) + 1;
00215 }
00216 }
00217 if ( __kmp_env_consistency_check ) {
00218
00219 if ( trip_count == 0 && *pupper != *plower ) {
00220 __kmp_error_construct( kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo, loc );
00221 }
00222 }
00223
00224
00225 switch ( schedtype ) {
00226 case kmp_sch_static:
00227 {
00228 if ( trip_count < nth ) {
00229 KMP_DEBUG_ASSERT(
00230 __kmp_static == kmp_sch_static_greedy || \
00231 __kmp_static == kmp_sch_static_balanced
00232 );
00233 if ( tid < trip_count ) {
00234 *pupper = *plower = *plower + tid * incr;
00235 } else {
00236 *plower = *pupper + incr;
00237 }
00238 *plastiter = ( tid == trip_count - 1 );
00239 } else {
00240 if ( __kmp_static == kmp_sch_static_balanced ) {
00241 register UT small_chunk = trip_count / nth;
00242 register UT extras = trip_count % nth;
00243 *plower += incr * ( tid * small_chunk + ( tid < extras ? tid : extras ) );
00244 *pupper = *plower + small_chunk * incr - ( tid < extras ? 0 : incr );
00245 *plastiter = ( tid == nth - 1 );
00246 } else {
00247 register T big_chunk_inc_count = ( trip_count/nth +
00248 ( ( trip_count % nth ) ? 1 : 0) ) * incr;
00249 register T old_upper = *pupper;
00250
00251 KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy );
00252
00253
00254 *plower += tid * big_chunk_inc_count;
00255 *pupper = *plower + big_chunk_inc_count - incr;
00256 if ( incr > 0 ) {
00257 if ( *pupper < *plower ) {
00258 *pupper = i_maxmin< T >::mx;
00259 }
00260 *plastiter = *plower <= old_upper && *pupper > old_upper - incr;
00261 if ( *pupper > old_upper ) *pupper = old_upper;
00262 } else {
00263 if ( *pupper > *plower ) {
00264 *pupper = i_maxmin< T >::mn;
00265 }
00266 *plastiter = *plower >= old_upper && *pupper < old_upper - incr;
00267 if ( *pupper < old_upper ) *pupper = old_upper;
00268 }
00269 }
00270 }
00271 break;
00272 }
00273 case kmp_sch_static_chunked:
00274 {
00275 register T span;
00276 if ( chunk < 1 ) {
00277 chunk = 1;
00278 }
00279 span = chunk * incr;
00280 *pstride = span * nth;
00281 *plower = *plower + (span * tid);
00282 *pupper = *plower + span - incr;
00283
00284 if (*plastiter) {
00285 kmp_int32 lasttid = ((trip_count - 1) / ( UT )chunk) % nth;
00286 *plastiter = (tid == lasttid);
00287 }
00288 break;
00289 }
00290 default:
00291 KMP_ASSERT2( 0, "__kmpc_for_static_init: unknown scheduling type" );
00292 break;
00293 }
00294
00295 #ifdef KMP_DEBUG
00296 {
00297 const char * buff;
00298
00299 buff = __kmp_str_format(
00300 "__kmpc_for_static_init: liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>\n",
00301 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec );
00302 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) );
00303 __kmp_str_free( &buff );
00304 }
00305 #endif
00306 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
00307
00308 #if OMPT_SUPPORT
00309 kmp_info_t *this_thr = __kmp_threads[ global_tid ];
00310 if ((ompt_status == ompt_status_track_callback)) {
00311 if (ompt_callbacks.ompt_callback(ompt_event_loop_begin)) {
00312 ompt_callbacks.ompt_callback(ompt_event_loop_begin)
00313 (team->t.ompt_team_info.parallel_id,
00314 team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_id);
00315 }
00316 }
00317 #endif
00318
00319 return;
00320 }
00321
00322
00323 extern "C" {
00324
00345 void
00346 __kmpc_for_static_init_4( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
00347 kmp_int32 *plower, kmp_int32 *pupper,
00348 kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk )
00349 {
00350 __kmp_for_static_init< kmp_int32 >(
00351 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
00352 }
00353
00357 void
00358 __kmpc_for_static_init_4u( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
00359 kmp_uint32 *plower, kmp_uint32 *pupper,
00360 kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk )
00361 {
00362 __kmp_for_static_init< kmp_uint32 >(
00363 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
00364 }
00365
00369 void
00370 __kmpc_for_static_init_8( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
00371 kmp_int64 *plower, kmp_int64 *pupper,
00372 kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk )
00373 {
00374 __kmp_for_static_init< kmp_int64 >(
00375 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
00376 }
00377
00381 void
00382 __kmpc_for_static_init_8u( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
00383 kmp_uint64 *plower, kmp_uint64 *pupper,
00384 kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk )
00385 {
00386 __kmp_for_static_init< kmp_uint64 >(
00387 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
00388 }
00393 }
00394