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