10b57cec5SDimitry Andric /* 20b57cec5SDimitry Andric * kmp_sched.cpp -- static scheduling -- iteration initialization 30b57cec5SDimitry Andric */ 40b57cec5SDimitry Andric 50b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 80b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 90b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric /* Static scheduling initialization. 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric NOTE: team->t.t_nproc is a constant inside of any dispatch loop, however 160b57cec5SDimitry Andric it may change values between parallel regions. __kmp_max_nth 170b57cec5SDimitry Andric is the largest value __kmp_nth may take, 1 is the smallest. */ 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #include "kmp.h" 200b57cec5SDimitry Andric #include "kmp_error.h" 210b57cec5SDimitry Andric #include "kmp_i18n.h" 220b57cec5SDimitry Andric #include "kmp_itt.h" 230b57cec5SDimitry Andric #include "kmp_stats.h" 240b57cec5SDimitry Andric #include "kmp_str.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric #if OMPT_SUPPORT 270b57cec5SDimitry Andric #include "ompt-specific.h" 280b57cec5SDimitry Andric #endif 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric #ifdef KMP_DEBUG 310b57cec5SDimitry Andric //------------------------------------------------------------------------- 320b57cec5SDimitry Andric // template for debug prints specification ( d, u, lld, llu ) 330b57cec5SDimitry Andric char const *traits_t<int>::spec = "d"; 340b57cec5SDimitry Andric char const *traits_t<unsigned int>::spec = "u"; 350b57cec5SDimitry Andric char const *traits_t<long long>::spec = "lld"; 360b57cec5SDimitry Andric char const *traits_t<unsigned long long>::spec = "llu"; 370b57cec5SDimitry Andric char const *traits_t<long>::spec = "ld"; 380b57cec5SDimitry Andric //------------------------------------------------------------------------- 390b57cec5SDimitry Andric #endif 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric #if KMP_STATS_ENABLED 420b57cec5SDimitry Andric #define KMP_STATS_LOOP_END(stat) \ 430b57cec5SDimitry Andric { \ 440b57cec5SDimitry Andric kmp_int64 t; \ 450b57cec5SDimitry Andric kmp_int64 u = (kmp_int64)(*pupper); \ 460b57cec5SDimitry Andric kmp_int64 l = (kmp_int64)(*plower); \ 470b57cec5SDimitry Andric kmp_int64 i = (kmp_int64)incr; \ 480b57cec5SDimitry Andric if (i == 1) { \ 490b57cec5SDimitry Andric t = u - l + 1; \ 500b57cec5SDimitry Andric } else if (i == -1) { \ 510b57cec5SDimitry Andric t = l - u + 1; \ 520b57cec5SDimitry Andric } else if (i > 0) { \ 530b57cec5SDimitry Andric t = (u - l) / i + 1; \ 540b57cec5SDimitry Andric } else { \ 550b57cec5SDimitry Andric t = (l - u) / (-i) + 1; \ 560b57cec5SDimitry Andric } \ 570b57cec5SDimitry Andric KMP_COUNT_VALUE(stat, t); \ 580b57cec5SDimitry Andric KMP_POP_PARTITIONED_TIMER(); \ 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric #else 610b57cec5SDimitry Andric #define KMP_STATS_LOOP_END(stat) /* Nothing */ 620b57cec5SDimitry Andric #endif 630b57cec5SDimitry Andric 64*06c3fb27SDimitry Andric #if USE_ITT_BUILD || defined KMP_DEBUG 65e8d8bef9SDimitry Andric static ident_t loc_stub = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;"}; 66e8d8bef9SDimitry Andric static inline void check_loc(ident_t *&loc) { 67e8d8bef9SDimitry Andric if (loc == NULL) 68e8d8bef9SDimitry Andric loc = &loc_stub; // may need to report location info to ittnotify 69e8d8bef9SDimitry Andric } 70*06c3fb27SDimitry Andric #endif 71e8d8bef9SDimitry Andric 720b57cec5SDimitry Andric template <typename T> 730b57cec5SDimitry Andric static void __kmp_for_static_init(ident_t *loc, kmp_int32 global_tid, 740b57cec5SDimitry Andric kmp_int32 schedtype, kmp_int32 *plastiter, 750b57cec5SDimitry Andric T *plower, T *pupper, 760b57cec5SDimitry Andric typename traits_t<T>::signed_t *pstride, 770b57cec5SDimitry Andric typename traits_t<T>::signed_t incr, 780b57cec5SDimitry Andric typename traits_t<T>::signed_t chunk 790b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 800b57cec5SDimitry Andric , 810b57cec5SDimitry Andric void *codeptr 820b57cec5SDimitry Andric #endif 830b57cec5SDimitry Andric ) { 840b57cec5SDimitry Andric KMP_COUNT_BLOCK(OMP_LOOP_STATIC); 850b57cec5SDimitry Andric KMP_PUSH_PARTITIONED_TIMER(OMP_loop_static); 860b57cec5SDimitry Andric KMP_PUSH_PARTITIONED_TIMER(OMP_loop_static_scheduling); 870b57cec5SDimitry Andric 88bdd1243dSDimitry Andric // Clear monotonic/nonmonotonic bits (ignore it) 89bdd1243dSDimitry Andric schedtype = SCHEDULE_WITHOUT_MODIFIERS(schedtype); 90bdd1243dSDimitry Andric 910b57cec5SDimitry Andric typedef typename traits_t<T>::unsigned_t UT; 920b57cec5SDimitry Andric typedef typename traits_t<T>::signed_t ST; 930b57cec5SDimitry Andric /* this all has to be changed back to TID and such.. */ 940b57cec5SDimitry Andric kmp_int32 gtid = global_tid; 950b57cec5SDimitry Andric kmp_uint32 tid; 960b57cec5SDimitry Andric kmp_uint32 nth; 970b57cec5SDimitry Andric UT trip_count; 980b57cec5SDimitry Andric kmp_team_t *team; 99e8d8bef9SDimitry Andric __kmp_assert_valid_gtid(gtid); 1000b57cec5SDimitry Andric kmp_info_t *th = __kmp_threads[gtid]; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1030b57cec5SDimitry Andric ompt_team_info_t *team_info = NULL; 1040b57cec5SDimitry Andric ompt_task_info_t *task_info = NULL; 1050b57cec5SDimitry Andric ompt_work_t ompt_work_type = ompt_work_loop; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric static kmp_int8 warn = 0; 1080b57cec5SDimitry Andric 10981ad6265SDimitry Andric if (ompt_enabled.ompt_callback_work || ompt_enabled.ompt_callback_dispatch) { 1100b57cec5SDimitry Andric // Only fully initialize variables needed by OMPT if OMPT is enabled. 1110b57cec5SDimitry Andric team_info = __ompt_get_teaminfo(0, NULL); 1120b57cec5SDimitry Andric task_info = __ompt_get_task_info_object(0); 1130b57cec5SDimitry Andric // Determine workshare type 1140b57cec5SDimitry Andric if (loc != NULL) { 1150b57cec5SDimitry Andric if ((loc->flags & KMP_IDENT_WORK_LOOP) != 0) { 1160b57cec5SDimitry Andric ompt_work_type = ompt_work_loop; 1170b57cec5SDimitry Andric } else if ((loc->flags & KMP_IDENT_WORK_SECTIONS) != 0) { 1180b57cec5SDimitry Andric ompt_work_type = ompt_work_sections; 1190b57cec5SDimitry Andric } else if ((loc->flags & KMP_IDENT_WORK_DISTRIBUTE) != 0) { 1200b57cec5SDimitry Andric ompt_work_type = ompt_work_distribute; 1210b57cec5SDimitry Andric } else { 1220b57cec5SDimitry Andric kmp_int8 bool_res = 1230b57cec5SDimitry Andric KMP_COMPARE_AND_STORE_ACQ8(&warn, (kmp_int8)0, (kmp_int8)1); 1240b57cec5SDimitry Andric if (bool_res) 1250b57cec5SDimitry Andric KMP_WARNING(OmptOutdatedWorkshare); 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric KMP_DEBUG_ASSERT(ompt_work_type); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric #endif 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric KMP_DEBUG_ASSERT(plastiter && plower && pupper && pstride); 1330b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_for_static_init called (%d)\n", global_tid)); 1340b57cec5SDimitry Andric #ifdef KMP_DEBUG 1350b57cec5SDimitry Andric { 1360b57cec5SDimitry Andric char *buff; 1370b57cec5SDimitry Andric // create format specifiers before the debug output 1380b57cec5SDimitry Andric buff = __kmp_str_format( 1390b57cec5SDimitry Andric "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," 1400b57cec5SDimitry Andric " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n", 1410b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec, 1420b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<ST>::spec, traits_t<T>::spec); 1430b57cec5SDimitry Andric KD_TRACE(100, (buff, global_tid, schedtype, *plastiter, *plower, *pupper, 1440b57cec5SDimitry Andric *pstride, incr, chunk)); 1450b57cec5SDimitry Andric __kmp_str_free(&buff); 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric #endif 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric if (__kmp_env_consistency_check) { 1500b57cec5SDimitry Andric __kmp_push_workshare(global_tid, ct_pdo, loc); 1510b57cec5SDimitry Andric if (incr == 0) { 1520b57cec5SDimitry Andric __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, 1530b57cec5SDimitry Andric loc); 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric /* special handling for zero-trip loops */ 1570b57cec5SDimitry Andric if (incr > 0 ? (*pupper < *plower) : (*plower < *pupper)) { 1580b57cec5SDimitry Andric if (plastiter != NULL) 1590b57cec5SDimitry Andric *plastiter = FALSE; 1600b57cec5SDimitry Andric /* leave pupper and plower set to entire iteration space */ 1610b57cec5SDimitry Andric *pstride = incr; /* value should never be used */ 1620b57cec5SDimitry Andric // *plower = *pupper - incr; 1630b57cec5SDimitry Andric // let compiler bypass the illegal loop (like for(i=1;i<10;i--)) 1640b57cec5SDimitry Andric // THE LINE COMMENTED ABOVE CAUSED shape2F/h_tests_1.f TO HAVE A FAILURE 1650b57cec5SDimitry Andric // ON A ZERO-TRIP LOOP (lower=1, upper=0,stride=1) - JPH June 23, 2009. 1660b57cec5SDimitry Andric #ifdef KMP_DEBUG 1670b57cec5SDimitry Andric { 1680b57cec5SDimitry Andric char *buff; 1690b57cec5SDimitry Andric // create format specifiers before the debug output 1700b57cec5SDimitry Andric buff = __kmp_str_format("__kmpc_for_static_init:(ZERO TRIP) liter=%%d " 1710b57cec5SDimitry Andric "lower=%%%s upper=%%%s stride = %%%s " 1720b57cec5SDimitry Andric "signed?<%s>, loc = %%s\n", 1730b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, 1740b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<T>::spec); 175fe6060f1SDimitry Andric check_loc(loc); 1760b57cec5SDimitry Andric KD_TRACE(100, 1770b57cec5SDimitry Andric (buff, *plastiter, *plower, *pupper, *pstride, loc->psource)); 1780b57cec5SDimitry Andric __kmp_str_free(&buff); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric #endif 1810b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1840b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_work) { 1850b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 1860b57cec5SDimitry Andric ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), 1870b57cec5SDimitry Andric &(task_info->task_data), 0, codeptr); 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric #endif 1900b57cec5SDimitry Andric KMP_STATS_LOOP_END(OMP_loop_static_iterations); 1910b57cec5SDimitry Andric return; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric // Although there are schedule enumerations above kmp_ord_upper which are not 1950b57cec5SDimitry Andric // schedules for "distribute", the only ones which are useful are dynamic, so 1960b57cec5SDimitry Andric // cannot be seen here, since this codepath is only executed for static 1970b57cec5SDimitry Andric // schedules. 1980b57cec5SDimitry Andric if (schedtype > kmp_ord_upper) { 1990b57cec5SDimitry Andric // we are in DISTRIBUTE construct 2000b57cec5SDimitry Andric schedtype += kmp_sch_static - 2010b57cec5SDimitry Andric kmp_distribute_static; // AC: convert to usual schedule type 20281ad6265SDimitry Andric if (th->th.th_team->t.t_serialized > 1) { 20381ad6265SDimitry Andric tid = 0; 20481ad6265SDimitry Andric team = th->th.th_team; 20581ad6265SDimitry Andric } else { 2060b57cec5SDimitry Andric tid = th->th.th_team->t.t_master_tid; 2070b57cec5SDimitry Andric team = th->th.th_team->t.t_parent; 20881ad6265SDimitry Andric } 2090b57cec5SDimitry Andric } else { 2100b57cec5SDimitry Andric tid = __kmp_tid_from_gtid(global_tid); 2110b57cec5SDimitry Andric team = th->th.th_team; 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric /* determine if "for" loop is an active worksharing construct */ 2150b57cec5SDimitry Andric if (team->t.t_serialized) { 2160b57cec5SDimitry Andric /* serialized parallel, each thread executes whole iteration space */ 2170b57cec5SDimitry Andric if (plastiter != NULL) 2180b57cec5SDimitry Andric *plastiter = TRUE; 2190b57cec5SDimitry Andric /* leave pupper and plower set to entire iteration space */ 2200b57cec5SDimitry Andric *pstride = 2210b57cec5SDimitry Andric (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric #ifdef KMP_DEBUG 2240b57cec5SDimitry Andric { 2250b57cec5SDimitry Andric char *buff; 2260b57cec5SDimitry Andric // create format specifiers before the debug output 2270b57cec5SDimitry Andric buff = __kmp_str_format("__kmpc_for_static_init: (serial) liter=%%d " 2280b57cec5SDimitry Andric "lower=%%%s upper=%%%s stride = %%%s\n", 2290b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, 2300b57cec5SDimitry Andric traits_t<ST>::spec); 2310b57cec5SDimitry Andric KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride)); 2320b57cec5SDimitry Andric __kmp_str_free(&buff); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric #endif 2350b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2380b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_work) { 2390b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 2400b57cec5SDimitry Andric ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), 2410b57cec5SDimitry Andric &(task_info->task_data), *pstride, codeptr); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric #endif 2440b57cec5SDimitry Andric KMP_STATS_LOOP_END(OMP_loop_static_iterations); 2450b57cec5SDimitry Andric return; 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric nth = team->t.t_nproc; 2480b57cec5SDimitry Andric if (nth == 1) { 2490b57cec5SDimitry Andric if (plastiter != NULL) 2500b57cec5SDimitry Andric *plastiter = TRUE; 2510b57cec5SDimitry Andric *pstride = 2520b57cec5SDimitry Andric (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1)); 2530b57cec5SDimitry Andric #ifdef KMP_DEBUG 2540b57cec5SDimitry Andric { 2550b57cec5SDimitry Andric char *buff; 2560b57cec5SDimitry Andric // create format specifiers before the debug output 2570b57cec5SDimitry Andric buff = __kmp_str_format("__kmpc_for_static_init: (serial) liter=%%d " 2580b57cec5SDimitry Andric "lower=%%%s upper=%%%s stride = %%%s\n", 2590b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, 2600b57cec5SDimitry Andric traits_t<ST>::spec); 2610b57cec5SDimitry Andric KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride)); 2620b57cec5SDimitry Andric __kmp_str_free(&buff); 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric #endif 2650b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2680b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_work) { 2690b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 2700b57cec5SDimitry Andric ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), 2710b57cec5SDimitry Andric &(task_info->task_data), *pstride, codeptr); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric #endif 2740b57cec5SDimitry Andric KMP_STATS_LOOP_END(OMP_loop_static_iterations); 2750b57cec5SDimitry Andric return; 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric /* compute trip count */ 2790b57cec5SDimitry Andric if (incr == 1) { 2800b57cec5SDimitry Andric trip_count = *pupper - *plower + 1; 2810b57cec5SDimitry Andric } else if (incr == -1) { 2820b57cec5SDimitry Andric trip_count = *plower - *pupper + 1; 2830b57cec5SDimitry Andric } else if (incr > 0) { 2840b57cec5SDimitry Andric // upper-lower can exceed the limit of signed type 2850b57cec5SDimitry Andric trip_count = (UT)(*pupper - *plower) / incr + 1; 2860b57cec5SDimitry Andric } else { 2870b57cec5SDimitry Andric trip_count = (UT)(*plower - *pupper) / (-incr) + 1; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric #if KMP_STATS_ENABLED 2910b57cec5SDimitry Andric if (KMP_MASTER_GTID(gtid)) { 2920b57cec5SDimitry Andric KMP_COUNT_VALUE(OMP_loop_static_total_iterations, trip_count); 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric #endif 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric if (__kmp_env_consistency_check) { 2970b57cec5SDimitry Andric /* tripcount overflow? */ 2980b57cec5SDimitry Andric if (trip_count == 0 && *pupper != *plower) { 2990b57cec5SDimitry Andric __kmp_error_construct(kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo, 3000b57cec5SDimitry Andric loc); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric /* compute remaining parameters */ 3050b57cec5SDimitry Andric switch (schedtype) { 3060b57cec5SDimitry Andric case kmp_sch_static: { 3070b57cec5SDimitry Andric if (trip_count < nth) { 3080b57cec5SDimitry Andric KMP_DEBUG_ASSERT( 3090b57cec5SDimitry Andric __kmp_static == kmp_sch_static_greedy || 3100b57cec5SDimitry Andric __kmp_static == 3110b57cec5SDimitry Andric kmp_sch_static_balanced); // Unknown static scheduling type. 3120b57cec5SDimitry Andric if (tid < trip_count) { 3130b57cec5SDimitry Andric *pupper = *plower = *plower + tid * incr; 3140b57cec5SDimitry Andric } else { 315fe6060f1SDimitry Andric // set bounds so non-active threads execute no iterations 316fe6060f1SDimitry Andric *plower = *pupper + (incr > 0 ? 1 : -1); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric if (plastiter != NULL) 3190b57cec5SDimitry Andric *plastiter = (tid == trip_count - 1); 3200b57cec5SDimitry Andric } else { 3210b57cec5SDimitry Andric if (__kmp_static == kmp_sch_static_balanced) { 3220b57cec5SDimitry Andric UT small_chunk = trip_count / nth; 3230b57cec5SDimitry Andric UT extras = trip_count % nth; 3240b57cec5SDimitry Andric *plower += incr * (tid * small_chunk + (tid < extras ? tid : extras)); 3250b57cec5SDimitry Andric *pupper = *plower + small_chunk * incr - (tid < extras ? 0 : incr); 3260b57cec5SDimitry Andric if (plastiter != NULL) 3270b57cec5SDimitry Andric *plastiter = (tid == nth - 1); 3280b57cec5SDimitry Andric } else { 3290b57cec5SDimitry Andric T big_chunk_inc_count = 3300b57cec5SDimitry Andric (trip_count / nth + ((trip_count % nth) ? 1 : 0)) * incr; 3310b57cec5SDimitry Andric T old_upper = *pupper; 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy); 3340b57cec5SDimitry Andric // Unknown static scheduling type. 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric *plower += tid * big_chunk_inc_count; 3370b57cec5SDimitry Andric *pupper = *plower + big_chunk_inc_count - incr; 3380b57cec5SDimitry Andric if (incr > 0) { 3390b57cec5SDimitry Andric if (*pupper < *plower) 3400b57cec5SDimitry Andric *pupper = traits_t<T>::max_value; 3410b57cec5SDimitry Andric if (plastiter != NULL) 3420b57cec5SDimitry Andric *plastiter = *plower <= old_upper && *pupper > old_upper - incr; 3430b57cec5SDimitry Andric if (*pupper > old_upper) 3440b57cec5SDimitry Andric *pupper = old_upper; // tracker C73258 3450b57cec5SDimitry Andric } else { 3460b57cec5SDimitry Andric if (*pupper > *plower) 3470b57cec5SDimitry Andric *pupper = traits_t<T>::min_value; 3480b57cec5SDimitry Andric if (plastiter != NULL) 3490b57cec5SDimitry Andric *plastiter = *plower >= old_upper && *pupper < old_upper - incr; 3500b57cec5SDimitry Andric if (*pupper < old_upper) 3510b57cec5SDimitry Andric *pupper = old_upper; // tracker C73258 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric *pstride = trip_count; 3560b57cec5SDimitry Andric break; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric case kmp_sch_static_chunked: { 3590b57cec5SDimitry Andric ST span; 360fe6060f1SDimitry Andric UT nchunks; 361fe6060f1SDimitry Andric if (chunk < 1) 3620b57cec5SDimitry Andric chunk = 1; 363fe6060f1SDimitry Andric else if ((UT)chunk > trip_count) 364fe6060f1SDimitry Andric chunk = trip_count; 365fe6060f1SDimitry Andric nchunks = (trip_count) / (UT)chunk + (trip_count % (UT)chunk ? 1 : 0); 3660b57cec5SDimitry Andric span = chunk * incr; 367fe6060f1SDimitry Andric if (nchunks < nth) { 368fe6060f1SDimitry Andric *pstride = span * nchunks; 369fe6060f1SDimitry Andric if (tid < nchunks) { 370fe6060f1SDimitry Andric *plower = *plower + (span * tid); 371fe6060f1SDimitry Andric *pupper = *plower + span - incr; 372fe6060f1SDimitry Andric } else { 373fe6060f1SDimitry Andric *plower = *pupper + (incr > 0 ? 1 : -1); 374fe6060f1SDimitry Andric } 375fe6060f1SDimitry Andric } else { 3760b57cec5SDimitry Andric *pstride = span * nth; 3770b57cec5SDimitry Andric *plower = *plower + (span * tid); 3780b57cec5SDimitry Andric *pupper = *plower + span - incr; 379fe6060f1SDimitry Andric } 3800b57cec5SDimitry Andric if (plastiter != NULL) 381fe6060f1SDimitry Andric *plastiter = (tid == (nchunks - 1) % nth); 3820b57cec5SDimitry Andric break; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric case kmp_sch_static_balanced_chunked: { 3850b57cec5SDimitry Andric T old_upper = *pupper; 3860b57cec5SDimitry Andric // round up to make sure the chunk is enough to cover all iterations 3870b57cec5SDimitry Andric UT span = (trip_count + nth - 1) / nth; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric // perform chunk adjustment 3900b57cec5SDimitry Andric chunk = (span + chunk - 1) & ~(chunk - 1); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric span = chunk * incr; 3930b57cec5SDimitry Andric *plower = *plower + (span * tid); 3940b57cec5SDimitry Andric *pupper = *plower + span - incr; 3950b57cec5SDimitry Andric if (incr > 0) { 3960b57cec5SDimitry Andric if (*pupper > old_upper) 3970b57cec5SDimitry Andric *pupper = old_upper; 3980b57cec5SDimitry Andric } else if (*pupper < old_upper) 3990b57cec5SDimitry Andric *pupper = old_upper; 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric if (plastiter != NULL) 4020b57cec5SDimitry Andric *plastiter = (tid == ((trip_count - 1) / (UT)chunk)); 4030b57cec5SDimitry Andric break; 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric default: 4060b57cec5SDimitry Andric KMP_ASSERT2(0, "__kmpc_for_static_init: unknown scheduling type"); 4070b57cec5SDimitry Andric break; 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric #if USE_ITT_BUILD 4110b57cec5SDimitry Andric // Report loop metadata 4120b57cec5SDimitry Andric if (KMP_MASTER_TID(tid) && __itt_metadata_add_ptr && 4130b57cec5SDimitry Andric __kmp_forkjoin_frames_mode == 3 && th->th.th_teams_microtask == NULL && 4140b57cec5SDimitry Andric team->t.t_active_level == 1) { 4150b57cec5SDimitry Andric kmp_uint64 cur_chunk = chunk; 416e8d8bef9SDimitry Andric check_loc(loc); 4170b57cec5SDimitry Andric // Calculate chunk in case it was not specified; it is specified for 4180b57cec5SDimitry Andric // kmp_sch_static_chunked 4190b57cec5SDimitry Andric if (schedtype == kmp_sch_static) { 4200b57cec5SDimitry Andric cur_chunk = trip_count / nth + ((trip_count % nth) ? 1 : 0); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric // 0 - "static" schedule 4230b57cec5SDimitry Andric __kmp_itt_metadata_loop(loc, 0, trip_count, cur_chunk); 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric #endif 4260b57cec5SDimitry Andric #ifdef KMP_DEBUG 4270b57cec5SDimitry Andric { 4280b57cec5SDimitry Andric char *buff; 4290b57cec5SDimitry Andric // create format specifiers before the debug output 4300b57cec5SDimitry Andric buff = __kmp_str_format("__kmpc_for_static_init: liter=%%d lower=%%%s " 4310b57cec5SDimitry Andric "upper=%%%s stride = %%%s signed?<%s>\n", 4320b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, 4330b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<T>::spec); 4340b57cec5SDimitry Andric KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride)); 4350b57cec5SDimitry Andric __kmp_str_free(&buff); 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric #endif 4380b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid)); 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 4410b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_work) { 4420b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 4430b57cec5SDimitry Andric ompt_work_type, ompt_scope_begin, &(team_info->parallel_data), 4440b57cec5SDimitry Andric &(task_info->task_data), trip_count, codeptr); 4450b57cec5SDimitry Andric } 44681ad6265SDimitry Andric if (ompt_enabled.ompt_callback_dispatch) { 44781ad6265SDimitry Andric ompt_dispatch_t dispatch_type; 44881ad6265SDimitry Andric ompt_data_t instance = ompt_data_none; 44981ad6265SDimitry Andric ompt_dispatch_chunk_t dispatch_chunk; 45081ad6265SDimitry Andric if (ompt_work_type == ompt_work_sections) { 45181ad6265SDimitry Andric dispatch_type = ompt_dispatch_section; 45281ad6265SDimitry Andric instance.ptr = codeptr; 45381ad6265SDimitry Andric } else { 45481ad6265SDimitry Andric OMPT_GET_DISPATCH_CHUNK(dispatch_chunk, *plower, *pupper, incr); 45581ad6265SDimitry Andric dispatch_type = (ompt_work_type == ompt_work_distribute) 45681ad6265SDimitry Andric ? ompt_dispatch_distribute_chunk 45781ad6265SDimitry Andric : ompt_dispatch_ws_loop_chunk; 45881ad6265SDimitry Andric instance.ptr = &dispatch_chunk; 45981ad6265SDimitry Andric } 46081ad6265SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_dispatch)( 46181ad6265SDimitry Andric &(team_info->parallel_data), &(task_info->task_data), dispatch_type, 46281ad6265SDimitry Andric instance); 46381ad6265SDimitry Andric } 4640b57cec5SDimitry Andric #endif 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric KMP_STATS_LOOP_END(OMP_loop_static_iterations); 4670b57cec5SDimitry Andric return; 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric template <typename T> 4710b57cec5SDimitry Andric static void __kmp_dist_for_static_init(ident_t *loc, kmp_int32 gtid, 4720b57cec5SDimitry Andric kmp_int32 schedule, kmp_int32 *plastiter, 4730b57cec5SDimitry Andric T *plower, T *pupper, T *pupperDist, 4740b57cec5SDimitry Andric typename traits_t<T>::signed_t *pstride, 4750b57cec5SDimitry Andric typename traits_t<T>::signed_t incr, 47681ad6265SDimitry Andric typename traits_t<T>::signed_t chunk 47781ad6265SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 47881ad6265SDimitry Andric , 47981ad6265SDimitry Andric void *codeptr 48081ad6265SDimitry Andric #endif 48181ad6265SDimitry Andric ) { 4820b57cec5SDimitry Andric KMP_COUNT_BLOCK(OMP_DISTRIBUTE); 4830b57cec5SDimitry Andric KMP_PUSH_PARTITIONED_TIMER(OMP_distribute); 4840b57cec5SDimitry Andric KMP_PUSH_PARTITIONED_TIMER(OMP_distribute_scheduling); 4850b57cec5SDimitry Andric typedef typename traits_t<T>::unsigned_t UT; 4860b57cec5SDimitry Andric typedef typename traits_t<T>::signed_t ST; 4870b57cec5SDimitry Andric kmp_uint32 tid; 4880b57cec5SDimitry Andric kmp_uint32 nth; 4890b57cec5SDimitry Andric kmp_uint32 team_id; 4900b57cec5SDimitry Andric kmp_uint32 nteams; 4910b57cec5SDimitry Andric UT trip_count; 4920b57cec5SDimitry Andric kmp_team_t *team; 4930b57cec5SDimitry Andric kmp_info_t *th; 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric KMP_DEBUG_ASSERT(plastiter && plower && pupper && pupperDist && pstride); 4960b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_dist_for_static_init called (%d)\n", gtid)); 497e8d8bef9SDimitry Andric __kmp_assert_valid_gtid(gtid); 4980b57cec5SDimitry Andric #ifdef KMP_DEBUG 4990b57cec5SDimitry Andric { 5000b57cec5SDimitry Andric char *buff; 5010b57cec5SDimitry Andric // create format specifiers before the debug output 5020b57cec5SDimitry Andric buff = __kmp_str_format( 5030b57cec5SDimitry Andric "__kmpc_dist_for_static_init: T#%%d schedLoop=%%d liter=%%d " 5040b57cec5SDimitry Andric "iter=(%%%s, %%%s, %%%s) chunk=%%%s signed?<%s>\n", 5050b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec, 5060b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<T>::spec); 5070b57cec5SDimitry Andric KD_TRACE(100, 5080b57cec5SDimitry Andric (buff, gtid, schedule, *plastiter, *plower, *pupper, incr, chunk)); 5090b57cec5SDimitry Andric __kmp_str_free(&buff); 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric #endif 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric if (__kmp_env_consistency_check) { 5140b57cec5SDimitry Andric __kmp_push_workshare(gtid, ct_pdo, loc); 5150b57cec5SDimitry Andric if (incr == 0) { 5160b57cec5SDimitry Andric __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, 5170b57cec5SDimitry Andric loc); 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric if (incr > 0 ? (*pupper < *plower) : (*plower < *pupper)) { 5200b57cec5SDimitry Andric // The loop is illegal. 5210b57cec5SDimitry Andric // Some zero-trip loops maintained by compiler, e.g.: 5220b57cec5SDimitry Andric // for(i=10;i<0;++i) // lower >= upper - run-time check 5230b57cec5SDimitry Andric // for(i=0;i>10;--i) // lower <= upper - run-time check 5240b57cec5SDimitry Andric // for(i=0;i>10;++i) // incr > 0 - compile-time check 5250b57cec5SDimitry Andric // for(i=10;i<0;--i) // incr < 0 - compile-time check 5260b57cec5SDimitry Andric // Compiler does not check the following illegal loops: 5270b57cec5SDimitry Andric // for(i=0;i<10;i+=incr) // where incr<0 5280b57cec5SDimitry Andric // for(i=10;i>0;i-=incr) // where incr<0 5290b57cec5SDimitry Andric __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc); 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric tid = __kmp_tid_from_gtid(gtid); 5330b57cec5SDimitry Andric th = __kmp_threads[gtid]; 5340b57cec5SDimitry Andric nth = th->th.th_team_nproc; 5350b57cec5SDimitry Andric team = th->th.th_team; 5360b57cec5SDimitry Andric KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct 5370b57cec5SDimitry Andric nteams = th->th.th_teams_size.nteams; 5380b57cec5SDimitry Andric team_id = team->t.t_master_tid; 5390b57cec5SDimitry Andric KMP_DEBUG_ASSERT(nteams == (kmp_uint32)team->t.t_parent->t.t_nproc); 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric // compute global trip count 5420b57cec5SDimitry Andric if (incr == 1) { 5430b57cec5SDimitry Andric trip_count = *pupper - *plower + 1; 5440b57cec5SDimitry Andric } else if (incr == -1) { 5450b57cec5SDimitry Andric trip_count = *plower - *pupper + 1; 5460b57cec5SDimitry Andric } else if (incr > 0) { 5470b57cec5SDimitry Andric // upper-lower can exceed the limit of signed type 5480b57cec5SDimitry Andric trip_count = (UT)(*pupper - *plower) / incr + 1; 5490b57cec5SDimitry Andric } else { 5500b57cec5SDimitry Andric trip_count = (UT)(*plower - *pupper) / (-incr) + 1; 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric *pstride = *pupper - *plower; // just in case (can be unused) 5540b57cec5SDimitry Andric if (trip_count <= nteams) { 5550b57cec5SDimitry Andric KMP_DEBUG_ASSERT( 5560b57cec5SDimitry Andric __kmp_static == kmp_sch_static_greedy || 5570b57cec5SDimitry Andric __kmp_static == 5580b57cec5SDimitry Andric kmp_sch_static_balanced); // Unknown static scheduling type. 559fe6060f1SDimitry Andric // only primary threads of some teams get single iteration, other threads 560fe6060f1SDimitry Andric // get nothing 5610b57cec5SDimitry Andric if (team_id < trip_count && tid == 0) { 5620b57cec5SDimitry Andric *pupper = *pupperDist = *plower = *plower + team_id * incr; 5630b57cec5SDimitry Andric } else { 5640b57cec5SDimitry Andric *pupperDist = *pupper; 5650b57cec5SDimitry Andric *plower = *pupper + incr; // compiler should skip loop body 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric if (plastiter != NULL) 5680b57cec5SDimitry Andric *plastiter = (tid == 0 && team_id == trip_count - 1); 5690b57cec5SDimitry Andric } else { 5700b57cec5SDimitry Andric // Get the team's chunk first (each team gets at most one chunk) 5710b57cec5SDimitry Andric if (__kmp_static == kmp_sch_static_balanced) { 5720b57cec5SDimitry Andric UT chunkD = trip_count / nteams; 5730b57cec5SDimitry Andric UT extras = trip_count % nteams; 5740b57cec5SDimitry Andric *plower += 5750b57cec5SDimitry Andric incr * (team_id * chunkD + (team_id < extras ? team_id : extras)); 5760b57cec5SDimitry Andric *pupperDist = *plower + chunkD * incr - (team_id < extras ? 0 : incr); 5770b57cec5SDimitry Andric if (plastiter != NULL) 5780b57cec5SDimitry Andric *plastiter = (team_id == nteams - 1); 5790b57cec5SDimitry Andric } else { 5800b57cec5SDimitry Andric T chunk_inc_count = 5810b57cec5SDimitry Andric (trip_count / nteams + ((trip_count % nteams) ? 1 : 0)) * incr; 5820b57cec5SDimitry Andric T upper = *pupper; 5830b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy); 5840b57cec5SDimitry Andric // Unknown static scheduling type. 5850b57cec5SDimitry Andric *plower += team_id * chunk_inc_count; 5860b57cec5SDimitry Andric *pupperDist = *plower + chunk_inc_count - incr; 5870b57cec5SDimitry Andric // Check/correct bounds if needed 5880b57cec5SDimitry Andric if (incr > 0) { 5890b57cec5SDimitry Andric if (*pupperDist < *plower) 5900b57cec5SDimitry Andric *pupperDist = traits_t<T>::max_value; 5910b57cec5SDimitry Andric if (plastiter != NULL) 5920b57cec5SDimitry Andric *plastiter = *plower <= upper && *pupperDist > upper - incr; 5930b57cec5SDimitry Andric if (*pupperDist > upper) 5940b57cec5SDimitry Andric *pupperDist = upper; // tracker C73258 5950b57cec5SDimitry Andric if (*plower > *pupperDist) { 5960b57cec5SDimitry Andric *pupper = *pupperDist; // no iterations available for the team 5970b57cec5SDimitry Andric goto end; 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric } else { 6000b57cec5SDimitry Andric if (*pupperDist > *plower) 6010b57cec5SDimitry Andric *pupperDist = traits_t<T>::min_value; 6020b57cec5SDimitry Andric if (plastiter != NULL) 6030b57cec5SDimitry Andric *plastiter = *plower >= upper && *pupperDist < upper - incr; 6040b57cec5SDimitry Andric if (*pupperDist < upper) 6050b57cec5SDimitry Andric *pupperDist = upper; // tracker C73258 6060b57cec5SDimitry Andric if (*plower < *pupperDist) { 6070b57cec5SDimitry Andric *pupper = *pupperDist; // no iterations available for the team 6080b57cec5SDimitry Andric goto end; 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric // Get the parallel loop chunk now (for thread) 6130b57cec5SDimitry Andric // compute trip count for team's chunk 6140b57cec5SDimitry Andric if (incr == 1) { 6150b57cec5SDimitry Andric trip_count = *pupperDist - *plower + 1; 6160b57cec5SDimitry Andric } else if (incr == -1) { 6170b57cec5SDimitry Andric trip_count = *plower - *pupperDist + 1; 6180b57cec5SDimitry Andric } else if (incr > 1) { 6190b57cec5SDimitry Andric // upper-lower can exceed the limit of signed type 6200b57cec5SDimitry Andric trip_count = (UT)(*pupperDist - *plower) / incr + 1; 6210b57cec5SDimitry Andric } else { 6220b57cec5SDimitry Andric trip_count = (UT)(*plower - *pupperDist) / (-incr) + 1; 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric KMP_DEBUG_ASSERT(trip_count); 6250b57cec5SDimitry Andric switch (schedule) { 6260b57cec5SDimitry Andric case kmp_sch_static: { 6270b57cec5SDimitry Andric if (trip_count <= nth) { 6280b57cec5SDimitry Andric KMP_DEBUG_ASSERT( 6290b57cec5SDimitry Andric __kmp_static == kmp_sch_static_greedy || 6300b57cec5SDimitry Andric __kmp_static == 6310b57cec5SDimitry Andric kmp_sch_static_balanced); // Unknown static scheduling type. 6320b57cec5SDimitry Andric if (tid < trip_count) 6330b57cec5SDimitry Andric *pupper = *plower = *plower + tid * incr; 6340b57cec5SDimitry Andric else 6350b57cec5SDimitry Andric *plower = *pupper + incr; // no iterations available 6360b57cec5SDimitry Andric if (plastiter != NULL) 6370b57cec5SDimitry Andric if (*plastiter != 0 && !(tid == trip_count - 1)) 6380b57cec5SDimitry Andric *plastiter = 0; 6390b57cec5SDimitry Andric } else { 6400b57cec5SDimitry Andric if (__kmp_static == kmp_sch_static_balanced) { 6410b57cec5SDimitry Andric UT chunkL = trip_count / nth; 6420b57cec5SDimitry Andric UT extras = trip_count % nth; 6430b57cec5SDimitry Andric *plower += incr * (tid * chunkL + (tid < extras ? tid : extras)); 6440b57cec5SDimitry Andric *pupper = *plower + chunkL * incr - (tid < extras ? 0 : incr); 6450b57cec5SDimitry Andric if (plastiter != NULL) 6460b57cec5SDimitry Andric if (*plastiter != 0 && !(tid == nth - 1)) 6470b57cec5SDimitry Andric *plastiter = 0; 6480b57cec5SDimitry Andric } else { 6490b57cec5SDimitry Andric T chunk_inc_count = 6500b57cec5SDimitry Andric (trip_count / nth + ((trip_count % nth) ? 1 : 0)) * incr; 6510b57cec5SDimitry Andric T upper = *pupperDist; 6520b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy); 6530b57cec5SDimitry Andric // Unknown static scheduling type. 6540b57cec5SDimitry Andric *plower += tid * chunk_inc_count; 6550b57cec5SDimitry Andric *pupper = *plower + chunk_inc_count - incr; 6560b57cec5SDimitry Andric if (incr > 0) { 6570b57cec5SDimitry Andric if (*pupper < *plower) 6580b57cec5SDimitry Andric *pupper = traits_t<T>::max_value; 6590b57cec5SDimitry Andric if (plastiter != NULL) 6600b57cec5SDimitry Andric if (*plastiter != 0 && 6610b57cec5SDimitry Andric !(*plower <= upper && *pupper > upper - incr)) 6620b57cec5SDimitry Andric *plastiter = 0; 6630b57cec5SDimitry Andric if (*pupper > upper) 6640b57cec5SDimitry Andric *pupper = upper; // tracker C73258 6650b57cec5SDimitry Andric } else { 6660b57cec5SDimitry Andric if (*pupper > *plower) 6670b57cec5SDimitry Andric *pupper = traits_t<T>::min_value; 6680b57cec5SDimitry Andric if (plastiter != NULL) 6690b57cec5SDimitry Andric if (*plastiter != 0 && 6700b57cec5SDimitry Andric !(*plower >= upper && *pupper < upper - incr)) 6710b57cec5SDimitry Andric *plastiter = 0; 6720b57cec5SDimitry Andric if (*pupper < upper) 6730b57cec5SDimitry Andric *pupper = upper; // tracker C73258 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric } 6770b57cec5SDimitry Andric break; 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric case kmp_sch_static_chunked: { 6800b57cec5SDimitry Andric ST span; 6810b57cec5SDimitry Andric if (chunk < 1) 6820b57cec5SDimitry Andric chunk = 1; 6830b57cec5SDimitry Andric span = chunk * incr; 6840b57cec5SDimitry Andric *pstride = span * nth; 6850b57cec5SDimitry Andric *plower = *plower + (span * tid); 6860b57cec5SDimitry Andric *pupper = *plower + span - incr; 6870b57cec5SDimitry Andric if (plastiter != NULL) 6880b57cec5SDimitry Andric if (*plastiter != 0 && !(tid == ((trip_count - 1) / (UT)chunk) % nth)) 6890b57cec5SDimitry Andric *plastiter = 0; 6900b57cec5SDimitry Andric break; 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric default: 6930b57cec5SDimitry Andric KMP_ASSERT2(0, 6940b57cec5SDimitry Andric "__kmpc_dist_for_static_init: unknown loop scheduling type"); 6950b57cec5SDimitry Andric break; 6960b57cec5SDimitry Andric } 6970b57cec5SDimitry Andric } 6980b57cec5SDimitry Andric end:; 6990b57cec5SDimitry Andric #ifdef KMP_DEBUG 7000b57cec5SDimitry Andric { 7010b57cec5SDimitry Andric char *buff; 7020b57cec5SDimitry Andric // create format specifiers before the debug output 7030b57cec5SDimitry Andric buff = __kmp_str_format( 7040b57cec5SDimitry Andric "__kmpc_dist_for_static_init: last=%%d lo=%%%s up=%%%s upDist=%%%s " 7050b57cec5SDimitry Andric "stride=%%%s signed?<%s>\n", 7060b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec, 7070b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<T>::spec); 7080b57cec5SDimitry Andric KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pupperDist, *pstride)); 7090b57cec5SDimitry Andric __kmp_str_free(&buff); 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric #endif 7120b57cec5SDimitry Andric KE_TRACE(10, ("__kmpc_dist_for_static_init: T#%d return\n", gtid)); 71381ad6265SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 71481ad6265SDimitry Andric if (ompt_enabled.ompt_callback_work || ompt_enabled.ompt_callback_dispatch) { 71581ad6265SDimitry Andric ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); 71681ad6265SDimitry Andric ompt_task_info_t *task_info = __ompt_get_task_info_object(0); 71781ad6265SDimitry Andric if (ompt_enabled.ompt_callback_work) { 71881ad6265SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 71981ad6265SDimitry Andric ompt_work_distribute, ompt_scope_begin, &(team_info->parallel_data), 72081ad6265SDimitry Andric &(task_info->task_data), 0, codeptr); 72181ad6265SDimitry Andric } 72281ad6265SDimitry Andric if (ompt_enabled.ompt_callback_dispatch) { 72381ad6265SDimitry Andric ompt_data_t instance = ompt_data_none; 72481ad6265SDimitry Andric ompt_dispatch_chunk_t dispatch_chunk; 72581ad6265SDimitry Andric OMPT_GET_DISPATCH_CHUNK(dispatch_chunk, *plower, *pupperDist, incr); 72681ad6265SDimitry Andric instance.ptr = &dispatch_chunk; 72781ad6265SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_dispatch)( 72881ad6265SDimitry Andric &(team_info->parallel_data), &(task_info->task_data), 72981ad6265SDimitry Andric ompt_dispatch_distribute_chunk, instance); 73081ad6265SDimitry Andric } 73181ad6265SDimitry Andric } 73281ad6265SDimitry Andric #endif // OMPT_SUPPORT && OMPT_OPTIONAL 7330b57cec5SDimitry Andric KMP_STATS_LOOP_END(OMP_distribute_iterations); 7340b57cec5SDimitry Andric return; 7350b57cec5SDimitry Andric } 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric template <typename T> 7380b57cec5SDimitry Andric static void __kmp_team_static_init(ident_t *loc, kmp_int32 gtid, 7390b57cec5SDimitry Andric kmp_int32 *p_last, T *p_lb, T *p_ub, 7400b57cec5SDimitry Andric typename traits_t<T>::signed_t *p_st, 7410b57cec5SDimitry Andric typename traits_t<T>::signed_t incr, 7420b57cec5SDimitry Andric typename traits_t<T>::signed_t chunk) { 7430b57cec5SDimitry Andric // The routine returns the first chunk distributed to the team and 7440b57cec5SDimitry Andric // stride for next chunks calculation. 7450b57cec5SDimitry Andric // Last iteration flag set for the team that will execute 7460b57cec5SDimitry Andric // the last iteration of the loop. 7475ffd83dbSDimitry Andric // The routine is called for dist_schedule(static,chunk) only. 7480b57cec5SDimitry Andric typedef typename traits_t<T>::unsigned_t UT; 7490b57cec5SDimitry Andric typedef typename traits_t<T>::signed_t ST; 7500b57cec5SDimitry Andric kmp_uint32 team_id; 7510b57cec5SDimitry Andric kmp_uint32 nteams; 7520b57cec5SDimitry Andric UT trip_count; 7530b57cec5SDimitry Andric T lower; 7540b57cec5SDimitry Andric T upper; 7550b57cec5SDimitry Andric ST span; 7560b57cec5SDimitry Andric kmp_team_t *team; 7570b57cec5SDimitry Andric kmp_info_t *th; 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric KMP_DEBUG_ASSERT(p_last && p_lb && p_ub && p_st); 7600b57cec5SDimitry Andric KE_TRACE(10, ("__kmp_team_static_init called (%d)\n", gtid)); 761e8d8bef9SDimitry Andric __kmp_assert_valid_gtid(gtid); 7620b57cec5SDimitry Andric #ifdef KMP_DEBUG 7630b57cec5SDimitry Andric { 7640b57cec5SDimitry Andric char *buff; 7650b57cec5SDimitry Andric // create format specifiers before the debug output 7660b57cec5SDimitry Andric buff = __kmp_str_format("__kmp_team_static_init enter: T#%%d liter=%%d " 7670b57cec5SDimitry Andric "iter=(%%%s, %%%s, %%%s) chunk %%%s; signed?<%s>\n", 7680b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, 7690b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<ST>::spec, 7700b57cec5SDimitry Andric traits_t<T>::spec); 7710b57cec5SDimitry Andric KD_TRACE(100, (buff, gtid, *p_last, *p_lb, *p_ub, *p_st, chunk)); 7720b57cec5SDimitry Andric __kmp_str_free(&buff); 7730b57cec5SDimitry Andric } 7740b57cec5SDimitry Andric #endif 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric lower = *p_lb; 7770b57cec5SDimitry Andric upper = *p_ub; 7780b57cec5SDimitry Andric if (__kmp_env_consistency_check) { 7790b57cec5SDimitry Andric if (incr == 0) { 7800b57cec5SDimitry Andric __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, 7810b57cec5SDimitry Andric loc); 7820b57cec5SDimitry Andric } 7830b57cec5SDimitry Andric if (incr > 0 ? (upper < lower) : (lower < upper)) { 7840b57cec5SDimitry Andric // The loop is illegal. 7850b57cec5SDimitry Andric // Some zero-trip loops maintained by compiler, e.g.: 7860b57cec5SDimitry Andric // for(i=10;i<0;++i) // lower >= upper - run-time check 7870b57cec5SDimitry Andric // for(i=0;i>10;--i) // lower <= upper - run-time check 7880b57cec5SDimitry Andric // for(i=0;i>10;++i) // incr > 0 - compile-time check 7890b57cec5SDimitry Andric // for(i=10;i<0;--i) // incr < 0 - compile-time check 7900b57cec5SDimitry Andric // Compiler does not check the following illegal loops: 7910b57cec5SDimitry Andric // for(i=0;i<10;i+=incr) // where incr<0 7920b57cec5SDimitry Andric // for(i=10;i>0;i-=incr) // where incr<0 7930b57cec5SDimitry Andric __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc); 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric th = __kmp_threads[gtid]; 7970b57cec5SDimitry Andric team = th->th.th_team; 7980b57cec5SDimitry Andric KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct 7990b57cec5SDimitry Andric nteams = th->th.th_teams_size.nteams; 8000b57cec5SDimitry Andric team_id = team->t.t_master_tid; 8010b57cec5SDimitry Andric KMP_DEBUG_ASSERT(nteams == (kmp_uint32)team->t.t_parent->t.t_nproc); 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric // compute trip count 8040b57cec5SDimitry Andric if (incr == 1) { 8050b57cec5SDimitry Andric trip_count = upper - lower + 1; 8060b57cec5SDimitry Andric } else if (incr == -1) { 8070b57cec5SDimitry Andric trip_count = lower - upper + 1; 8080b57cec5SDimitry Andric } else if (incr > 0) { 8090b57cec5SDimitry Andric // upper-lower can exceed the limit of signed type 8100b57cec5SDimitry Andric trip_count = (UT)(upper - lower) / incr + 1; 8110b57cec5SDimitry Andric } else { 8120b57cec5SDimitry Andric trip_count = (UT)(lower - upper) / (-incr) + 1; 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric if (chunk < 1) 8150b57cec5SDimitry Andric chunk = 1; 8160b57cec5SDimitry Andric span = chunk * incr; 8170b57cec5SDimitry Andric *p_st = span * nteams; 8180b57cec5SDimitry Andric *p_lb = lower + (span * team_id); 8190b57cec5SDimitry Andric *p_ub = *p_lb + span - incr; 8200b57cec5SDimitry Andric if (p_last != NULL) 8210b57cec5SDimitry Andric *p_last = (team_id == ((trip_count - 1) / (UT)chunk) % nteams); 8220b57cec5SDimitry Andric // Correct upper bound if needed 8230b57cec5SDimitry Andric if (incr > 0) { 8240b57cec5SDimitry Andric if (*p_ub < *p_lb) // overflow? 8250b57cec5SDimitry Andric *p_ub = traits_t<T>::max_value; 8260b57cec5SDimitry Andric if (*p_ub > upper) 8270b57cec5SDimitry Andric *p_ub = upper; // tracker C73258 8280b57cec5SDimitry Andric } else { // incr < 0 8290b57cec5SDimitry Andric if (*p_ub > *p_lb) 8300b57cec5SDimitry Andric *p_ub = traits_t<T>::min_value; 8310b57cec5SDimitry Andric if (*p_ub < upper) 8320b57cec5SDimitry Andric *p_ub = upper; // tracker C73258 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric #ifdef KMP_DEBUG 8350b57cec5SDimitry Andric { 8360b57cec5SDimitry Andric char *buff; 8370b57cec5SDimitry Andric // create format specifiers before the debug output 8380b57cec5SDimitry Andric buff = 8390b57cec5SDimitry Andric __kmp_str_format("__kmp_team_static_init exit: T#%%d team%%u liter=%%d " 8400b57cec5SDimitry Andric "iter=(%%%s, %%%s, %%%s) chunk %%%s\n", 8410b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, 8420b57cec5SDimitry Andric traits_t<ST>::spec, traits_t<ST>::spec); 8430b57cec5SDimitry Andric KD_TRACE(100, (buff, gtid, team_id, *p_last, *p_lb, *p_ub, *p_st, chunk)); 8440b57cec5SDimitry Andric __kmp_str_free(&buff); 8450b57cec5SDimitry Andric } 8460b57cec5SDimitry Andric #endif 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric //------------------------------------------------------------------------------ 8500b57cec5SDimitry Andric extern "C" { 8510b57cec5SDimitry Andric /*! 8520b57cec5SDimitry Andric @ingroup WORK_SHARING 8530b57cec5SDimitry Andric @param loc Source code location 8540b57cec5SDimitry Andric @param gtid Global thread id of this thread 8550b57cec5SDimitry Andric @param schedtype Scheduling type 8560b57cec5SDimitry Andric @param plastiter Pointer to the "last iteration" flag 8570b57cec5SDimitry Andric @param plower Pointer to the lower bound 8580b57cec5SDimitry Andric @param pupper Pointer to the upper bound 8590b57cec5SDimitry Andric @param pstride Pointer to the stride 8600b57cec5SDimitry Andric @param incr Loop increment 8610b57cec5SDimitry Andric @param chunk The chunk size 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric Each of the four functions here are identical apart from the argument types. 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric The functions compute the upper and lower bounds and stride to be used for the 8660b57cec5SDimitry Andric set of iterations to be executed by the current thread from the statically 8670b57cec5SDimitry Andric scheduled loop that is described by the initial values of the bounds, stride, 8680b57cec5SDimitry Andric increment and chunk size. 8690b57cec5SDimitry Andric 8700b57cec5SDimitry Andric @{ 8710b57cec5SDimitry Andric */ 8720b57cec5SDimitry Andric void __kmpc_for_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, 8730b57cec5SDimitry Andric kmp_int32 *plastiter, kmp_int32 *plower, 8740b57cec5SDimitry Andric kmp_int32 *pupper, kmp_int32 *pstride, 8750b57cec5SDimitry Andric kmp_int32 incr, kmp_int32 chunk) { 8760b57cec5SDimitry Andric __kmp_for_static_init<kmp_int32>(loc, gtid, schedtype, plastiter, plower, 8770b57cec5SDimitry Andric pupper, pstride, incr, chunk 8780b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 8790b57cec5SDimitry Andric , 8800b57cec5SDimitry Andric OMPT_GET_RETURN_ADDRESS(0) 8810b57cec5SDimitry Andric #endif 8820b57cec5SDimitry Andric ); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric /*! 8860b57cec5SDimitry Andric See @ref __kmpc_for_static_init_4 8870b57cec5SDimitry Andric */ 8880b57cec5SDimitry Andric void __kmpc_for_static_init_4u(ident_t *loc, kmp_int32 gtid, 8890b57cec5SDimitry Andric kmp_int32 schedtype, kmp_int32 *plastiter, 8900b57cec5SDimitry Andric kmp_uint32 *plower, kmp_uint32 *pupper, 8910b57cec5SDimitry Andric kmp_int32 *pstride, kmp_int32 incr, 8920b57cec5SDimitry Andric kmp_int32 chunk) { 8930b57cec5SDimitry Andric __kmp_for_static_init<kmp_uint32>(loc, gtid, schedtype, plastiter, plower, 8940b57cec5SDimitry Andric pupper, pstride, incr, chunk 8950b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 8960b57cec5SDimitry Andric , 8970b57cec5SDimitry Andric OMPT_GET_RETURN_ADDRESS(0) 8980b57cec5SDimitry Andric #endif 8990b57cec5SDimitry Andric ); 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric /*! 9030b57cec5SDimitry Andric See @ref __kmpc_for_static_init_4 9040b57cec5SDimitry Andric */ 9050b57cec5SDimitry Andric void __kmpc_for_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, 9060b57cec5SDimitry Andric kmp_int32 *plastiter, kmp_int64 *plower, 9070b57cec5SDimitry Andric kmp_int64 *pupper, kmp_int64 *pstride, 9080b57cec5SDimitry Andric kmp_int64 incr, kmp_int64 chunk) { 9090b57cec5SDimitry Andric __kmp_for_static_init<kmp_int64>(loc, gtid, schedtype, plastiter, plower, 9100b57cec5SDimitry Andric pupper, pstride, incr, chunk 9110b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 9120b57cec5SDimitry Andric , 9130b57cec5SDimitry Andric OMPT_GET_RETURN_ADDRESS(0) 9140b57cec5SDimitry Andric #endif 9150b57cec5SDimitry Andric ); 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric /*! 9190b57cec5SDimitry Andric See @ref __kmpc_for_static_init_4 9200b57cec5SDimitry Andric */ 9210b57cec5SDimitry Andric void __kmpc_for_static_init_8u(ident_t *loc, kmp_int32 gtid, 9220b57cec5SDimitry Andric kmp_int32 schedtype, kmp_int32 *plastiter, 9230b57cec5SDimitry Andric kmp_uint64 *plower, kmp_uint64 *pupper, 9240b57cec5SDimitry Andric kmp_int64 *pstride, kmp_int64 incr, 9250b57cec5SDimitry Andric kmp_int64 chunk) { 9260b57cec5SDimitry Andric __kmp_for_static_init<kmp_uint64>(loc, gtid, schedtype, plastiter, plower, 9270b57cec5SDimitry Andric pupper, pstride, incr, chunk 9280b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 9290b57cec5SDimitry Andric , 9300b57cec5SDimitry Andric OMPT_GET_RETURN_ADDRESS(0) 9310b57cec5SDimitry Andric #endif 9320b57cec5SDimitry Andric ); 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric /*! 9350b57cec5SDimitry Andric @} 9360b57cec5SDimitry Andric */ 9370b57cec5SDimitry Andric 93881ad6265SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 93981ad6265SDimitry Andric #define OMPT_CODEPTR_ARG , OMPT_GET_RETURN_ADDRESS(0) 94081ad6265SDimitry Andric #else 94181ad6265SDimitry Andric #define OMPT_CODEPTR_ARG 94281ad6265SDimitry Andric #endif 94381ad6265SDimitry Andric 9440b57cec5SDimitry Andric /*! 9450b57cec5SDimitry Andric @ingroup WORK_SHARING 9460b57cec5SDimitry Andric @param loc Source code location 9470b57cec5SDimitry Andric @param gtid Global thread id of this thread 9480b57cec5SDimitry Andric @param schedule Scheduling type for the parallel loop 9490b57cec5SDimitry Andric @param plastiter Pointer to the "last iteration" flag 9500b57cec5SDimitry Andric @param plower Pointer to the lower bound 9510b57cec5SDimitry Andric @param pupper Pointer to the upper bound of loop chunk 9520b57cec5SDimitry Andric @param pupperD Pointer to the upper bound of dist_chunk 9530b57cec5SDimitry Andric @param pstride Pointer to the stride for parallel loop 9540b57cec5SDimitry Andric @param incr Loop increment 9550b57cec5SDimitry Andric @param chunk The chunk size for the parallel loop 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric Each of the four functions here are identical apart from the argument types. 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric The functions compute the upper and lower bounds and strides to be used for the 9600b57cec5SDimitry Andric set of iterations to be executed by the current thread from the statically 9610b57cec5SDimitry Andric scheduled loop that is described by the initial values of the bounds, strides, 9620b57cec5SDimitry Andric increment and chunks for parallel loop and distribute constructs. 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric @{ 9650b57cec5SDimitry Andric */ 9660b57cec5SDimitry Andric void __kmpc_dist_for_static_init_4(ident_t *loc, kmp_int32 gtid, 9670b57cec5SDimitry Andric kmp_int32 schedule, kmp_int32 *plastiter, 9680b57cec5SDimitry Andric kmp_int32 *plower, kmp_int32 *pupper, 9690b57cec5SDimitry Andric kmp_int32 *pupperD, kmp_int32 *pstride, 9700b57cec5SDimitry Andric kmp_int32 incr, kmp_int32 chunk) { 9710b57cec5SDimitry Andric __kmp_dist_for_static_init<kmp_int32>(loc, gtid, schedule, plastiter, plower, 97281ad6265SDimitry Andric pupper, pupperD, pstride, incr, 97381ad6265SDimitry Andric chunk OMPT_CODEPTR_ARG); 9740b57cec5SDimitry Andric } 9750b57cec5SDimitry Andric 9760b57cec5SDimitry Andric /*! 9770b57cec5SDimitry Andric See @ref __kmpc_dist_for_static_init_4 9780b57cec5SDimitry Andric */ 9790b57cec5SDimitry Andric void __kmpc_dist_for_static_init_4u(ident_t *loc, kmp_int32 gtid, 9800b57cec5SDimitry Andric kmp_int32 schedule, kmp_int32 *plastiter, 9810b57cec5SDimitry Andric kmp_uint32 *plower, kmp_uint32 *pupper, 9820b57cec5SDimitry Andric kmp_uint32 *pupperD, kmp_int32 *pstride, 9830b57cec5SDimitry Andric kmp_int32 incr, kmp_int32 chunk) { 9840b57cec5SDimitry Andric __kmp_dist_for_static_init<kmp_uint32>(loc, gtid, schedule, plastiter, plower, 98581ad6265SDimitry Andric pupper, pupperD, pstride, incr, 98681ad6265SDimitry Andric chunk OMPT_CODEPTR_ARG); 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric /*! 9900b57cec5SDimitry Andric See @ref __kmpc_dist_for_static_init_4 9910b57cec5SDimitry Andric */ 9920b57cec5SDimitry Andric void __kmpc_dist_for_static_init_8(ident_t *loc, kmp_int32 gtid, 9930b57cec5SDimitry Andric kmp_int32 schedule, kmp_int32 *plastiter, 9940b57cec5SDimitry Andric kmp_int64 *plower, kmp_int64 *pupper, 9950b57cec5SDimitry Andric kmp_int64 *pupperD, kmp_int64 *pstride, 9960b57cec5SDimitry Andric kmp_int64 incr, kmp_int64 chunk) { 9970b57cec5SDimitry Andric __kmp_dist_for_static_init<kmp_int64>(loc, gtid, schedule, plastiter, plower, 99881ad6265SDimitry Andric pupper, pupperD, pstride, incr, 99981ad6265SDimitry Andric chunk OMPT_CODEPTR_ARG); 10000b57cec5SDimitry Andric } 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric /*! 10030b57cec5SDimitry Andric See @ref __kmpc_dist_for_static_init_4 10040b57cec5SDimitry Andric */ 10050b57cec5SDimitry Andric void __kmpc_dist_for_static_init_8u(ident_t *loc, kmp_int32 gtid, 10060b57cec5SDimitry Andric kmp_int32 schedule, kmp_int32 *plastiter, 10070b57cec5SDimitry Andric kmp_uint64 *plower, kmp_uint64 *pupper, 10080b57cec5SDimitry Andric kmp_uint64 *pupperD, kmp_int64 *pstride, 10090b57cec5SDimitry Andric kmp_int64 incr, kmp_int64 chunk) { 10100b57cec5SDimitry Andric __kmp_dist_for_static_init<kmp_uint64>(loc, gtid, schedule, plastiter, plower, 101181ad6265SDimitry Andric pupper, pupperD, pstride, incr, 101281ad6265SDimitry Andric chunk OMPT_CODEPTR_ARG); 10130b57cec5SDimitry Andric } 10140b57cec5SDimitry Andric /*! 10150b57cec5SDimitry Andric @} 10160b57cec5SDimitry Andric */ 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric //------------------------------------------------------------------------------ 10190b57cec5SDimitry Andric // Auxiliary routines for Distribute Parallel Loop construct implementation 10200b57cec5SDimitry Andric // Transfer call to template< type T > 10210b57cec5SDimitry Andric // __kmp_team_static_init( ident_t *loc, int gtid, 10220b57cec5SDimitry Andric // int *p_last, T *lb, T *ub, ST *st, ST incr, ST chunk ) 10230b57cec5SDimitry Andric 10240b57cec5SDimitry Andric /*! 10250b57cec5SDimitry Andric @ingroup WORK_SHARING 10260b57cec5SDimitry Andric @{ 10270b57cec5SDimitry Andric @param loc Source location 10280b57cec5SDimitry Andric @param gtid Global thread id 10290b57cec5SDimitry Andric @param p_last pointer to last iteration flag 10300b57cec5SDimitry Andric @param p_lb pointer to Lower bound 10310b57cec5SDimitry Andric @param p_ub pointer to Upper bound 10320b57cec5SDimitry Andric @param p_st Step (or increment if you prefer) 10330b57cec5SDimitry Andric @param incr Loop increment 10340b57cec5SDimitry Andric @param chunk The chunk size to block with 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric The functions compute the upper and lower bounds and stride to be used for the 10370b57cec5SDimitry Andric set of iterations to be executed by the current team from the statically 10380b57cec5SDimitry Andric scheduled loop that is described by the initial values of the bounds, stride, 10390b57cec5SDimitry Andric increment and chunk for the distribute construct as part of composite distribute 10400b57cec5SDimitry Andric parallel loop construct. These functions are all identical apart from the types 10410b57cec5SDimitry Andric of the arguments. 10420b57cec5SDimitry Andric */ 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric void __kmpc_team_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 10450b57cec5SDimitry Andric kmp_int32 *p_lb, kmp_int32 *p_ub, 10460b57cec5SDimitry Andric kmp_int32 *p_st, kmp_int32 incr, 10470b57cec5SDimitry Andric kmp_int32 chunk) { 10480b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_init_serial); 10490b57cec5SDimitry Andric __kmp_team_static_init<kmp_int32>(loc, gtid, p_last, p_lb, p_ub, p_st, incr, 10500b57cec5SDimitry Andric chunk); 10510b57cec5SDimitry Andric } 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric /*! 10540b57cec5SDimitry Andric See @ref __kmpc_team_static_init_4 10550b57cec5SDimitry Andric */ 10560b57cec5SDimitry Andric void __kmpc_team_static_init_4u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 10570b57cec5SDimitry Andric kmp_uint32 *p_lb, kmp_uint32 *p_ub, 10580b57cec5SDimitry Andric kmp_int32 *p_st, kmp_int32 incr, 10590b57cec5SDimitry Andric kmp_int32 chunk) { 10600b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_init_serial); 10610b57cec5SDimitry Andric __kmp_team_static_init<kmp_uint32>(loc, gtid, p_last, p_lb, p_ub, p_st, incr, 10620b57cec5SDimitry Andric chunk); 10630b57cec5SDimitry Andric } 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric /*! 10660b57cec5SDimitry Andric See @ref __kmpc_team_static_init_4 10670b57cec5SDimitry Andric */ 10680b57cec5SDimitry Andric void __kmpc_team_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 10690b57cec5SDimitry Andric kmp_int64 *p_lb, kmp_int64 *p_ub, 10700b57cec5SDimitry Andric kmp_int64 *p_st, kmp_int64 incr, 10710b57cec5SDimitry Andric kmp_int64 chunk) { 10720b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_init_serial); 10730b57cec5SDimitry Andric __kmp_team_static_init<kmp_int64>(loc, gtid, p_last, p_lb, p_ub, p_st, incr, 10740b57cec5SDimitry Andric chunk); 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric /*! 10780b57cec5SDimitry Andric See @ref __kmpc_team_static_init_4 10790b57cec5SDimitry Andric */ 10800b57cec5SDimitry Andric void __kmpc_team_static_init_8u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, 10810b57cec5SDimitry Andric kmp_uint64 *p_lb, kmp_uint64 *p_ub, 10820b57cec5SDimitry Andric kmp_int64 *p_st, kmp_int64 incr, 10830b57cec5SDimitry Andric kmp_int64 chunk) { 10840b57cec5SDimitry Andric KMP_DEBUG_ASSERT(__kmp_init_serial); 10850b57cec5SDimitry Andric __kmp_team_static_init<kmp_uint64>(loc, gtid, p_last, p_lb, p_ub, p_st, incr, 10860b57cec5SDimitry Andric chunk); 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric /*! 10890b57cec5SDimitry Andric @} 10900b57cec5SDimitry Andric */ 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric } // extern "C" 1093