xref: /freebsd-src/contrib/llvm-project/openmp/runtime/src/kmp_sched.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 {                                                                   \
55*0fca6ea1SDimitry Andric       KMP_DEBUG_ASSERT(i != 0);                                                \
560b57cec5SDimitry Andric       t = (l - u) / (-i) + 1;                                                  \
570b57cec5SDimitry Andric     }                                                                          \
580b57cec5SDimitry Andric     KMP_COUNT_VALUE(stat, t);                                                  \
590b57cec5SDimitry Andric     KMP_POP_PARTITIONED_TIMER();                                               \
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric #else
620b57cec5SDimitry Andric #define KMP_STATS_LOOP_END(stat) /* Nothing */
630b57cec5SDimitry Andric #endif
640b57cec5SDimitry Andric 
6506c3fb27SDimitry Andric #if USE_ITT_BUILD || defined KMP_DEBUG
66e8d8bef9SDimitry Andric static ident_t loc_stub = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;"};
67e8d8bef9SDimitry Andric static inline void check_loc(ident_t *&loc) {
68e8d8bef9SDimitry Andric   if (loc == NULL)
69e8d8bef9SDimitry Andric     loc = &loc_stub; // may need to report location info to ittnotify
70e8d8bef9SDimitry Andric }
7106c3fb27SDimitry Andric #endif
72e8d8bef9SDimitry Andric 
730b57cec5SDimitry Andric template <typename T>
740b57cec5SDimitry Andric static void __kmp_for_static_init(ident_t *loc, kmp_int32 global_tid,
750b57cec5SDimitry Andric                                   kmp_int32 schedtype, kmp_int32 *plastiter,
760b57cec5SDimitry Andric                                   T *plower, T *pupper,
770b57cec5SDimitry Andric                                   typename traits_t<T>::signed_t *pstride,
780b57cec5SDimitry Andric                                   typename traits_t<T>::signed_t incr,
790b57cec5SDimitry Andric                                   typename traits_t<T>::signed_t chunk
800b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
810b57cec5SDimitry Andric                                   ,
820b57cec5SDimitry Andric                                   void *codeptr
830b57cec5SDimitry Andric #endif
840b57cec5SDimitry Andric ) {
850b57cec5SDimitry Andric   KMP_COUNT_BLOCK(OMP_LOOP_STATIC);
860b57cec5SDimitry Andric   KMP_PUSH_PARTITIONED_TIMER(OMP_loop_static);
870b57cec5SDimitry Andric   KMP_PUSH_PARTITIONED_TIMER(OMP_loop_static_scheduling);
880b57cec5SDimitry Andric 
89bdd1243dSDimitry Andric   // Clear monotonic/nonmonotonic bits (ignore it)
90bdd1243dSDimitry Andric   schedtype = SCHEDULE_WITHOUT_MODIFIERS(schedtype);
91bdd1243dSDimitry Andric 
920b57cec5SDimitry Andric   typedef typename traits_t<T>::unsigned_t UT;
930b57cec5SDimitry Andric   typedef typename traits_t<T>::signed_t ST;
940b57cec5SDimitry Andric   /*  this all has to be changed back to TID and such.. */
950b57cec5SDimitry Andric   kmp_int32 gtid = global_tid;
960b57cec5SDimitry Andric   kmp_uint32 tid;
970b57cec5SDimitry Andric   kmp_uint32 nth;
980b57cec5SDimitry Andric   UT trip_count;
990b57cec5SDimitry Andric   kmp_team_t *team;
100e8d8bef9SDimitry Andric   __kmp_assert_valid_gtid(gtid);
1010b57cec5SDimitry Andric   kmp_info_t *th = __kmp_threads[gtid];
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1040b57cec5SDimitry Andric   ompt_team_info_t *team_info = NULL;
1050b57cec5SDimitry Andric   ompt_task_info_t *task_info = NULL;
106*0fca6ea1SDimitry Andric   ompt_work_t ompt_work_type = ompt_work_loop_static;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   static kmp_int8 warn = 0;
1090b57cec5SDimitry Andric 
11081ad6265SDimitry Andric   if (ompt_enabled.ompt_callback_work || ompt_enabled.ompt_callback_dispatch) {
1110b57cec5SDimitry Andric     // Only fully initialize variables needed by OMPT if OMPT is enabled.
1120b57cec5SDimitry Andric     team_info = __ompt_get_teaminfo(0, NULL);
1130b57cec5SDimitry Andric     task_info = __ompt_get_task_info_object(0);
1140b57cec5SDimitry Andric     // Determine workshare type
1150b57cec5SDimitry Andric     if (loc != NULL) {
1160b57cec5SDimitry Andric       if ((loc->flags & KMP_IDENT_WORK_LOOP) != 0) {
117*0fca6ea1SDimitry Andric         ompt_work_type = ompt_work_loop_static;
1180b57cec5SDimitry Andric       } else if ((loc->flags & KMP_IDENT_WORK_SECTIONS) != 0) {
1190b57cec5SDimitry Andric         ompt_work_type = ompt_work_sections;
1200b57cec5SDimitry Andric       } else if ((loc->flags & KMP_IDENT_WORK_DISTRIBUTE) != 0) {
1210b57cec5SDimitry Andric         ompt_work_type = ompt_work_distribute;
1220b57cec5SDimitry Andric       } else {
1230b57cec5SDimitry Andric         kmp_int8 bool_res =
1240b57cec5SDimitry Andric             KMP_COMPARE_AND_STORE_ACQ8(&warn, (kmp_int8)0, (kmp_int8)1);
1250b57cec5SDimitry Andric         if (bool_res)
1260b57cec5SDimitry Andric           KMP_WARNING(OmptOutdatedWorkshare);
1270b57cec5SDimitry Andric       }
1280b57cec5SDimitry Andric       KMP_DEBUG_ASSERT(ompt_work_type);
1290b57cec5SDimitry Andric     }
1300b57cec5SDimitry Andric   }
1310b57cec5SDimitry Andric #endif
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(plastiter && plower && pupper && pstride);
1340b57cec5SDimitry Andric   KE_TRACE(10, ("__kmpc_for_static_init called (%d)\n", global_tid));
1350b57cec5SDimitry Andric #ifdef KMP_DEBUG
1360b57cec5SDimitry Andric   {
1370b57cec5SDimitry Andric     char *buff;
1380b57cec5SDimitry Andric     // create format specifiers before the debug output
1390b57cec5SDimitry Andric     buff = __kmp_str_format(
1400b57cec5SDimitry Andric         "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s,"
1410b57cec5SDimitry Andric         " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n",
1420b57cec5SDimitry Andric         traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec,
1430b57cec5SDimitry Andric         traits_t<ST>::spec, traits_t<ST>::spec, traits_t<T>::spec);
1440b57cec5SDimitry Andric     KD_TRACE(100, (buff, global_tid, schedtype, *plastiter, *plower, *pupper,
1450b57cec5SDimitry Andric                    *pstride, incr, chunk));
1460b57cec5SDimitry Andric     __kmp_str_free(&buff);
1470b57cec5SDimitry Andric   }
1480b57cec5SDimitry Andric #endif
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   if (__kmp_env_consistency_check) {
1510b57cec5SDimitry Andric     __kmp_push_workshare(global_tid, ct_pdo, loc);
1520b57cec5SDimitry Andric     if (incr == 0) {
1530b57cec5SDimitry Andric       __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo,
1540b57cec5SDimitry Andric                             loc);
1550b57cec5SDimitry Andric     }
1560b57cec5SDimitry Andric   }
1570b57cec5SDimitry Andric   /* special handling for zero-trip loops */
1580b57cec5SDimitry Andric   if (incr > 0 ? (*pupper < *plower) : (*plower < *pupper)) {
1590b57cec5SDimitry Andric     if (plastiter != NULL)
1600b57cec5SDimitry Andric       *plastiter = FALSE;
1610b57cec5SDimitry Andric     /* leave pupper and plower set to entire iteration space */
1620b57cec5SDimitry Andric     *pstride = incr; /* value should never be used */
1630b57cec5SDimitry Andric // *plower = *pupper - incr;
1640b57cec5SDimitry Andric // let compiler bypass the illegal loop (like for(i=1;i<10;i--))
1650b57cec5SDimitry Andric // THE LINE COMMENTED ABOVE CAUSED shape2F/h_tests_1.f TO HAVE A FAILURE
1660b57cec5SDimitry Andric // ON A ZERO-TRIP LOOP (lower=1, upper=0,stride=1) - JPH June 23, 2009.
1670b57cec5SDimitry Andric #ifdef KMP_DEBUG
1680b57cec5SDimitry Andric     {
1690b57cec5SDimitry Andric       char *buff;
1700b57cec5SDimitry Andric       // create format specifiers before the debug output
1710b57cec5SDimitry Andric       buff = __kmp_str_format("__kmpc_for_static_init:(ZERO TRIP) liter=%%d "
1720b57cec5SDimitry Andric                               "lower=%%%s upper=%%%s stride = %%%s "
1730b57cec5SDimitry Andric                               "signed?<%s>, loc = %%s\n",
1740b57cec5SDimitry Andric                               traits_t<T>::spec, traits_t<T>::spec,
1750b57cec5SDimitry Andric                               traits_t<ST>::spec, traits_t<T>::spec);
176fe6060f1SDimitry Andric       check_loc(loc);
1770b57cec5SDimitry Andric       KD_TRACE(100,
1780b57cec5SDimitry Andric                (buff, *plastiter, *plower, *pupper, *pstride, loc->psource));
1790b57cec5SDimitry Andric       __kmp_str_free(&buff);
1800b57cec5SDimitry Andric     }
1810b57cec5SDimitry Andric #endif
1820b57cec5SDimitry Andric     KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid));
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1850b57cec5SDimitry Andric     if (ompt_enabled.ompt_callback_work) {
1860b57cec5SDimitry Andric       ompt_callbacks.ompt_callback(ompt_callback_work)(
1870b57cec5SDimitry Andric           ompt_work_type, ompt_scope_begin, &(team_info->parallel_data),
1880b57cec5SDimitry Andric           &(task_info->task_data), 0, codeptr);
1890b57cec5SDimitry Andric     }
1900b57cec5SDimitry Andric #endif
1910b57cec5SDimitry Andric     KMP_STATS_LOOP_END(OMP_loop_static_iterations);
1920b57cec5SDimitry Andric     return;
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   // Although there are schedule enumerations above kmp_ord_upper which are not
1960b57cec5SDimitry Andric   // schedules for "distribute", the only ones which are useful are dynamic, so
1970b57cec5SDimitry Andric   // cannot be seen here, since this codepath is only executed for static
1980b57cec5SDimitry Andric   // schedules.
1990b57cec5SDimitry Andric   if (schedtype > kmp_ord_upper) {
2000b57cec5SDimitry Andric     // we are in DISTRIBUTE construct
2010b57cec5SDimitry Andric     schedtype += kmp_sch_static -
2020b57cec5SDimitry Andric                  kmp_distribute_static; // AC: convert to usual schedule type
20381ad6265SDimitry Andric     if (th->th.th_team->t.t_serialized > 1) {
20481ad6265SDimitry Andric       tid = 0;
20581ad6265SDimitry Andric       team = th->th.th_team;
20681ad6265SDimitry Andric     } else {
2070b57cec5SDimitry Andric       tid = th->th.th_team->t.t_master_tid;
2080b57cec5SDimitry Andric       team = th->th.th_team->t.t_parent;
20981ad6265SDimitry Andric     }
2100b57cec5SDimitry Andric   } else {
2110b57cec5SDimitry Andric     tid = __kmp_tid_from_gtid(global_tid);
2120b57cec5SDimitry Andric     team = th->th.th_team;
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   /* determine if "for" loop is an active worksharing construct */
2160b57cec5SDimitry Andric   if (team->t.t_serialized) {
2170b57cec5SDimitry Andric     /* serialized parallel, each thread executes whole iteration space */
2180b57cec5SDimitry Andric     if (plastiter != NULL)
2190b57cec5SDimitry Andric       *plastiter = TRUE;
2200b57cec5SDimitry Andric     /* leave pupper and plower set to entire iteration space */
2210b57cec5SDimitry Andric     *pstride =
2220b57cec5SDimitry Andric         (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1));
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric #ifdef KMP_DEBUG
2250b57cec5SDimitry Andric     {
2260b57cec5SDimitry Andric       char *buff;
2270b57cec5SDimitry Andric       // create format specifiers before the debug output
2280b57cec5SDimitry Andric       buff = __kmp_str_format("__kmpc_for_static_init: (serial) liter=%%d "
2290b57cec5SDimitry Andric                               "lower=%%%s upper=%%%s stride = %%%s\n",
2300b57cec5SDimitry Andric                               traits_t<T>::spec, traits_t<T>::spec,
2310b57cec5SDimitry Andric                               traits_t<ST>::spec);
2320b57cec5SDimitry Andric       KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride));
2330b57cec5SDimitry Andric       __kmp_str_free(&buff);
2340b57cec5SDimitry Andric     }
2350b57cec5SDimitry Andric #endif
2360b57cec5SDimitry Andric     KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid));
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2390b57cec5SDimitry Andric     if (ompt_enabled.ompt_callback_work) {
2400b57cec5SDimitry Andric       ompt_callbacks.ompt_callback(ompt_callback_work)(
2410b57cec5SDimitry Andric           ompt_work_type, ompt_scope_begin, &(team_info->parallel_data),
2420b57cec5SDimitry Andric           &(task_info->task_data), *pstride, codeptr);
2430b57cec5SDimitry Andric     }
2440b57cec5SDimitry Andric #endif
2450b57cec5SDimitry Andric     KMP_STATS_LOOP_END(OMP_loop_static_iterations);
2460b57cec5SDimitry Andric     return;
2470b57cec5SDimitry Andric   }
2480b57cec5SDimitry Andric   nth = team->t.t_nproc;
2490b57cec5SDimitry Andric   if (nth == 1) {
2500b57cec5SDimitry Andric     if (plastiter != NULL)
2510b57cec5SDimitry Andric       *plastiter = TRUE;
2520b57cec5SDimitry Andric     *pstride =
2530b57cec5SDimitry Andric         (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1));
2540b57cec5SDimitry Andric #ifdef KMP_DEBUG
2550b57cec5SDimitry Andric     {
2560b57cec5SDimitry Andric       char *buff;
2570b57cec5SDimitry Andric       // create format specifiers before the debug output
2580b57cec5SDimitry Andric       buff = __kmp_str_format("__kmpc_for_static_init: (serial) liter=%%d "
2590b57cec5SDimitry Andric                               "lower=%%%s upper=%%%s stride = %%%s\n",
2600b57cec5SDimitry Andric                               traits_t<T>::spec, traits_t<T>::spec,
2610b57cec5SDimitry Andric                               traits_t<ST>::spec);
2620b57cec5SDimitry Andric       KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride));
2630b57cec5SDimitry Andric       __kmp_str_free(&buff);
2640b57cec5SDimitry Andric     }
2650b57cec5SDimitry Andric #endif
2660b57cec5SDimitry Andric     KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid));
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2690b57cec5SDimitry Andric     if (ompt_enabled.ompt_callback_work) {
2700b57cec5SDimitry Andric       ompt_callbacks.ompt_callback(ompt_callback_work)(
2710b57cec5SDimitry Andric           ompt_work_type, ompt_scope_begin, &(team_info->parallel_data),
2720b57cec5SDimitry Andric           &(task_info->task_data), *pstride, codeptr);
2730b57cec5SDimitry Andric     }
2740b57cec5SDimitry Andric #endif
2750b57cec5SDimitry Andric     KMP_STATS_LOOP_END(OMP_loop_static_iterations);
2760b57cec5SDimitry Andric     return;
2770b57cec5SDimitry Andric   }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   /* compute trip count */
2800b57cec5SDimitry Andric   if (incr == 1) {
2810b57cec5SDimitry Andric     trip_count = *pupper - *plower + 1;
2820b57cec5SDimitry Andric   } else if (incr == -1) {
2830b57cec5SDimitry Andric     trip_count = *plower - *pupper + 1;
2840b57cec5SDimitry Andric   } else if (incr > 0) {
2850b57cec5SDimitry Andric     // upper-lower can exceed the limit of signed type
2860b57cec5SDimitry Andric     trip_count = (UT)(*pupper - *plower) / incr + 1;
2870b57cec5SDimitry Andric   } else {
288*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(incr != 0);
2890b57cec5SDimitry Andric     trip_count = (UT)(*plower - *pupper) / (-incr) + 1;
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric #if KMP_STATS_ENABLED
2930b57cec5SDimitry Andric   if (KMP_MASTER_GTID(gtid)) {
2940b57cec5SDimitry Andric     KMP_COUNT_VALUE(OMP_loop_static_total_iterations, trip_count);
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric #endif
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   if (__kmp_env_consistency_check) {
2990b57cec5SDimitry Andric     /* tripcount overflow? */
3000b57cec5SDimitry Andric     if (trip_count == 0 && *pupper != *plower) {
3010b57cec5SDimitry Andric       __kmp_error_construct(kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo,
3020b57cec5SDimitry Andric                             loc);
3030b57cec5SDimitry Andric     }
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   /* compute remaining parameters */
3070b57cec5SDimitry Andric   switch (schedtype) {
3080b57cec5SDimitry Andric   case kmp_sch_static: {
3090b57cec5SDimitry Andric     if (trip_count < nth) {
3100b57cec5SDimitry Andric       KMP_DEBUG_ASSERT(
3110b57cec5SDimitry Andric           __kmp_static == kmp_sch_static_greedy ||
3120b57cec5SDimitry Andric           __kmp_static ==
3130b57cec5SDimitry Andric               kmp_sch_static_balanced); // Unknown static scheduling type.
3140b57cec5SDimitry Andric       if (tid < trip_count) {
3150b57cec5SDimitry Andric         *pupper = *plower = *plower + tid * incr;
3160b57cec5SDimitry Andric       } else {
317fe6060f1SDimitry Andric         // set bounds so non-active threads execute no iterations
318fe6060f1SDimitry Andric         *plower = *pupper + (incr > 0 ? 1 : -1);
3190b57cec5SDimitry Andric       }
3200b57cec5SDimitry Andric       if (plastiter != NULL)
3210b57cec5SDimitry Andric         *plastiter = (tid == trip_count - 1);
3220b57cec5SDimitry Andric     } else {
323*0fca6ea1SDimitry Andric       KMP_DEBUG_ASSERT(nth != 0);
3240b57cec5SDimitry Andric       if (__kmp_static == kmp_sch_static_balanced) {
3250b57cec5SDimitry Andric         UT small_chunk = trip_count / nth;
3260b57cec5SDimitry Andric         UT extras = trip_count % nth;
3270b57cec5SDimitry Andric         *plower += incr * (tid * small_chunk + (tid < extras ? tid : extras));
3280b57cec5SDimitry Andric         *pupper = *plower + small_chunk * incr - (tid < extras ? 0 : incr);
3290b57cec5SDimitry Andric         if (plastiter != NULL)
3300b57cec5SDimitry Andric           *plastiter = (tid == nth - 1);
3310b57cec5SDimitry Andric       } else {
3320b57cec5SDimitry Andric         T big_chunk_inc_count =
3330b57cec5SDimitry Andric             (trip_count / nth + ((trip_count % nth) ? 1 : 0)) * incr;
3340b57cec5SDimitry Andric         T old_upper = *pupper;
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy);
3370b57cec5SDimitry Andric         // Unknown static scheduling type.
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric         *plower += tid * big_chunk_inc_count;
3400b57cec5SDimitry Andric         *pupper = *plower + big_chunk_inc_count - incr;
3410b57cec5SDimitry Andric         if (incr > 0) {
3420b57cec5SDimitry Andric           if (*pupper < *plower)
3430b57cec5SDimitry Andric             *pupper = traits_t<T>::max_value;
3440b57cec5SDimitry Andric           if (plastiter != NULL)
3450b57cec5SDimitry Andric             *plastiter = *plower <= old_upper && *pupper > old_upper - incr;
3460b57cec5SDimitry Andric           if (*pupper > old_upper)
3470b57cec5SDimitry Andric             *pupper = old_upper; // tracker C73258
3480b57cec5SDimitry Andric         } else {
3490b57cec5SDimitry Andric           if (*pupper > *plower)
3500b57cec5SDimitry Andric             *pupper = traits_t<T>::min_value;
3510b57cec5SDimitry Andric           if (plastiter != NULL)
3520b57cec5SDimitry Andric             *plastiter = *plower >= old_upper && *pupper < old_upper - incr;
3530b57cec5SDimitry Andric           if (*pupper < old_upper)
3540b57cec5SDimitry Andric             *pupper = old_upper; // tracker C73258
3550b57cec5SDimitry Andric         }
3560b57cec5SDimitry Andric       }
3570b57cec5SDimitry Andric     }
3580b57cec5SDimitry Andric     *pstride = trip_count;
3590b57cec5SDimitry Andric     break;
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric   case kmp_sch_static_chunked: {
3620b57cec5SDimitry Andric     ST span;
363fe6060f1SDimitry Andric     UT nchunks;
364*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(chunk != 0);
365fe6060f1SDimitry Andric     if (chunk < 1)
3660b57cec5SDimitry Andric       chunk = 1;
367fe6060f1SDimitry Andric     else if ((UT)chunk > trip_count)
368fe6060f1SDimitry Andric       chunk = trip_count;
369fe6060f1SDimitry Andric     nchunks = (trip_count) / (UT)chunk + (trip_count % (UT)chunk ? 1 : 0);
3700b57cec5SDimitry Andric     span = chunk * incr;
371fe6060f1SDimitry Andric     if (nchunks < nth) {
372fe6060f1SDimitry Andric       *pstride = span * nchunks;
373fe6060f1SDimitry Andric       if (tid < nchunks) {
374fe6060f1SDimitry Andric         *plower = *plower + (span * tid);
375fe6060f1SDimitry Andric         *pupper = *plower + span - incr;
376fe6060f1SDimitry Andric       } else {
377fe6060f1SDimitry Andric         *plower = *pupper + (incr > 0 ? 1 : -1);
378fe6060f1SDimitry Andric       }
379fe6060f1SDimitry Andric     } else {
3800b57cec5SDimitry Andric       *pstride = span * nth;
3810b57cec5SDimitry Andric       *plower = *plower + (span * tid);
3820b57cec5SDimitry Andric       *pupper = *plower + span - incr;
383fe6060f1SDimitry Andric     }
3840b57cec5SDimitry Andric     if (plastiter != NULL)
385fe6060f1SDimitry Andric       *plastiter = (tid == (nchunks - 1) % nth);
3860b57cec5SDimitry Andric     break;
3870b57cec5SDimitry Andric   }
3880b57cec5SDimitry Andric   case kmp_sch_static_balanced_chunked: {
3890b57cec5SDimitry Andric     T old_upper = *pupper;
390*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(nth != 0);
3910b57cec5SDimitry Andric     // round up to make sure the chunk is enough to cover all iterations
3920b57cec5SDimitry Andric     UT span = (trip_count + nth - 1) / nth;
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric     // perform chunk adjustment
3950b57cec5SDimitry Andric     chunk = (span + chunk - 1) & ~(chunk - 1);
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric     span = chunk * incr;
3980b57cec5SDimitry Andric     *plower = *plower + (span * tid);
3990b57cec5SDimitry Andric     *pupper = *plower + span - incr;
4000b57cec5SDimitry Andric     if (incr > 0) {
4010b57cec5SDimitry Andric       if (*pupper > old_upper)
4020b57cec5SDimitry Andric         *pupper = old_upper;
4030b57cec5SDimitry Andric     } else if (*pupper < old_upper)
4040b57cec5SDimitry Andric       *pupper = old_upper;
4050b57cec5SDimitry Andric 
406*0fca6ea1SDimitry Andric     if (plastiter != NULL) {
407*0fca6ea1SDimitry Andric       KMP_DEBUG_ASSERT(chunk != 0);
4080b57cec5SDimitry Andric       *plastiter = (tid == ((trip_count - 1) / (UT)chunk));
409*0fca6ea1SDimitry Andric     }
4100b57cec5SDimitry Andric     break;
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric   default:
4130b57cec5SDimitry Andric     KMP_ASSERT2(0, "__kmpc_for_static_init: unknown scheduling type");
4140b57cec5SDimitry Andric     break;
4150b57cec5SDimitry Andric   }
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric #if USE_ITT_BUILD
4180b57cec5SDimitry Andric   // Report loop metadata
4190b57cec5SDimitry Andric   if (KMP_MASTER_TID(tid) && __itt_metadata_add_ptr &&
4200b57cec5SDimitry Andric       __kmp_forkjoin_frames_mode == 3 && th->th.th_teams_microtask == NULL &&
4210b57cec5SDimitry Andric       team->t.t_active_level == 1) {
4220b57cec5SDimitry Andric     kmp_uint64 cur_chunk = chunk;
423e8d8bef9SDimitry Andric     check_loc(loc);
4240b57cec5SDimitry Andric     // Calculate chunk in case it was not specified; it is specified for
4250b57cec5SDimitry Andric     // kmp_sch_static_chunked
4260b57cec5SDimitry Andric     if (schedtype == kmp_sch_static) {
427*0fca6ea1SDimitry Andric       KMP_DEBUG_ASSERT(nth != 0);
4280b57cec5SDimitry Andric       cur_chunk = trip_count / nth + ((trip_count % nth) ? 1 : 0);
4290b57cec5SDimitry Andric     }
4300b57cec5SDimitry Andric     // 0 - "static" schedule
4310b57cec5SDimitry Andric     __kmp_itt_metadata_loop(loc, 0, trip_count, cur_chunk);
4320b57cec5SDimitry Andric   }
4330b57cec5SDimitry Andric #endif
4340b57cec5SDimitry Andric #ifdef KMP_DEBUG
4350b57cec5SDimitry Andric   {
4360b57cec5SDimitry Andric     char *buff;
4370b57cec5SDimitry Andric     // create format specifiers before the debug output
4380b57cec5SDimitry Andric     buff = __kmp_str_format("__kmpc_for_static_init: liter=%%d lower=%%%s "
4390b57cec5SDimitry Andric                             "upper=%%%s stride = %%%s signed?<%s>\n",
4400b57cec5SDimitry Andric                             traits_t<T>::spec, traits_t<T>::spec,
4410b57cec5SDimitry Andric                             traits_t<ST>::spec, traits_t<T>::spec);
4420b57cec5SDimitry Andric     KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pstride));
4430b57cec5SDimitry Andric     __kmp_str_free(&buff);
4440b57cec5SDimitry Andric   }
4450b57cec5SDimitry Andric #endif
4460b57cec5SDimitry Andric   KE_TRACE(10, ("__kmpc_for_static_init: T#%d return\n", global_tid));
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
4490b57cec5SDimitry Andric   if (ompt_enabled.ompt_callback_work) {
4500b57cec5SDimitry Andric     ompt_callbacks.ompt_callback(ompt_callback_work)(
4510b57cec5SDimitry Andric         ompt_work_type, ompt_scope_begin, &(team_info->parallel_data),
4520b57cec5SDimitry Andric         &(task_info->task_data), trip_count, codeptr);
4530b57cec5SDimitry Andric   }
45481ad6265SDimitry Andric   if (ompt_enabled.ompt_callback_dispatch) {
45581ad6265SDimitry Andric     ompt_dispatch_t dispatch_type;
45681ad6265SDimitry Andric     ompt_data_t instance = ompt_data_none;
45781ad6265SDimitry Andric     ompt_dispatch_chunk_t dispatch_chunk;
45881ad6265SDimitry Andric     if (ompt_work_type == ompt_work_sections) {
45981ad6265SDimitry Andric       dispatch_type = ompt_dispatch_section;
46081ad6265SDimitry Andric       instance.ptr = codeptr;
46181ad6265SDimitry Andric     } else {
46281ad6265SDimitry Andric       OMPT_GET_DISPATCH_CHUNK(dispatch_chunk, *plower, *pupper, incr);
46381ad6265SDimitry Andric       dispatch_type = (ompt_work_type == ompt_work_distribute)
46481ad6265SDimitry Andric                           ? ompt_dispatch_distribute_chunk
46581ad6265SDimitry Andric                           : ompt_dispatch_ws_loop_chunk;
46681ad6265SDimitry Andric       instance.ptr = &dispatch_chunk;
46781ad6265SDimitry Andric     }
46881ad6265SDimitry Andric     ompt_callbacks.ompt_callback(ompt_callback_dispatch)(
46981ad6265SDimitry Andric         &(team_info->parallel_data), &(task_info->task_data), dispatch_type,
47081ad6265SDimitry Andric         instance);
47181ad6265SDimitry Andric   }
4720b57cec5SDimitry Andric #endif
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric   KMP_STATS_LOOP_END(OMP_loop_static_iterations);
4750b57cec5SDimitry Andric   return;
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric template <typename T>
4790b57cec5SDimitry Andric static void __kmp_dist_for_static_init(ident_t *loc, kmp_int32 gtid,
4800b57cec5SDimitry Andric                                        kmp_int32 schedule, kmp_int32 *plastiter,
4810b57cec5SDimitry Andric                                        T *plower, T *pupper, T *pupperDist,
4820b57cec5SDimitry Andric                                        typename traits_t<T>::signed_t *pstride,
4830b57cec5SDimitry Andric                                        typename traits_t<T>::signed_t incr,
48481ad6265SDimitry Andric                                        typename traits_t<T>::signed_t chunk
48581ad6265SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
48681ad6265SDimitry Andric                                        ,
48781ad6265SDimitry Andric                                        void *codeptr
48881ad6265SDimitry Andric #endif
48981ad6265SDimitry Andric ) {
4900b57cec5SDimitry Andric   KMP_COUNT_BLOCK(OMP_DISTRIBUTE);
4910b57cec5SDimitry Andric   KMP_PUSH_PARTITIONED_TIMER(OMP_distribute);
4920b57cec5SDimitry Andric   KMP_PUSH_PARTITIONED_TIMER(OMP_distribute_scheduling);
4930b57cec5SDimitry Andric   typedef typename traits_t<T>::unsigned_t UT;
4940b57cec5SDimitry Andric   typedef typename traits_t<T>::signed_t ST;
4950b57cec5SDimitry Andric   kmp_uint32 tid;
4960b57cec5SDimitry Andric   kmp_uint32 nth;
4970b57cec5SDimitry Andric   kmp_uint32 team_id;
4980b57cec5SDimitry Andric   kmp_uint32 nteams;
4990b57cec5SDimitry Andric   UT trip_count;
5000b57cec5SDimitry Andric   kmp_team_t *team;
5010b57cec5SDimitry Andric   kmp_info_t *th;
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(plastiter && plower && pupper && pupperDist && pstride);
5040b57cec5SDimitry Andric   KE_TRACE(10, ("__kmpc_dist_for_static_init called (%d)\n", gtid));
505e8d8bef9SDimitry Andric   __kmp_assert_valid_gtid(gtid);
5060b57cec5SDimitry Andric #ifdef KMP_DEBUG
5070b57cec5SDimitry Andric   {
5080b57cec5SDimitry Andric     char *buff;
5090b57cec5SDimitry Andric     // create format specifiers before the debug output
5100b57cec5SDimitry Andric     buff = __kmp_str_format(
5110b57cec5SDimitry Andric         "__kmpc_dist_for_static_init: T#%%d schedLoop=%%d liter=%%d "
5120b57cec5SDimitry Andric         "iter=(%%%s, %%%s, %%%s) chunk=%%%s signed?<%s>\n",
5130b57cec5SDimitry Andric         traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec,
5140b57cec5SDimitry Andric         traits_t<ST>::spec, traits_t<T>::spec);
5150b57cec5SDimitry Andric     KD_TRACE(100,
5160b57cec5SDimitry Andric              (buff, gtid, schedule, *plastiter, *plower, *pupper, incr, chunk));
5170b57cec5SDimitry Andric     __kmp_str_free(&buff);
5180b57cec5SDimitry Andric   }
5190b57cec5SDimitry Andric #endif
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   if (__kmp_env_consistency_check) {
5220b57cec5SDimitry Andric     __kmp_push_workshare(gtid, ct_pdo, loc);
5230b57cec5SDimitry Andric     if (incr == 0) {
5240b57cec5SDimitry Andric       __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo,
5250b57cec5SDimitry Andric                             loc);
5260b57cec5SDimitry Andric     }
5270b57cec5SDimitry Andric     if (incr > 0 ? (*pupper < *plower) : (*plower < *pupper)) {
5280b57cec5SDimitry Andric       // The loop is illegal.
5290b57cec5SDimitry Andric       // Some zero-trip loops maintained by compiler, e.g.:
5300b57cec5SDimitry Andric       //   for(i=10;i<0;++i) // lower >= upper - run-time check
5310b57cec5SDimitry Andric       //   for(i=0;i>10;--i) // lower <= upper - run-time check
5320b57cec5SDimitry Andric       //   for(i=0;i>10;++i) // incr > 0       - compile-time check
5330b57cec5SDimitry Andric       //   for(i=10;i<0;--i) // incr < 0       - compile-time check
5340b57cec5SDimitry Andric       // Compiler does not check the following illegal loops:
5350b57cec5SDimitry Andric       //   for(i=0;i<10;i+=incr) // where incr<0
5360b57cec5SDimitry Andric       //   for(i=10;i>0;i-=incr) // where incr<0
5370b57cec5SDimitry Andric       __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc);
5380b57cec5SDimitry Andric     }
5390b57cec5SDimitry Andric   }
5400b57cec5SDimitry Andric   tid = __kmp_tid_from_gtid(gtid);
5410b57cec5SDimitry Andric   th = __kmp_threads[gtid];
5420b57cec5SDimitry Andric   nth = th->th.th_team_nproc;
5430b57cec5SDimitry Andric   team = th->th.th_team;
5440b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct
5450b57cec5SDimitry Andric   nteams = th->th.th_teams_size.nteams;
5460b57cec5SDimitry Andric   team_id = team->t.t_master_tid;
5470b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(nteams == (kmp_uint32)team->t.t_parent->t.t_nproc);
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   // compute global trip count
5500b57cec5SDimitry Andric   if (incr == 1) {
5510b57cec5SDimitry Andric     trip_count = *pupper - *plower + 1;
5520b57cec5SDimitry Andric   } else if (incr == -1) {
5530b57cec5SDimitry Andric     trip_count = *plower - *pupper + 1;
5540b57cec5SDimitry Andric   } else if (incr > 0) {
5550b57cec5SDimitry Andric     // upper-lower can exceed the limit of signed type
5560b57cec5SDimitry Andric     trip_count = (UT)(*pupper - *plower) / incr + 1;
5570b57cec5SDimitry Andric   } else {
558*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(incr != 0);
5590b57cec5SDimitry Andric     trip_count = (UT)(*plower - *pupper) / (-incr) + 1;
5600b57cec5SDimitry Andric   }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   *pstride = *pupper - *plower; // just in case (can be unused)
5630b57cec5SDimitry Andric   if (trip_count <= nteams) {
5640b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(
5650b57cec5SDimitry Andric         __kmp_static == kmp_sch_static_greedy ||
5660b57cec5SDimitry Andric         __kmp_static ==
5670b57cec5SDimitry Andric             kmp_sch_static_balanced); // Unknown static scheduling type.
568fe6060f1SDimitry Andric     // only primary threads of some teams get single iteration, other threads
569fe6060f1SDimitry Andric     // get nothing
5700b57cec5SDimitry Andric     if (team_id < trip_count && tid == 0) {
5710b57cec5SDimitry Andric       *pupper = *pupperDist = *plower = *plower + team_id * incr;
5720b57cec5SDimitry Andric     } else {
5730b57cec5SDimitry Andric       *pupperDist = *pupper;
5740b57cec5SDimitry Andric       *plower = *pupper + incr; // compiler should skip loop body
5750b57cec5SDimitry Andric     }
5760b57cec5SDimitry Andric     if (plastiter != NULL)
5770b57cec5SDimitry Andric       *plastiter = (tid == 0 && team_id == trip_count - 1);
5780b57cec5SDimitry Andric   } else {
5790b57cec5SDimitry Andric     // Get the team's chunk first (each team gets at most one chunk)
580*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(nteams != 0);
5810b57cec5SDimitry Andric     if (__kmp_static == kmp_sch_static_balanced) {
5820b57cec5SDimitry Andric       UT chunkD = trip_count / nteams;
5830b57cec5SDimitry Andric       UT extras = trip_count % nteams;
5840b57cec5SDimitry Andric       *plower +=
5850b57cec5SDimitry Andric           incr * (team_id * chunkD + (team_id < extras ? team_id : extras));
5860b57cec5SDimitry Andric       *pupperDist = *plower + chunkD * incr - (team_id < extras ? 0 : incr);
5870b57cec5SDimitry Andric       if (plastiter != NULL)
5880b57cec5SDimitry Andric         *plastiter = (team_id == nteams - 1);
5890b57cec5SDimitry Andric     } else {
5900b57cec5SDimitry Andric       T chunk_inc_count =
5910b57cec5SDimitry Andric           (trip_count / nteams + ((trip_count % nteams) ? 1 : 0)) * incr;
5920b57cec5SDimitry Andric       T upper = *pupper;
5930b57cec5SDimitry Andric       KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy);
5940b57cec5SDimitry Andric       // Unknown static scheduling type.
5950b57cec5SDimitry Andric       *plower += team_id * chunk_inc_count;
5960b57cec5SDimitry Andric       *pupperDist = *plower + chunk_inc_count - incr;
5970b57cec5SDimitry Andric       // Check/correct bounds if needed
5980b57cec5SDimitry Andric       if (incr > 0) {
5990b57cec5SDimitry Andric         if (*pupperDist < *plower)
6000b57cec5SDimitry Andric           *pupperDist = traits_t<T>::max_value;
6010b57cec5SDimitry Andric         if (plastiter != NULL)
6020b57cec5SDimitry Andric           *plastiter = *plower <= upper && *pupperDist > upper - incr;
6030b57cec5SDimitry Andric         if (*pupperDist > upper)
6040b57cec5SDimitry Andric           *pupperDist = upper; // tracker C73258
6050b57cec5SDimitry Andric         if (*plower > *pupperDist) {
6060b57cec5SDimitry Andric           *pupper = *pupperDist; // no iterations available for the team
6070b57cec5SDimitry Andric           goto end;
6080b57cec5SDimitry Andric         }
6090b57cec5SDimitry Andric       } else {
6100b57cec5SDimitry Andric         if (*pupperDist > *plower)
6110b57cec5SDimitry Andric           *pupperDist = traits_t<T>::min_value;
6120b57cec5SDimitry Andric         if (plastiter != NULL)
6130b57cec5SDimitry Andric           *plastiter = *plower >= upper && *pupperDist < upper - incr;
6140b57cec5SDimitry Andric         if (*pupperDist < upper)
6150b57cec5SDimitry Andric           *pupperDist = upper; // tracker C73258
6160b57cec5SDimitry Andric         if (*plower < *pupperDist) {
6170b57cec5SDimitry Andric           *pupper = *pupperDist; // no iterations available for the team
6180b57cec5SDimitry Andric           goto end;
6190b57cec5SDimitry Andric         }
6200b57cec5SDimitry Andric       }
6210b57cec5SDimitry Andric     }
6220b57cec5SDimitry Andric     // Get the parallel loop chunk now (for thread)
6230b57cec5SDimitry Andric     // compute trip count for team's chunk
6240b57cec5SDimitry Andric     if (incr == 1) {
6250b57cec5SDimitry Andric       trip_count = *pupperDist - *plower + 1;
6260b57cec5SDimitry Andric     } else if (incr == -1) {
6270b57cec5SDimitry Andric       trip_count = *plower - *pupperDist + 1;
6280b57cec5SDimitry Andric     } else if (incr > 1) {
6290b57cec5SDimitry Andric       // upper-lower can exceed the limit of signed type
6300b57cec5SDimitry Andric       trip_count = (UT)(*pupperDist - *plower) / incr + 1;
6310b57cec5SDimitry Andric     } else {
632*0fca6ea1SDimitry Andric       KMP_DEBUG_ASSERT(incr != 0);
6330b57cec5SDimitry Andric       trip_count = (UT)(*plower - *pupperDist) / (-incr) + 1;
6340b57cec5SDimitry Andric     }
6350b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(trip_count);
6360b57cec5SDimitry Andric     switch (schedule) {
6370b57cec5SDimitry Andric     case kmp_sch_static: {
6380b57cec5SDimitry Andric       if (trip_count <= nth) {
6390b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(
6400b57cec5SDimitry Andric             __kmp_static == kmp_sch_static_greedy ||
6410b57cec5SDimitry Andric             __kmp_static ==
6420b57cec5SDimitry Andric                 kmp_sch_static_balanced); // Unknown static scheduling type.
6430b57cec5SDimitry Andric         if (tid < trip_count)
6440b57cec5SDimitry Andric           *pupper = *plower = *plower + tid * incr;
6450b57cec5SDimitry Andric         else
6460b57cec5SDimitry Andric           *plower = *pupper + incr; // no iterations available
6470b57cec5SDimitry Andric         if (plastiter != NULL)
6480b57cec5SDimitry Andric           if (*plastiter != 0 && !(tid == trip_count - 1))
6490b57cec5SDimitry Andric             *plastiter = 0;
6500b57cec5SDimitry Andric       } else {
651*0fca6ea1SDimitry Andric         KMP_DEBUG_ASSERT(nth != 0);
6520b57cec5SDimitry Andric         if (__kmp_static == kmp_sch_static_balanced) {
6530b57cec5SDimitry Andric           UT chunkL = trip_count / nth;
6540b57cec5SDimitry Andric           UT extras = trip_count % nth;
6550b57cec5SDimitry Andric           *plower += incr * (tid * chunkL + (tid < extras ? tid : extras));
6560b57cec5SDimitry Andric           *pupper = *plower + chunkL * incr - (tid < extras ? 0 : incr);
6570b57cec5SDimitry Andric           if (plastiter != NULL)
6580b57cec5SDimitry Andric             if (*plastiter != 0 && !(tid == nth - 1))
6590b57cec5SDimitry Andric               *plastiter = 0;
6600b57cec5SDimitry Andric         } else {
6610b57cec5SDimitry Andric           T chunk_inc_count =
6620b57cec5SDimitry Andric               (trip_count / nth + ((trip_count % nth) ? 1 : 0)) * incr;
6630b57cec5SDimitry Andric           T upper = *pupperDist;
6640b57cec5SDimitry Andric           KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy);
6650b57cec5SDimitry Andric           // Unknown static scheduling type.
6660b57cec5SDimitry Andric           *plower += tid * chunk_inc_count;
6670b57cec5SDimitry Andric           *pupper = *plower + chunk_inc_count - incr;
6680b57cec5SDimitry Andric           if (incr > 0) {
6690b57cec5SDimitry Andric             if (*pupper < *plower)
6700b57cec5SDimitry Andric               *pupper = traits_t<T>::max_value;
6710b57cec5SDimitry Andric             if (plastiter != NULL)
6720b57cec5SDimitry Andric               if (*plastiter != 0 &&
6730b57cec5SDimitry Andric                   !(*plower <= upper && *pupper > upper - incr))
6740b57cec5SDimitry Andric                 *plastiter = 0;
6750b57cec5SDimitry Andric             if (*pupper > upper)
6760b57cec5SDimitry Andric               *pupper = upper; // tracker C73258
6770b57cec5SDimitry Andric           } else {
6780b57cec5SDimitry Andric             if (*pupper > *plower)
6790b57cec5SDimitry Andric               *pupper = traits_t<T>::min_value;
6800b57cec5SDimitry Andric             if (plastiter != NULL)
6810b57cec5SDimitry Andric               if (*plastiter != 0 &&
6820b57cec5SDimitry Andric                   !(*plower >= upper && *pupper < upper - incr))
6830b57cec5SDimitry Andric                 *plastiter = 0;
6840b57cec5SDimitry Andric             if (*pupper < upper)
6850b57cec5SDimitry Andric               *pupper = upper; // tracker C73258
6860b57cec5SDimitry Andric           }
6870b57cec5SDimitry Andric         }
6880b57cec5SDimitry Andric       }
6890b57cec5SDimitry Andric       break;
6900b57cec5SDimitry Andric     }
6910b57cec5SDimitry Andric     case kmp_sch_static_chunked: {
6920b57cec5SDimitry Andric       ST span;
6930b57cec5SDimitry Andric       if (chunk < 1)
6940b57cec5SDimitry Andric         chunk = 1;
6950b57cec5SDimitry Andric       span = chunk * incr;
6960b57cec5SDimitry Andric       *pstride = span * nth;
6970b57cec5SDimitry Andric       *plower = *plower + (span * tid);
6980b57cec5SDimitry Andric       *pupper = *plower + span - incr;
699*0fca6ea1SDimitry Andric       if (plastiter != NULL) {
700*0fca6ea1SDimitry Andric         KMP_DEBUG_ASSERT(chunk != 0);
7010b57cec5SDimitry Andric         if (*plastiter != 0 && !(tid == ((trip_count - 1) / (UT)chunk) % nth))
7020b57cec5SDimitry Andric           *plastiter = 0;
703*0fca6ea1SDimitry Andric       }
7040b57cec5SDimitry Andric       break;
7050b57cec5SDimitry Andric     }
7060b57cec5SDimitry Andric     default:
7070b57cec5SDimitry Andric       KMP_ASSERT2(0,
7080b57cec5SDimitry Andric                   "__kmpc_dist_for_static_init: unknown loop scheduling type");
7090b57cec5SDimitry Andric       break;
7100b57cec5SDimitry Andric     }
7110b57cec5SDimitry Andric   }
7120b57cec5SDimitry Andric end:;
7130b57cec5SDimitry Andric #ifdef KMP_DEBUG
7140b57cec5SDimitry Andric   {
7150b57cec5SDimitry Andric     char *buff;
7160b57cec5SDimitry Andric     // create format specifiers before the debug output
7170b57cec5SDimitry Andric     buff = __kmp_str_format(
7180b57cec5SDimitry Andric         "__kmpc_dist_for_static_init: last=%%d lo=%%%s up=%%%s upDist=%%%s "
7190b57cec5SDimitry Andric         "stride=%%%s signed?<%s>\n",
7200b57cec5SDimitry Andric         traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec,
7210b57cec5SDimitry Andric         traits_t<ST>::spec, traits_t<T>::spec);
7220b57cec5SDimitry Andric     KD_TRACE(100, (buff, *plastiter, *plower, *pupper, *pupperDist, *pstride));
7230b57cec5SDimitry Andric     __kmp_str_free(&buff);
7240b57cec5SDimitry Andric   }
7250b57cec5SDimitry Andric #endif
7260b57cec5SDimitry Andric   KE_TRACE(10, ("__kmpc_dist_for_static_init: T#%d return\n", gtid));
72781ad6265SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
72881ad6265SDimitry Andric   if (ompt_enabled.ompt_callback_work || ompt_enabled.ompt_callback_dispatch) {
72981ad6265SDimitry Andric     ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
73081ad6265SDimitry Andric     ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
73181ad6265SDimitry Andric     if (ompt_enabled.ompt_callback_work) {
73281ad6265SDimitry Andric       ompt_callbacks.ompt_callback(ompt_callback_work)(
73381ad6265SDimitry Andric           ompt_work_distribute, ompt_scope_begin, &(team_info->parallel_data),
73481ad6265SDimitry Andric           &(task_info->task_data), 0, codeptr);
73581ad6265SDimitry Andric     }
73681ad6265SDimitry Andric     if (ompt_enabled.ompt_callback_dispatch) {
73781ad6265SDimitry Andric       ompt_data_t instance = ompt_data_none;
73881ad6265SDimitry Andric       ompt_dispatch_chunk_t dispatch_chunk;
73981ad6265SDimitry Andric       OMPT_GET_DISPATCH_CHUNK(dispatch_chunk, *plower, *pupperDist, incr);
74081ad6265SDimitry Andric       instance.ptr = &dispatch_chunk;
74181ad6265SDimitry Andric       ompt_callbacks.ompt_callback(ompt_callback_dispatch)(
74281ad6265SDimitry Andric           &(team_info->parallel_data), &(task_info->task_data),
74381ad6265SDimitry Andric           ompt_dispatch_distribute_chunk, instance);
74481ad6265SDimitry Andric     }
74581ad6265SDimitry Andric   }
74681ad6265SDimitry Andric #endif // OMPT_SUPPORT && OMPT_OPTIONAL
7470b57cec5SDimitry Andric   KMP_STATS_LOOP_END(OMP_distribute_iterations);
7480b57cec5SDimitry Andric   return;
7490b57cec5SDimitry Andric }
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric template <typename T>
7520b57cec5SDimitry Andric static void __kmp_team_static_init(ident_t *loc, kmp_int32 gtid,
7530b57cec5SDimitry Andric                                    kmp_int32 *p_last, T *p_lb, T *p_ub,
7540b57cec5SDimitry Andric                                    typename traits_t<T>::signed_t *p_st,
7550b57cec5SDimitry Andric                                    typename traits_t<T>::signed_t incr,
7560b57cec5SDimitry Andric                                    typename traits_t<T>::signed_t chunk) {
7570b57cec5SDimitry Andric   // The routine returns the first chunk distributed to the team and
7580b57cec5SDimitry Andric   // stride for next chunks calculation.
7590b57cec5SDimitry Andric   // Last iteration flag set for the team that will execute
7600b57cec5SDimitry Andric   // the last iteration of the loop.
7615ffd83dbSDimitry Andric   // The routine is called for dist_schedule(static,chunk) only.
7620b57cec5SDimitry Andric   typedef typename traits_t<T>::unsigned_t UT;
7630b57cec5SDimitry Andric   typedef typename traits_t<T>::signed_t ST;
7640b57cec5SDimitry Andric   kmp_uint32 team_id;
7650b57cec5SDimitry Andric   kmp_uint32 nteams;
7660b57cec5SDimitry Andric   UT trip_count;
7670b57cec5SDimitry Andric   T lower;
7680b57cec5SDimitry Andric   T upper;
7690b57cec5SDimitry Andric   ST span;
7700b57cec5SDimitry Andric   kmp_team_t *team;
7710b57cec5SDimitry Andric   kmp_info_t *th;
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(p_last && p_lb && p_ub && p_st);
7740b57cec5SDimitry Andric   KE_TRACE(10, ("__kmp_team_static_init called (%d)\n", gtid));
775e8d8bef9SDimitry Andric   __kmp_assert_valid_gtid(gtid);
7760b57cec5SDimitry Andric #ifdef KMP_DEBUG
7770b57cec5SDimitry Andric   {
7780b57cec5SDimitry Andric     char *buff;
7790b57cec5SDimitry Andric     // create format specifiers before the debug output
7800b57cec5SDimitry Andric     buff = __kmp_str_format("__kmp_team_static_init enter: T#%%d liter=%%d "
7810b57cec5SDimitry Andric                             "iter=(%%%s, %%%s, %%%s) chunk %%%s; signed?<%s>\n",
7820b57cec5SDimitry Andric                             traits_t<T>::spec, traits_t<T>::spec,
7830b57cec5SDimitry Andric                             traits_t<ST>::spec, traits_t<ST>::spec,
7840b57cec5SDimitry Andric                             traits_t<T>::spec);
7850b57cec5SDimitry Andric     KD_TRACE(100, (buff, gtid, *p_last, *p_lb, *p_ub, *p_st, chunk));
7860b57cec5SDimitry Andric     __kmp_str_free(&buff);
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric #endif
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric   lower = *p_lb;
7910b57cec5SDimitry Andric   upper = *p_ub;
7920b57cec5SDimitry Andric   if (__kmp_env_consistency_check) {
7930b57cec5SDimitry Andric     if (incr == 0) {
7940b57cec5SDimitry Andric       __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo,
7950b57cec5SDimitry Andric                             loc);
7960b57cec5SDimitry Andric     }
7970b57cec5SDimitry Andric     if (incr > 0 ? (upper < lower) : (lower < upper)) {
7980b57cec5SDimitry Andric       // The loop is illegal.
7990b57cec5SDimitry Andric       // Some zero-trip loops maintained by compiler, e.g.:
8000b57cec5SDimitry Andric       //   for(i=10;i<0;++i) // lower >= upper - run-time check
8010b57cec5SDimitry Andric       //   for(i=0;i>10;--i) // lower <= upper - run-time check
8020b57cec5SDimitry Andric       //   for(i=0;i>10;++i) // incr > 0       - compile-time check
8030b57cec5SDimitry Andric       //   for(i=10;i<0;--i) // incr < 0       - compile-time check
8040b57cec5SDimitry Andric       // Compiler does not check the following illegal loops:
8050b57cec5SDimitry Andric       //   for(i=0;i<10;i+=incr) // where incr<0
8060b57cec5SDimitry Andric       //   for(i=10;i>0;i-=incr) // where incr<0
8070b57cec5SDimitry Andric       __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc);
8080b57cec5SDimitry Andric     }
8090b57cec5SDimitry Andric   }
8100b57cec5SDimitry Andric   th = __kmp_threads[gtid];
8110b57cec5SDimitry Andric   team = th->th.th_team;
8120b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct
8130b57cec5SDimitry Andric   nteams = th->th.th_teams_size.nteams;
8140b57cec5SDimitry Andric   team_id = team->t.t_master_tid;
8150b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(nteams == (kmp_uint32)team->t.t_parent->t.t_nproc);
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric   // compute trip count
8180b57cec5SDimitry Andric   if (incr == 1) {
8190b57cec5SDimitry Andric     trip_count = upper - lower + 1;
8200b57cec5SDimitry Andric   } else if (incr == -1) {
8210b57cec5SDimitry Andric     trip_count = lower - upper + 1;
8220b57cec5SDimitry Andric   } else if (incr > 0) {
8230b57cec5SDimitry Andric     // upper-lower can exceed the limit of signed type
8240b57cec5SDimitry Andric     trip_count = (UT)(upper - lower) / incr + 1;
8250b57cec5SDimitry Andric   } else {
826*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(incr != 0);
8270b57cec5SDimitry Andric     trip_count = (UT)(lower - upper) / (-incr) + 1;
8280b57cec5SDimitry Andric   }
8290b57cec5SDimitry Andric   if (chunk < 1)
8300b57cec5SDimitry Andric     chunk = 1;
8310b57cec5SDimitry Andric   span = chunk * incr;
8320b57cec5SDimitry Andric   *p_st = span * nteams;
8330b57cec5SDimitry Andric   *p_lb = lower + (span * team_id);
8340b57cec5SDimitry Andric   *p_ub = *p_lb + span - incr;
835*0fca6ea1SDimitry Andric   if (p_last != NULL) {
836*0fca6ea1SDimitry Andric     KMP_DEBUG_ASSERT(chunk != 0);
8370b57cec5SDimitry Andric     *p_last = (team_id == ((trip_count - 1) / (UT)chunk) % nteams);
838*0fca6ea1SDimitry Andric   }
8390b57cec5SDimitry Andric   // Correct upper bound if needed
8400b57cec5SDimitry Andric   if (incr > 0) {
8410b57cec5SDimitry Andric     if (*p_ub < *p_lb) // overflow?
8420b57cec5SDimitry Andric       *p_ub = traits_t<T>::max_value;
8430b57cec5SDimitry Andric     if (*p_ub > upper)
8440b57cec5SDimitry Andric       *p_ub = upper; // tracker C73258
8450b57cec5SDimitry Andric   } else { // incr < 0
8460b57cec5SDimitry Andric     if (*p_ub > *p_lb)
8470b57cec5SDimitry Andric       *p_ub = traits_t<T>::min_value;
8480b57cec5SDimitry Andric     if (*p_ub < upper)
8490b57cec5SDimitry Andric       *p_ub = upper; // tracker C73258
8500b57cec5SDimitry Andric   }
8510b57cec5SDimitry Andric #ifdef KMP_DEBUG
8520b57cec5SDimitry Andric   {
8530b57cec5SDimitry Andric     char *buff;
8540b57cec5SDimitry Andric     // create format specifiers before the debug output
8550b57cec5SDimitry Andric     buff =
8560b57cec5SDimitry Andric         __kmp_str_format("__kmp_team_static_init exit: T#%%d team%%u liter=%%d "
8570b57cec5SDimitry Andric                          "iter=(%%%s, %%%s, %%%s) chunk %%%s\n",
8580b57cec5SDimitry Andric                          traits_t<T>::spec, traits_t<T>::spec,
8590b57cec5SDimitry Andric                          traits_t<ST>::spec, traits_t<ST>::spec);
8600b57cec5SDimitry Andric     KD_TRACE(100, (buff, gtid, team_id, *p_last, *p_lb, *p_ub, *p_st, chunk));
8610b57cec5SDimitry Andric     __kmp_str_free(&buff);
8620b57cec5SDimitry Andric   }
8630b57cec5SDimitry Andric #endif
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric //------------------------------------------------------------------------------
8670b57cec5SDimitry Andric extern "C" {
8680b57cec5SDimitry Andric /*!
8690b57cec5SDimitry Andric @ingroup WORK_SHARING
8700b57cec5SDimitry Andric @param    loc       Source code location
8710b57cec5SDimitry Andric @param    gtid      Global thread id of this thread
8720b57cec5SDimitry Andric @param    schedtype  Scheduling type
8730b57cec5SDimitry Andric @param    plastiter Pointer to the "last iteration" flag
8740b57cec5SDimitry Andric @param    plower    Pointer to the lower bound
8750b57cec5SDimitry Andric @param    pupper    Pointer to the upper bound
8760b57cec5SDimitry Andric @param    pstride   Pointer to the stride
8770b57cec5SDimitry Andric @param    incr      Loop increment
8780b57cec5SDimitry Andric @param    chunk     The chunk size
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric Each of the four functions here are identical apart from the argument types.
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric The functions compute the upper and lower bounds and stride to be used for the
8830b57cec5SDimitry Andric set of iterations to be executed by the current thread from the statically
8840b57cec5SDimitry Andric scheduled loop that is described by the initial values of the bounds, stride,
8850b57cec5SDimitry Andric increment and chunk size.
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric @{
8880b57cec5SDimitry Andric */
8890b57cec5SDimitry Andric void __kmpc_for_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype,
8900b57cec5SDimitry Andric                               kmp_int32 *plastiter, kmp_int32 *plower,
8910b57cec5SDimitry Andric                               kmp_int32 *pupper, kmp_int32 *pstride,
8920b57cec5SDimitry Andric                               kmp_int32 incr, kmp_int32 chunk) {
8930b57cec5SDimitry Andric   __kmp_for_static_init<kmp_int32>(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_4u(ident_t *loc, kmp_int32 gtid,
9060b57cec5SDimitry Andric                                kmp_int32 schedtype, kmp_int32 *plastiter,
9070b57cec5SDimitry Andric                                kmp_uint32 *plower, kmp_uint32 *pupper,
9080b57cec5SDimitry Andric                                kmp_int32 *pstride, kmp_int32 incr,
9090b57cec5SDimitry Andric                                kmp_int32 chunk) {
9100b57cec5SDimitry Andric   __kmp_for_static_init<kmp_uint32>(loc, gtid, schedtype, plastiter, plower,
9110b57cec5SDimitry Andric                                     pupper, pstride, incr, chunk
9120b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
9130b57cec5SDimitry Andric                                     ,
9140b57cec5SDimitry Andric                                     OMPT_GET_RETURN_ADDRESS(0)
9150b57cec5SDimitry Andric #endif
9160b57cec5SDimitry Andric   );
9170b57cec5SDimitry Andric }
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric /*!
9200b57cec5SDimitry Andric  See @ref __kmpc_for_static_init_4
9210b57cec5SDimitry Andric  */
9220b57cec5SDimitry Andric void __kmpc_for_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype,
9230b57cec5SDimitry Andric                               kmp_int32 *plastiter, kmp_int64 *plower,
9240b57cec5SDimitry Andric                               kmp_int64 *pupper, kmp_int64 *pstride,
9250b57cec5SDimitry Andric                               kmp_int64 incr, kmp_int64 chunk) {
9260b57cec5SDimitry Andric   __kmp_for_static_init<kmp_int64>(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  See @ref __kmpc_for_static_init_4
9370b57cec5SDimitry Andric  */
9380b57cec5SDimitry Andric void __kmpc_for_static_init_8u(ident_t *loc, kmp_int32 gtid,
9390b57cec5SDimitry Andric                                kmp_int32 schedtype, kmp_int32 *plastiter,
9400b57cec5SDimitry Andric                                kmp_uint64 *plower, kmp_uint64 *pupper,
9410b57cec5SDimitry Andric                                kmp_int64 *pstride, kmp_int64 incr,
9420b57cec5SDimitry Andric                                kmp_int64 chunk) {
9430b57cec5SDimitry Andric   __kmp_for_static_init<kmp_uint64>(loc, gtid, schedtype, plastiter, plower,
9440b57cec5SDimitry Andric                                     pupper, pstride, incr, chunk
9450b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
9460b57cec5SDimitry Andric                                     ,
9470b57cec5SDimitry Andric                                     OMPT_GET_RETURN_ADDRESS(0)
9480b57cec5SDimitry Andric #endif
9490b57cec5SDimitry Andric   );
9500b57cec5SDimitry Andric }
9510b57cec5SDimitry Andric /*!
9520b57cec5SDimitry Andric @}
9530b57cec5SDimitry Andric */
9540b57cec5SDimitry Andric 
95581ad6265SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
95681ad6265SDimitry Andric #define OMPT_CODEPTR_ARG , OMPT_GET_RETURN_ADDRESS(0)
95781ad6265SDimitry Andric #else
95881ad6265SDimitry Andric #define OMPT_CODEPTR_ARG
95981ad6265SDimitry Andric #endif
96081ad6265SDimitry Andric 
9610b57cec5SDimitry Andric /*!
9620b57cec5SDimitry Andric @ingroup WORK_SHARING
9630b57cec5SDimitry Andric @param    loc       Source code location
9640b57cec5SDimitry Andric @param    gtid      Global thread id of this thread
9650b57cec5SDimitry Andric @param    schedule  Scheduling type for the parallel loop
9660b57cec5SDimitry Andric @param    plastiter Pointer to the "last iteration" flag
9670b57cec5SDimitry Andric @param    plower    Pointer to the lower bound
9680b57cec5SDimitry Andric @param    pupper    Pointer to the upper bound of loop chunk
9690b57cec5SDimitry Andric @param    pupperD   Pointer to the upper bound of dist_chunk
9700b57cec5SDimitry Andric @param    pstride   Pointer to the stride for parallel loop
9710b57cec5SDimitry Andric @param    incr      Loop increment
9720b57cec5SDimitry Andric @param    chunk     The chunk size for the parallel loop
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric Each of the four functions here are identical apart from the argument types.
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric The functions compute the upper and lower bounds and strides to be used for the
9770b57cec5SDimitry Andric set of iterations to be executed by the current thread from the statically
9780b57cec5SDimitry Andric scheduled loop that is described by the initial values of the bounds, strides,
9790b57cec5SDimitry Andric increment and chunks for parallel loop and distribute constructs.
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric @{
9820b57cec5SDimitry Andric */
9830b57cec5SDimitry Andric void __kmpc_dist_for_static_init_4(ident_t *loc, kmp_int32 gtid,
9840b57cec5SDimitry Andric                                    kmp_int32 schedule, kmp_int32 *plastiter,
9850b57cec5SDimitry Andric                                    kmp_int32 *plower, kmp_int32 *pupper,
9860b57cec5SDimitry Andric                                    kmp_int32 *pupperD, kmp_int32 *pstride,
9870b57cec5SDimitry Andric                                    kmp_int32 incr, kmp_int32 chunk) {
9880b57cec5SDimitry Andric   __kmp_dist_for_static_init<kmp_int32>(loc, gtid, schedule, plastiter, plower,
98981ad6265SDimitry Andric                                         pupper, pupperD, pstride, incr,
99081ad6265SDimitry Andric                                         chunk OMPT_CODEPTR_ARG);
9910b57cec5SDimitry Andric }
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric /*!
9940b57cec5SDimitry Andric  See @ref __kmpc_dist_for_static_init_4
9950b57cec5SDimitry Andric  */
9960b57cec5SDimitry Andric void __kmpc_dist_for_static_init_4u(ident_t *loc, kmp_int32 gtid,
9970b57cec5SDimitry Andric                                     kmp_int32 schedule, kmp_int32 *plastiter,
9980b57cec5SDimitry Andric                                     kmp_uint32 *plower, kmp_uint32 *pupper,
9990b57cec5SDimitry Andric                                     kmp_uint32 *pupperD, kmp_int32 *pstride,
10000b57cec5SDimitry Andric                                     kmp_int32 incr, kmp_int32 chunk) {
10010b57cec5SDimitry Andric   __kmp_dist_for_static_init<kmp_uint32>(loc, gtid, schedule, plastiter, plower,
100281ad6265SDimitry Andric                                          pupper, pupperD, pstride, incr,
100381ad6265SDimitry Andric                                          chunk OMPT_CODEPTR_ARG);
10040b57cec5SDimitry Andric }
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric /*!
10070b57cec5SDimitry Andric  See @ref __kmpc_dist_for_static_init_4
10080b57cec5SDimitry Andric  */
10090b57cec5SDimitry Andric void __kmpc_dist_for_static_init_8(ident_t *loc, kmp_int32 gtid,
10100b57cec5SDimitry Andric                                    kmp_int32 schedule, kmp_int32 *plastiter,
10110b57cec5SDimitry Andric                                    kmp_int64 *plower, kmp_int64 *pupper,
10120b57cec5SDimitry Andric                                    kmp_int64 *pupperD, kmp_int64 *pstride,
10130b57cec5SDimitry Andric                                    kmp_int64 incr, kmp_int64 chunk) {
10140b57cec5SDimitry Andric   __kmp_dist_for_static_init<kmp_int64>(loc, gtid, schedule, plastiter, plower,
101581ad6265SDimitry Andric                                         pupper, pupperD, pstride, incr,
101681ad6265SDimitry Andric                                         chunk OMPT_CODEPTR_ARG);
10170b57cec5SDimitry Andric }
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric /*!
10200b57cec5SDimitry Andric  See @ref __kmpc_dist_for_static_init_4
10210b57cec5SDimitry Andric  */
10220b57cec5SDimitry Andric void __kmpc_dist_for_static_init_8u(ident_t *loc, kmp_int32 gtid,
10230b57cec5SDimitry Andric                                     kmp_int32 schedule, kmp_int32 *plastiter,
10240b57cec5SDimitry Andric                                     kmp_uint64 *plower, kmp_uint64 *pupper,
10250b57cec5SDimitry Andric                                     kmp_uint64 *pupperD, kmp_int64 *pstride,
10260b57cec5SDimitry Andric                                     kmp_int64 incr, kmp_int64 chunk) {
10270b57cec5SDimitry Andric   __kmp_dist_for_static_init<kmp_uint64>(loc, gtid, schedule, plastiter, plower,
102881ad6265SDimitry Andric                                          pupper, pupperD, pstride, incr,
102981ad6265SDimitry Andric                                          chunk OMPT_CODEPTR_ARG);
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric /*!
10320b57cec5SDimitry Andric @}
10330b57cec5SDimitry Andric */
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric //------------------------------------------------------------------------------
10360b57cec5SDimitry Andric // Auxiliary routines for Distribute Parallel Loop construct implementation
10370b57cec5SDimitry Andric //    Transfer call to template< type T >
10380b57cec5SDimitry Andric //    __kmp_team_static_init( ident_t *loc, int gtid,
10390b57cec5SDimitry Andric //        int *p_last, T *lb, T *ub, ST *st, ST incr, ST chunk )
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric /*!
10420b57cec5SDimitry Andric @ingroup WORK_SHARING
10430b57cec5SDimitry Andric @{
10440b57cec5SDimitry Andric @param loc Source location
10450b57cec5SDimitry Andric @param gtid Global thread id
10460b57cec5SDimitry Andric @param p_last pointer to last iteration flag
10470b57cec5SDimitry Andric @param p_lb  pointer to Lower bound
10480b57cec5SDimitry Andric @param p_ub  pointer to Upper bound
10490b57cec5SDimitry Andric @param p_st  Step (or increment if you prefer)
10500b57cec5SDimitry Andric @param incr  Loop increment
10510b57cec5SDimitry Andric @param chunk The chunk size to block with
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric The functions compute the upper and lower bounds and stride to be used for the
10540b57cec5SDimitry Andric set of iterations to be executed by the current team from the statically
10550b57cec5SDimitry Andric scheduled loop that is described by the initial values of the bounds, stride,
10560b57cec5SDimitry Andric increment and chunk for the distribute construct as part of composite distribute
10570b57cec5SDimitry Andric parallel loop construct. These functions are all identical apart from the types
10580b57cec5SDimitry Andric of the arguments.
10590b57cec5SDimitry Andric */
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric void __kmpc_team_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
10620b57cec5SDimitry Andric                                kmp_int32 *p_lb, kmp_int32 *p_ub,
10630b57cec5SDimitry Andric                                kmp_int32 *p_st, kmp_int32 incr,
10640b57cec5SDimitry Andric                                kmp_int32 chunk) {
10650b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(__kmp_init_serial);
10660b57cec5SDimitry Andric   __kmp_team_static_init<kmp_int32>(loc, gtid, p_last, p_lb, p_ub, p_st, incr,
10670b57cec5SDimitry Andric                                     chunk);
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric /*!
10710b57cec5SDimitry Andric  See @ref __kmpc_team_static_init_4
10720b57cec5SDimitry Andric  */
10730b57cec5SDimitry Andric void __kmpc_team_static_init_4u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
10740b57cec5SDimitry Andric                                 kmp_uint32 *p_lb, kmp_uint32 *p_ub,
10750b57cec5SDimitry Andric                                 kmp_int32 *p_st, kmp_int32 incr,
10760b57cec5SDimitry Andric                                 kmp_int32 chunk) {
10770b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(__kmp_init_serial);
10780b57cec5SDimitry Andric   __kmp_team_static_init<kmp_uint32>(loc, gtid, p_last, p_lb, p_ub, p_st, incr,
10790b57cec5SDimitry Andric                                      chunk);
10800b57cec5SDimitry Andric }
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric /*!
10830b57cec5SDimitry Andric  See @ref __kmpc_team_static_init_4
10840b57cec5SDimitry Andric  */
10850b57cec5SDimitry Andric void __kmpc_team_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
10860b57cec5SDimitry Andric                                kmp_int64 *p_lb, kmp_int64 *p_ub,
10870b57cec5SDimitry Andric                                kmp_int64 *p_st, kmp_int64 incr,
10880b57cec5SDimitry Andric                                kmp_int64 chunk) {
10890b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(__kmp_init_serial);
10900b57cec5SDimitry Andric   __kmp_team_static_init<kmp_int64>(loc, gtid, p_last, p_lb, p_ub, p_st, incr,
10910b57cec5SDimitry Andric                                     chunk);
10920b57cec5SDimitry Andric }
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric /*!
10950b57cec5SDimitry Andric  See @ref __kmpc_team_static_init_4
10960b57cec5SDimitry Andric  */
10970b57cec5SDimitry Andric void __kmpc_team_static_init_8u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
10980b57cec5SDimitry Andric                                 kmp_uint64 *p_lb, kmp_uint64 *p_ub,
10990b57cec5SDimitry Andric                                 kmp_int64 *p_st, kmp_int64 incr,
11000b57cec5SDimitry Andric                                 kmp_int64 chunk) {
11010b57cec5SDimitry Andric   KMP_DEBUG_ASSERT(__kmp_init_serial);
11020b57cec5SDimitry Andric   __kmp_team_static_init<kmp_uint64>(loc, gtid, p_last, p_lb, p_ub, p_st, incr,
11030b57cec5SDimitry Andric                                      chunk);
11040b57cec5SDimitry Andric }
11050b57cec5SDimitry Andric /*!
11060b57cec5SDimitry Andric @}
11070b57cec5SDimitry Andric */
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric } // extern "C"
1110