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