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