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