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