1 /* 2 * kmp_sched.c -- static scheduling -- iteration initialization 3 */ 4 5 6 //===----------------------------------------------------------------------===// 7 // 8 // The LLVM Compiler Infrastructure 9 // 10 // This file is dual licensed under the MIT and the University of Illinois Open 11 // Source Licenses. See LICENSE.txt for details. 12 // 13 //===----------------------------------------------------------------------===// 14 15 16 /* 17 * Static scheduling initialization. 18 * 19 * NOTE: team->t.t_nproc is a constant inside of any dispatch loop, however 20 * it may change values between parallel regions. __kmp_max_nth 21 * is the largest value __kmp_nth may take, 1 is the smallest. 22 * 23 */ 24 25 #include "kmp.h" 26 #include "kmp_i18n.h" 27 #include "kmp_str.h" 28 #include "kmp_error.h" 29 #include "kmp_stats.h" 30 #include "kmp_itt.h" 31 32 // template for type limits 33 template< typename T > 34 struct i_maxmin { 35 static const T mx; 36 static const T mn; 37 }; 38 template<> 39 struct i_maxmin< int > { 40 static const int mx = 0x7fffffff; 41 static const int mn = 0x80000000; 42 }; 43 template<> 44 struct i_maxmin< unsigned int > { 45 static const unsigned int mx = 0xffffffff; 46 static const unsigned int mn = 0x00000000; 47 }; 48 template<> 49 struct i_maxmin< long long > { 50 static const long long mx = 0x7fffffffffffffffLL; 51 static const long long mn = 0x8000000000000000LL; 52 }; 53 template<> 54 struct i_maxmin< unsigned long long > { 55 static const unsigned long long mx = 0xffffffffffffffffLL; 56 static const unsigned long long mn = 0x0000000000000000LL; 57 }; 58 //------------------------------------------------------------------------- 59 #ifdef KMP_DEBUG 60 //------------------------------------------------------------------------- 61 // template for debug prints specification ( d, u, lld, llu ) 62 char const * traits_t< int >::spec = "d"; 63 char const * traits_t< unsigned int >::spec = "u"; 64 char const * traits_t< long long >::spec = "lld"; 65 char const * traits_t< unsigned long long >::spec = "llu"; 66 //------------------------------------------------------------------------- 67 #endif 68 69 template< typename T > 70 static void 71 __kmp_for_static_init( 72 ident_t *loc, 73 kmp_int32 global_tid, 74 kmp_int32 schedtype, 75 kmp_int32 *plastiter, 76 T *plower, 77 T *pupper, 78 typename traits_t< T >::signed_t *pstride, 79 typename traits_t< T >::signed_t incr, 80 typename traits_t< T >::signed_t chunk 81 ) { 82 KMP_COUNT_BLOCK(OMP_FOR_static); 83 typedef typename traits_t< T >::unsigned_t UT; 84 typedef typename traits_t< T >::signed_t ST; 85 /* this all has to be changed back to TID and such.. */ 86 register kmp_int32 gtid = global_tid; 87 register kmp_uint32 tid; 88 register kmp_uint32 nth; 89 register UT trip_count; 90 register kmp_team_t *team; 91 92 KMP_DEBUG_ASSERT( plastiter && plower && pupper && pstride ); 93 KE_TRACE( 10, ("__kmpc_for_static_init called (%d)\n", global_tid)); 94 #ifdef KMP_DEBUG 95 { 96 const char * buff; 97 // create format specifiers before the debug output 98 buff = __kmp_str_format( 99 "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," \ 100 " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n", 101 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, 102 traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec ); 103 KD_TRACE(100, ( buff, global_tid, schedtype, *plastiter, 104 *plower, *pupper, *pstride, incr, chunk ) ); 105 __kmp_str_free( &buff ); 106 } 107 #endif 108 109 if ( __kmp_env_consistency_check ) { 110 __kmp_push_workshare( global_tid, ct_pdo, loc ); 111 if ( incr == 0 ) { 112 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); 113 } 114 } 115 /* special handling for zero-trip loops */ 116 if ( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) { 117 if( plastiter != NULL ) 118 *plastiter = FALSE; 119 /* leave pupper and plower set to entire iteration space */ 120 *pstride = incr; /* value should never be used */ 121 // *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,\ 122 upper=0,stride=1) - JPH June 23, 2009. 123 #ifdef KMP_DEBUG 124 { 125 const char * buff; 126 // create format specifiers before the debug output 127 buff = __kmp_str_format( 128 "__kmpc_for_static_init:(ZERO TRIP) liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>, loc = %%s\n", 129 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec ); 130 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride, loc->psource ) ); 131 __kmp_str_free( &buff ); 132 } 133 #endif 134 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); 135 return; 136 } 137 138 #if OMP_40_ENABLED 139 if ( schedtype > kmp_ord_upper ) { 140 // we are in DISTRIBUTE construct 141 schedtype += kmp_sch_static - kmp_distribute_static; // AC: convert to usual schedule type 142 tid = __kmp_threads[ gtid ]->th.th_team->t.t_master_tid; 143 team = __kmp_threads[ gtid ]->th.th_team->t.t_parent; 144 } else 145 #endif 146 { 147 tid = __kmp_tid_from_gtid( global_tid ); 148 team = __kmp_threads[ gtid ]->th.th_team; 149 } 150 151 /* determine if "for" loop is an active worksharing construct */ 152 if ( team -> t.t_serialized ) { 153 /* serialized parallel, each thread executes whole iteration space */ 154 if( plastiter != NULL ) 155 *plastiter = TRUE; 156 /* leave pupper and plower set to entire iteration space */ 157 *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); 158 159 #ifdef KMP_DEBUG 160 { 161 const char * buff; 162 // create format specifiers before the debug output 163 buff = __kmp_str_format( 164 "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n", 165 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec ); 166 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) ); 167 __kmp_str_free( &buff ); 168 } 169 #endif 170 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); 171 return; 172 } 173 nth = team->t.t_nproc; 174 if ( nth == 1 ) { 175 if( plastiter != NULL ) 176 *plastiter = TRUE; 177 *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); 178 #ifdef KMP_DEBUG 179 { 180 const char * buff; 181 // create format specifiers before the debug output 182 buff = __kmp_str_format( 183 "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n", 184 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec ); 185 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) ); 186 __kmp_str_free( &buff ); 187 } 188 #endif 189 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); 190 return; 191 } 192 193 /* compute trip count */ 194 if ( incr == 1 ) { 195 trip_count = *pupper - *plower + 1; 196 } else if (incr == -1) { 197 trip_count = *plower - *pupper + 1; 198 } else { 199 if ( incr > 1 ) { // the check is needed for unsigned division when incr < 0 200 trip_count = (*pupper - *plower) / incr + 1; 201 } else { 202 trip_count = (*plower - *pupper) / ( -incr ) + 1; 203 } 204 } 205 206 if ( __kmp_env_consistency_check ) { 207 /* tripcount overflow? */ 208 if ( trip_count == 0 && *pupper != *plower ) { 209 __kmp_error_construct( kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo, loc ); 210 } 211 } 212 213 /* compute remaining parameters */ 214 switch ( schedtype ) { 215 case kmp_sch_static: 216 { 217 if ( trip_count < nth ) { 218 KMP_DEBUG_ASSERT( 219 __kmp_static == kmp_sch_static_greedy || \ 220 __kmp_static == kmp_sch_static_balanced 221 ); // Unknown static scheduling type. 222 if ( tid < trip_count ) { 223 *pupper = *plower = *plower + tid * incr; 224 } else { 225 *plower = *pupper + incr; 226 } 227 if( plastiter != NULL ) 228 *plastiter = ( tid == trip_count - 1 ); 229 } else { 230 if ( __kmp_static == kmp_sch_static_balanced ) { 231 register UT small_chunk = trip_count / nth; 232 register UT extras = trip_count % nth; 233 *plower += incr * ( tid * small_chunk + ( tid < extras ? tid : extras ) ); 234 *pupper = *plower + small_chunk * incr - ( tid < extras ? 0 : incr ); 235 if( plastiter != NULL ) 236 *plastiter = ( tid == nth - 1 ); 237 } else { 238 register T big_chunk_inc_count = ( trip_count/nth + 239 ( ( trip_count % nth ) ? 1 : 0) ) * incr; 240 register T old_upper = *pupper; 241 242 KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy ); 243 // Unknown static scheduling type. 244 245 *plower += tid * big_chunk_inc_count; 246 *pupper = *plower + big_chunk_inc_count - incr; 247 if ( incr > 0 ) { 248 if( *pupper < *plower ) 249 *pupper = i_maxmin< T >::mx; 250 if( plastiter != NULL ) 251 *plastiter = *plower <= old_upper && *pupper > old_upper - incr; 252 if ( *pupper > old_upper ) *pupper = old_upper; // tracker C73258 253 } else { 254 if( *pupper > *plower ) 255 *pupper = i_maxmin< T >::mn; 256 if( plastiter != NULL ) 257 *plastiter = *plower >= old_upper && *pupper < old_upper - incr; 258 if ( *pupper < old_upper ) *pupper = old_upper; // tracker C73258 259 } 260 } 261 } 262 break; 263 } 264 case kmp_sch_static_chunked: 265 { 266 register ST span; 267 if ( chunk < 1 ) { 268 chunk = 1; 269 } 270 span = chunk * incr; 271 *pstride = span * nth; 272 *plower = *plower + (span * tid); 273 *pupper = *plower + span - incr; 274 if( plastiter != NULL ) 275 *plastiter = (tid == ((trip_count - 1)/( UT )chunk) % nth); 276 break; 277 } 278 default: 279 KMP_ASSERT2( 0, "__kmpc_for_static_init: unknown scheduling type" ); 280 break; 281 } 282 283 #if USE_ITT_BUILD 284 // Report loop metadata 285 if ( KMP_MASTER_TID(tid) && __itt_metadata_add_ptr && __kmp_forkjoin_frames_mode == 3 ) { 286 kmp_uint64 cur_chunk = chunk; 287 // Calculate chunk in case it was not specified; it is specified for kmp_sch_static_chunked 288 if ( schedtype == kmp_sch_static ) { 289 cur_chunk = trip_count / nth + ( ( trip_count % nth ) ? 1 : 0); 290 } 291 // 0 - "static" schedule 292 __kmp_itt_metadata_loop(loc, 0, trip_count, cur_chunk); 293 } 294 #endif 295 #ifdef KMP_DEBUG 296 { 297 const char * buff; 298 // create format specifiers before the debug output 299 buff = __kmp_str_format( 300 "__kmpc_for_static_init: liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>\n", 301 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec ); 302 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) ); 303 __kmp_str_free( &buff ); 304 } 305 #endif 306 KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) ); 307 return; 308 } 309 310 template< typename T > 311 static void 312 __kmp_dist_for_static_init( 313 ident_t *loc, 314 kmp_int32 gtid, 315 kmp_int32 schedule, 316 kmp_int32 *plastiter, 317 T *plower, 318 T *pupper, 319 T *pupperDist, 320 typename traits_t< T >::signed_t *pstride, 321 typename traits_t< T >::signed_t incr, 322 typename traits_t< T >::signed_t chunk 323 ) { 324 KMP_COUNT_BLOCK(OMP_DISTR_FOR_static); 325 typedef typename traits_t< T >::unsigned_t UT; 326 typedef typename traits_t< T >::signed_t ST; 327 register kmp_uint32 tid; 328 register kmp_uint32 nth; 329 register kmp_uint32 team_id; 330 register kmp_uint32 nteams; 331 register UT trip_count; 332 register kmp_team_t *team; 333 kmp_info_t * th; 334 335 KMP_DEBUG_ASSERT( plastiter && plower && pupper && pupperDist && pstride ); 336 KE_TRACE( 10, ("__kmpc_dist_for_static_init called (%d)\n", gtid)); 337 #ifdef KMP_DEBUG 338 { 339 const char * buff; 340 // create format specifiers before the debug output 341 buff = __kmp_str_format( 342 "__kmpc_dist_for_static_init: T#%%d schedLoop=%%d liter=%%d "\ 343 "iter=(%%%s, %%%s, %%%s) chunk=%%%s signed?<%s>\n", 344 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, 345 traits_t< ST >::spec, traits_t< T >::spec ); 346 KD_TRACE(100, ( buff, gtid, schedule, *plastiter, 347 *plower, *pupper, incr, chunk ) ); 348 __kmp_str_free( &buff ); 349 } 350 #endif 351 352 if( __kmp_env_consistency_check ) { 353 __kmp_push_workshare( gtid, ct_pdo, loc ); 354 if( incr == 0 ) { 355 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); 356 } 357 if( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) { 358 // The loop is illegal. 359 // Some zero-trip loops maintained by compiler, e.g.: 360 // for(i=10;i<0;++i) // lower >= upper - run-time check 361 // for(i=0;i>10;--i) // lower <= upper - run-time check 362 // for(i=0;i>10;++i) // incr > 0 - compile-time check 363 // for(i=10;i<0;--i) // incr < 0 - compile-time check 364 // Compiler does not check the following illegal loops: 365 // for(i=0;i<10;i+=incr) // where incr<0 366 // for(i=10;i>0;i-=incr) // where incr<0 367 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc ); 368 } 369 } 370 tid = __kmp_tid_from_gtid( gtid ); 371 th = __kmp_threads[gtid]; 372 KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct 373 nth = th->th.th_team_nproc; 374 team = th->th.th_team; 375 #if OMP_40_ENABLED 376 nteams = th->th.th_teams_size.nteams; 377 #endif 378 team_id = team->t.t_master_tid; 379 KMP_DEBUG_ASSERT(nteams == team->t.t_parent->t.t_nproc); 380 381 // compute global trip count 382 if( incr == 1 ) { 383 trip_count = *pupper - *plower + 1; 384 } else if(incr == -1) { 385 trip_count = *plower - *pupper + 1; 386 } else { 387 trip_count = (ST)(*pupper - *plower) / incr + 1; // cast to signed to cover incr<0 case 388 } 389 *pstride = *pupper - *plower; // just in case (can be unused) 390 if( trip_count <= nteams ) { 391 KMP_DEBUG_ASSERT( 392 __kmp_static == kmp_sch_static_greedy || \ 393 __kmp_static == kmp_sch_static_balanced 394 ); // Unknown static scheduling type. 395 // only masters of some teams get single iteration, other threads get nothing 396 if( team_id < trip_count && tid == 0 ) { 397 *pupper = *pupperDist = *plower = *plower + team_id * incr; 398 } else { 399 *pupperDist = *pupper; 400 *plower = *pupper + incr; // compiler should skip loop body 401 } 402 if( plastiter != NULL ) 403 *plastiter = ( tid == 0 && team_id == trip_count - 1 ); 404 } else { 405 // Get the team's chunk first (each team gets at most one chunk) 406 if( __kmp_static == kmp_sch_static_balanced ) { 407 register UT chunkD = trip_count / nteams; 408 register UT extras = trip_count % nteams; 409 *plower += incr * ( team_id * chunkD + ( team_id < extras ? team_id : extras ) ); 410 *pupperDist = *plower + chunkD * incr - ( team_id < extras ? 0 : incr ); 411 if( plastiter != NULL ) 412 *plastiter = ( team_id == nteams - 1 ); 413 } else { 414 register T chunk_inc_count = 415 ( trip_count / nteams + ( ( trip_count % nteams ) ? 1 : 0) ) * incr; 416 register T upper = *pupper; 417 KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy ); 418 // Unknown static scheduling type. 419 *plower += team_id * chunk_inc_count; 420 *pupperDist = *plower + chunk_inc_count - incr; 421 // Check/correct bounds if needed 422 if( incr > 0 ) { 423 if( *pupperDist < *plower ) 424 *pupperDist = i_maxmin< T >::mx; 425 if( plastiter != NULL ) 426 *plastiter = *plower <= upper && *pupperDist > upper - incr; 427 if( *pupperDist > upper ) 428 *pupperDist = upper; // tracker C73258 429 if( *plower > *pupperDist ) { 430 *pupper = *pupperDist; // no iterations available for the team 431 goto end; 432 } 433 } else { 434 if( *pupperDist > *plower ) 435 *pupperDist = i_maxmin< T >::mn; 436 if( plastiter != NULL ) 437 *plastiter = *plower >= upper && *pupperDist < upper - incr; 438 if( *pupperDist < upper ) 439 *pupperDist = upper; // tracker C73258 440 if( *plower < *pupperDist ) { 441 *pupper = *pupperDist; // no iterations available for the team 442 goto end; 443 } 444 } 445 } 446 // Get the parallel loop chunk now (for thread) 447 // compute trip count for team's chunk 448 if( incr == 1 ) { 449 trip_count = *pupperDist - *plower + 1; 450 } else if(incr == -1) { 451 trip_count = *plower - *pupperDist + 1; 452 } else { 453 trip_count = (ST)(*pupperDist - *plower) / incr + 1; 454 } 455 KMP_DEBUG_ASSERT( trip_count ); 456 switch( schedule ) { 457 case kmp_sch_static: 458 { 459 if( trip_count <= nth ) { 460 KMP_DEBUG_ASSERT( 461 __kmp_static == kmp_sch_static_greedy || \ 462 __kmp_static == kmp_sch_static_balanced 463 ); // Unknown static scheduling type. 464 if( tid < trip_count ) 465 *pupper = *plower = *plower + tid * incr; 466 else 467 *plower = *pupper + incr; // no iterations available 468 if( plastiter != NULL ) 469 if( *plastiter != 0 && !( tid == trip_count - 1 ) ) 470 *plastiter = 0; 471 } else { 472 if( __kmp_static == kmp_sch_static_balanced ) { 473 register UT chunkL = trip_count / nth; 474 register UT extras = trip_count % nth; 475 *plower += incr * (tid * chunkL + (tid < extras ? tid : extras)); 476 *pupper = *plower + chunkL * incr - (tid < extras ? 0 : incr); 477 if( plastiter != NULL ) 478 if( *plastiter != 0 && !( tid == nth - 1 ) ) 479 *plastiter = 0; 480 } else { 481 register T chunk_inc_count = 482 ( trip_count / nth + ( ( trip_count % nth ) ? 1 : 0) ) * incr; 483 register T upper = *pupperDist; 484 KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy ); 485 // Unknown static scheduling type. 486 *plower += tid * chunk_inc_count; 487 *pupper = *plower + chunk_inc_count - incr; 488 if( incr > 0 ) { 489 if( *pupper < *plower ) 490 *pupper = i_maxmin< T >::mx; 491 if( plastiter != NULL ) 492 if( *plastiter != 0 && !(*plower <= upper && *pupper > upper - incr) ) 493 *plastiter = 0; 494 if( *pupper > upper ) 495 *pupper = upper;//tracker C73258 496 } else { 497 if( *pupper > *plower ) 498 *pupper = i_maxmin< T >::mn; 499 if( plastiter != NULL ) 500 if( *plastiter != 0 && !(*plower >= upper && *pupper < upper - incr) ) 501 *plastiter = 0; 502 if( *pupper < upper ) 503 *pupper = upper;//tracker C73258 504 } 505 } 506 } 507 break; 508 } 509 case kmp_sch_static_chunked: 510 { 511 register ST span; 512 if( chunk < 1 ) 513 chunk = 1; 514 span = chunk * incr; 515 *pstride = span * nth; 516 *plower = *plower + (span * tid); 517 *pupper = *plower + span - incr; 518 if( plastiter != NULL ) 519 if( *plastiter != 0 && !(tid == ((trip_count - 1) / ( UT )chunk) % nth) ) 520 *plastiter = 0; 521 break; 522 } 523 default: 524 KMP_ASSERT2( 0, "__kmpc_dist_for_static_init: unknown loop scheduling type" ); 525 break; 526 } 527 } 528 end:; 529 #ifdef KMP_DEBUG 530 { 531 const char * buff; 532 // create format specifiers before the debug output 533 buff = __kmp_str_format( 534 "__kmpc_dist_for_static_init: last=%%d lo=%%%s up=%%%s upDist=%%%s "\ 535 "stride=%%%s signed?<%s>\n", 536 traits_t< T >::spec, traits_t< T >::spec, traits_t< T >::spec, 537 traits_t< ST >::spec, traits_t< T >::spec ); 538 KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pupperDist, *pstride ) ); 539 __kmp_str_free( &buff ); 540 } 541 #endif 542 KE_TRACE( 10, ("__kmpc_dist_for_static_init: T#%d return\n", gtid ) ); 543 return; 544 } 545 546 template< typename T > 547 static void 548 __kmp_team_static_init( 549 ident_t *loc, 550 kmp_int32 gtid, 551 kmp_int32 *p_last, 552 T *p_lb, 553 T *p_ub, 554 typename traits_t< T >::signed_t *p_st, 555 typename traits_t< T >::signed_t incr, 556 typename traits_t< T >::signed_t chunk 557 ) { 558 // The routine returns the first chunk distributed to the team and 559 // stride for next chunks calculation. 560 // Last iteration flag set for the team that will execute 561 // the last iteration of the loop. 562 // The routine is called for dist_schedue(static,chunk) only. 563 typedef typename traits_t< T >::unsigned_t UT; 564 typedef typename traits_t< T >::signed_t ST; 565 kmp_uint32 team_id; 566 kmp_uint32 nteams; 567 UT trip_count; 568 T lower; 569 T upper; 570 ST span; 571 kmp_team_t *team; 572 kmp_info_t *th; 573 574 KMP_DEBUG_ASSERT( p_last && p_lb && p_ub && p_st ); 575 KE_TRACE( 10, ("__kmp_team_static_init called (%d)\n", gtid)); 576 #ifdef KMP_DEBUG 577 { 578 const char * buff; 579 // create format specifiers before the debug output 580 buff = __kmp_str_format( "__kmp_team_static_init enter: T#%%d liter=%%d "\ 581 "iter=(%%%s, %%%s, %%%s) chunk %%%s; signed?<%s>\n", 582 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, 583 traits_t< ST >::spec, traits_t< T >::spec ); 584 KD_TRACE(100, ( buff, gtid, *p_last, *p_lb, *p_ub, *p_st, chunk ) ); 585 __kmp_str_free( &buff ); 586 } 587 #endif 588 589 lower = *p_lb; 590 upper = *p_ub; 591 if( __kmp_env_consistency_check ) { 592 if( incr == 0 ) { 593 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc ); 594 } 595 if( incr > 0 ? (upper < lower) : (lower < upper) ) { 596 // The loop is illegal. 597 // Some zero-trip loops maintained by compiler, e.g.: 598 // for(i=10;i<0;++i) // lower >= upper - run-time check 599 // for(i=0;i>10;--i) // lower <= upper - run-time check 600 // for(i=0;i>10;++i) // incr > 0 - compile-time check 601 // for(i=10;i<0;--i) // incr < 0 - compile-time check 602 // Compiler does not check the following illegal loops: 603 // for(i=0;i<10;i+=incr) // where incr<0 604 // for(i=10;i>0;i-=incr) // where incr<0 605 __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc ); 606 } 607 } 608 th = __kmp_threads[gtid]; 609 KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct 610 team = th->th.th_team; 611 #if OMP_40_ENABLED 612 nteams = th->th.th_teams_size.nteams; 613 #endif 614 team_id = team->t.t_master_tid; 615 KMP_DEBUG_ASSERT(nteams == team->t.t_parent->t.t_nproc); 616 617 // compute trip count 618 if( incr == 1 ) { 619 trip_count = upper - lower + 1; 620 } else if(incr == -1) { 621 trip_count = lower - upper + 1; 622 } else { 623 trip_count = (ST)(upper - lower) / incr + 1; // cast to signed to cover incr<0 case 624 } 625 if( chunk < 1 ) 626 chunk = 1; 627 span = chunk * incr; 628 *p_st = span * nteams; 629 *p_lb = lower + (span * team_id); 630 *p_ub = *p_lb + span - incr; 631 if ( p_last != NULL ) 632 *p_last = (team_id == ((trip_count - 1)/(UT)chunk) % nteams); 633 // Correct upper bound if needed 634 if( incr > 0 ) { 635 if( *p_ub < *p_lb ) // overflow? 636 *p_ub = i_maxmin< T >::mx; 637 if( *p_ub > upper ) 638 *p_ub = upper; // tracker C73258 639 } else { // incr < 0 640 if( *p_ub > *p_lb ) 641 *p_ub = i_maxmin< T >::mn; 642 if( *p_ub < upper ) 643 *p_ub = upper; // tracker C73258 644 } 645 #ifdef KMP_DEBUG 646 { 647 const char * buff; 648 // create format specifiers before the debug output 649 buff = __kmp_str_format( "__kmp_team_static_init exit: T#%%d team%%u liter=%%d "\ 650 "iter=(%%%s, %%%s, %%%s) chunk %%%s\n", 651 traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, 652 traits_t< ST >::spec ); 653 KD_TRACE(100, ( buff, gtid, team_id, *p_last, *p_lb, *p_ub, *p_st, chunk ) ); 654 __kmp_str_free( &buff ); 655 } 656 #endif 657 } 658 659 //-------------------------------------------------------------------------------------- 660 extern "C" { 661 662 /*! 663 @ingroup WORK_SHARING 664 @param loc Source code location 665 @param gtid Global thread id of this thread 666 @param schedtype Scheduling type 667 @param plastiter Pointer to the "last iteration" flag 668 @param plower Pointer to the lower bound 669 @param pupper Pointer to the upper bound 670 @param pstride Pointer to the stride 671 @param incr Loop increment 672 @param chunk The chunk size 673 674 Each of the four functions here are identical apart from the argument types. 675 676 The functions compute the upper and lower bounds and stride to be used for the set of iterations 677 to be executed by the current thread from the statically scheduled loop that is described by the 678 initial values of the bounds, stride, increment and chunk size. 679 680 @{ 681 */ 682 void 683 __kmpc_for_static_init_4( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, 684 kmp_int32 *plower, kmp_int32 *pupper, 685 kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk ) 686 { 687 __kmp_for_static_init< kmp_int32 >( 688 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk ); 689 } 690 691 /*! 692 See @ref __kmpc_for_static_init_4 693 */ 694 void 695 __kmpc_for_static_init_4u( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, 696 kmp_uint32 *plower, kmp_uint32 *pupper, 697 kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk ) 698 { 699 __kmp_for_static_init< kmp_uint32 >( 700 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk ); 701 } 702 703 /*! 704 See @ref __kmpc_for_static_init_4 705 */ 706 void 707 __kmpc_for_static_init_8( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, 708 kmp_int64 *plower, kmp_int64 *pupper, 709 kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk ) 710 { 711 __kmp_for_static_init< kmp_int64 >( 712 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk ); 713 } 714 715 /*! 716 See @ref __kmpc_for_static_init_4 717 */ 718 void 719 __kmpc_for_static_init_8u( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, 720 kmp_uint64 *plower, kmp_uint64 *pupper, 721 kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk ) 722 { 723 __kmp_for_static_init< kmp_uint64 >( 724 loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk ); 725 } 726 /*! 727 @} 728 */ 729 730 /*! 731 @ingroup WORK_SHARING 732 @param loc Source code location 733 @param gtid Global thread id of this thread 734 @param scheduleD Scheduling type for the distribute 735 @param scheduleL Scheduling type for the parallel loop 736 @param plastiter Pointer to the "last iteration" flag 737 @param plower Pointer to the lower bound 738 @param pupper Pointer to the upper bound of loop chunk 739 @param pupperD Pointer to the upper bound of dist_chunk 740 @param pstrideD Pointer to the stride for distribute 741 @param pstrideL Pointer to the stride for parallel loop 742 @param incr Loop increment 743 @param chunkD The chunk size for the distribute 744 @param chunkL The chunk size for the parallel loop 745 746 Each of the four functions here are identical apart from the argument types. 747 748 The functions compute the upper and lower bounds and strides to be used for the set of iterations 749 to be executed by the current thread from the statically scheduled loop that is described by the 750 initial values of the bounds, strides, increment and chunks for parallel loop and distribute 751 constructs. 752 753 @{ 754 */ 755 void 756 __kmpc_dist_for_static_init_4( 757 ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, 758 kmp_int32 *plower, kmp_int32 *pupper, kmp_int32 *pupperD, 759 kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk ) 760 { 761 __kmp_dist_for_static_init< kmp_int32 >( 762 loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk ); 763 } 764 765 /*! 766 See @ref __kmpc_dist_for_static_init_4 767 */ 768 void 769 __kmpc_dist_for_static_init_4u( 770 ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, 771 kmp_uint32 *plower, kmp_uint32 *pupper, kmp_uint32 *pupperD, 772 kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk ) 773 { 774 __kmp_dist_for_static_init< kmp_uint32 >( 775 loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk ); 776 } 777 778 /*! 779 See @ref __kmpc_dist_for_static_init_4 780 */ 781 void 782 __kmpc_dist_for_static_init_8( 783 ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, 784 kmp_int64 *plower, kmp_int64 *pupper, kmp_int64 *pupperD, 785 kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk ) 786 { 787 __kmp_dist_for_static_init< kmp_int64 >( 788 loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk ); 789 } 790 791 /*! 792 See @ref __kmpc_dist_for_static_init_4 793 */ 794 void 795 __kmpc_dist_for_static_init_8u( 796 ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, 797 kmp_uint64 *plower, kmp_uint64 *pupper, kmp_uint64 *pupperD, 798 kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk ) 799 { 800 __kmp_dist_for_static_init< kmp_uint64 >( 801 loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk ); 802 } 803 /*! 804 @} 805 */ 806 807 //----------------------------------------------------------------------------------------- 808 // Auxiliary routines for Distribute Parallel Loop construct implementation 809 // Transfer call to template< type T > 810 // __kmp_team_static_init( ident_t *loc, int gtid, 811 // int *p_last, T *lb, T *ub, ST *st, ST incr, ST chunk ) 812 813 /*! 814 @ingroup WORK_SHARING 815 @{ 816 @param loc Source location 817 @param gtid Global thread id 818 @param p_last pointer to last iteration flag 819 @param p_lb pointer to Lower bound 820 @param p_ub pointer to Upper bound 821 @param p_st Step (or increment if you prefer) 822 @param incr Loop increment 823 @param chunk The chunk size to block with 824 825 The functions compute the upper and lower bounds and stride to be used for the set of iterations 826 to be executed by the current team from the statically scheduled loop that is described by the 827 initial values of the bounds, stride, increment and chunk for the distribute construct as part of 828 composite distribute parallel loop construct. 829 These functions are all identical apart from the types of the arguments. 830 */ 831 832 void 833 __kmpc_team_static_init_4( 834 ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 835 kmp_int32 *p_lb, kmp_int32 *p_ub, kmp_int32 *p_st, kmp_int32 incr, kmp_int32 chunk ) 836 { 837 KMP_DEBUG_ASSERT( __kmp_init_serial ); 838 __kmp_team_static_init< kmp_int32 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk ); 839 } 840 841 /*! 842 See @ref __kmpc_team_static_init_4 843 */ 844 void 845 __kmpc_team_static_init_4u( 846 ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 847 kmp_uint32 *p_lb, kmp_uint32 *p_ub, kmp_int32 *p_st, kmp_int32 incr, kmp_int32 chunk ) 848 { 849 KMP_DEBUG_ASSERT( __kmp_init_serial ); 850 __kmp_team_static_init< kmp_uint32 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk ); 851 } 852 853 /*! 854 See @ref __kmpc_team_static_init_4 855 */ 856 void 857 __kmpc_team_static_init_8( 858 ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 859 kmp_int64 *p_lb, kmp_int64 *p_ub, kmp_int64 *p_st, kmp_int64 incr, kmp_int64 chunk ) 860 { 861 KMP_DEBUG_ASSERT( __kmp_init_serial ); 862 __kmp_team_static_init< kmp_int64 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk ); 863 } 864 865 /*! 866 See @ref __kmpc_team_static_init_4 867 */ 868 void 869 __kmpc_team_static_init_8u( 870 ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 871 kmp_uint64 *p_lb, kmp_uint64 *p_ub, kmp_int64 *p_st, kmp_int64 incr, kmp_int64 chunk ) 872 { 873 KMP_DEBUG_ASSERT( __kmp_init_serial ); 874 __kmp_team_static_init< kmp_uint64 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk ); 875 } 876 /*! 877 @} 878 */ 879 880 } // extern "C" 881 882