Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Modules Pages
kmp_sched.cpp
1 /*
2  * kmp_sched.c -- static scheduling -- iteration initialization
3  */
4 
5 /* <copyright>
6  Copyright (c) 1997-2015 Intel Corporation. All Rights Reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11 
12  * Redistributions of source code must retain the above copyright
13  notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17  * Neither the name of Intel Corporation nor the names of its
18  contributors may be used to endorse or promote products derived
19  from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 </copyright> */
34 
35 /*
36  * Static scheduling initialization.
37  *
38  * NOTE: team->t.t_nproc is a constant inside of any dispatch loop, however
39  * it may change values between parallel regions. __kmp_max_nth
40  * is the largest value __kmp_nth may take, 1 is the smallest.
41  *
42  */
43 
44 #include "kmp.h"
45 #include "kmp_i18n.h"
46 #include "kmp_str.h"
47 #include "kmp_error.h"
48 #include "kmp_stats.h"
49 #include "kmp_itt.h"
50 
51 // template for type limits
52 template< typename T >
53 struct i_maxmin {
54  static const T mx;
55  static const T mn;
56 };
57 template<>
58 struct i_maxmin< int > {
59  static const int mx = 0x7fffffff;
60  static const int mn = 0x80000000;
61 };
62 template<>
63 struct i_maxmin< unsigned int > {
64  static const unsigned int mx = 0xffffffff;
65  static const unsigned int mn = 0x00000000;
66 };
67 template<>
68 struct i_maxmin< long long > {
69  static const long long mx = 0x7fffffffffffffffLL;
70  static const long long mn = 0x8000000000000000LL;
71 };
72 template<>
73 struct i_maxmin< unsigned long long > {
74  static const unsigned long long mx = 0xffffffffffffffffLL;
75  static const unsigned long long mn = 0x0000000000000000LL;
76 };
77 //-------------------------------------------------------------------------
78 #ifdef KMP_DEBUG
79 //-------------------------------------------------------------------------
80 // template for debug prints specification ( d, u, lld, llu )
81  char const * traits_t< int >::spec = "d";
82  char const * traits_t< unsigned int >::spec = "u";
83  char const * traits_t< long long >::spec = "lld";
84  char const * traits_t< unsigned long long >::spec = "llu";
85 //-------------------------------------------------------------------------
86 #endif
87 
88 template< typename T >
89 static void
90 __kmp_for_static_init(
91  ident_t *loc,
92  kmp_int32 global_tid,
93  kmp_int32 schedtype,
94  kmp_int32 *plastiter,
95  T *plower,
96  T *pupper,
97  typename traits_t< T >::signed_t *pstride,
98  typename traits_t< T >::signed_t incr,
99  typename traits_t< T >::signed_t chunk
100 ) {
101  KMP_COUNT_BLOCK(OMP_FOR_static);
102  typedef typename traits_t< T >::unsigned_t UT;
103  typedef typename traits_t< T >::signed_t ST;
104  /* this all has to be changed back to TID and such.. */
105  register kmp_int32 gtid = global_tid;
106  register kmp_uint32 tid;
107  register kmp_uint32 nth;
108  register UT trip_count;
109  register kmp_team_t *team;
110  register kmp_info_t *th = __kmp_threads[ gtid ];
111 
112  KMP_DEBUG_ASSERT( plastiter && plower && pupper && pstride );
113  KE_TRACE( 10, ("__kmpc_for_static_init called (%d)\n", global_tid));
114  #ifdef KMP_DEBUG
115  {
116  const char * buff;
117  // create format specifiers before the debug output
118  buff = __kmp_str_format(
119  "__kmpc_for_static_init: T#%%d sched=%%d liter=%%d iter=(%%%s," \
120  " %%%s, %%%s) incr=%%%s chunk=%%%s signed?<%s>\n",
121  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec,
122  traits_t< ST >::spec, traits_t< ST >::spec, traits_t< T >::spec );
123  KD_TRACE(100, ( buff, global_tid, schedtype, *plastiter,
124  *plower, *pupper, *pstride, incr, chunk ) );
125  __kmp_str_free( &buff );
126  }
127  #endif
128 
129  if ( __kmp_env_consistency_check ) {
130  __kmp_push_workshare( global_tid, ct_pdo, loc );
131  if ( incr == 0 ) {
132  __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc );
133  }
134  }
135  /* special handling for zero-trip loops */
136  if ( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) {
137  if( plastiter != NULL )
138  *plastiter = FALSE;
139  /* leave pupper and plower set to entire iteration space */
140  *pstride = incr; /* value should never be used */
141  // *plower = *pupper - incr; // let compiler bypass the illegal loop (like for(i=1;i<10;i--)) THIS LINE CAUSED shape2F/h_tests_1.f TO HAVE A FAILURE ON A ZERO-TRIP LOOP (lower=1,\
142  upper=0,stride=1) - JPH June 23, 2009.
143  #ifdef KMP_DEBUG
144  {
145  const char * buff;
146  // create format specifiers before the debug output
147  buff = __kmp_str_format(
148  "__kmpc_for_static_init:(ZERO TRIP) liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>, loc = %%s\n",
149  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec );
150  KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride, loc->psource ) );
151  __kmp_str_free( &buff );
152  }
153  #endif
154  KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
155  return;
156  }
157 
158  #if OMP_40_ENABLED
159  if ( schedtype > kmp_ord_upper ) {
160  // we are in DISTRIBUTE construct
161  schedtype += kmp_sch_static - kmp_distribute_static; // AC: convert to usual schedule type
162  tid = th->th.th_team->t.t_master_tid;
163  team = th->th.th_team->t.t_parent;
164  } else
165  #endif
166  {
167  tid = __kmp_tid_from_gtid( global_tid );
168  team = th->th.th_team;
169  }
170 
171  /* determine if "for" loop is an active worksharing construct */
172  if ( team -> t.t_serialized ) {
173  /* serialized parallel, each thread executes whole iteration space */
174  if( plastiter != NULL )
175  *plastiter = TRUE;
176  /* leave pupper and plower set to entire iteration space */
177  *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1));
178 
179  #ifdef KMP_DEBUG
180  {
181  const char * buff;
182  // create format specifiers before the debug output
183  buff = __kmp_str_format(
184  "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n",
185  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec );
186  KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) );
187  __kmp_str_free( &buff );
188  }
189  #endif
190  KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
191  return;
192  }
193  nth = team->t.t_nproc;
194  if ( nth == 1 ) {
195  if( plastiter != NULL )
196  *plastiter = TRUE;
197  *pstride = (incr > 0) ? (*pupper - *plower + 1) : (-(*plower - *pupper + 1));
198  #ifdef KMP_DEBUG
199  {
200  const char * buff;
201  // create format specifiers before the debug output
202  buff = __kmp_str_format(
203  "__kmpc_for_static_init: (serial) liter=%%d lower=%%%s upper=%%%s stride = %%%s\n",
204  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec );
205  KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) );
206  __kmp_str_free( &buff );
207  }
208  #endif
209  KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
210  return;
211  }
212 
213  /* compute trip count */
214  if ( incr == 1 ) {
215  trip_count = *pupper - *plower + 1;
216  } else if (incr == -1) {
217  trip_count = *plower - *pupper + 1;
218  } else {
219  if ( incr > 1 ) { // the check is needed for unsigned division when incr < 0
220  trip_count = (*pupper - *plower) / incr + 1;
221  } else {
222  trip_count = (*plower - *pupper) / ( -incr ) + 1;
223  }
224  }
225 
226  if ( __kmp_env_consistency_check ) {
227  /* tripcount overflow? */
228  if ( trip_count == 0 && *pupper != *plower ) {
229  __kmp_error_construct( kmp_i18n_msg_CnsIterationRangeTooLarge, ct_pdo, loc );
230  }
231  }
232 
233  /* compute remaining parameters */
234  switch ( schedtype ) {
235  case kmp_sch_static:
236  {
237  if ( trip_count < nth ) {
238  KMP_DEBUG_ASSERT(
239  __kmp_static == kmp_sch_static_greedy || \
240  __kmp_static == kmp_sch_static_balanced
241  ); // Unknown static scheduling type.
242  if ( tid < trip_count ) {
243  *pupper = *plower = *plower + tid * incr;
244  } else {
245  *plower = *pupper + incr;
246  }
247  if( plastiter != NULL )
248  *plastiter = ( tid == trip_count - 1 );
249  } else {
250  if ( __kmp_static == kmp_sch_static_balanced ) {
251  register UT small_chunk = trip_count / nth;
252  register UT extras = trip_count % nth;
253  *plower += incr * ( tid * small_chunk + ( tid < extras ? tid : extras ) );
254  *pupper = *plower + small_chunk * incr - ( tid < extras ? 0 : incr );
255  if( plastiter != NULL )
256  *plastiter = ( tid == nth - 1 );
257  } else {
258  register T big_chunk_inc_count = ( trip_count/nth +
259  ( ( trip_count % nth ) ? 1 : 0) ) * incr;
260  register T old_upper = *pupper;
261 
262  KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy );
263  // Unknown static scheduling type.
264 
265  *plower += tid * big_chunk_inc_count;
266  *pupper = *plower + big_chunk_inc_count - incr;
267  if ( incr > 0 ) {
268  if( *pupper < *plower )
269  *pupper = i_maxmin< T >::mx;
270  if( plastiter != NULL )
271  *plastiter = *plower <= old_upper && *pupper > old_upper - incr;
272  if ( *pupper > old_upper ) *pupper = old_upper; // tracker C73258
273  } else {
274  if( *pupper > *plower )
275  *pupper = i_maxmin< T >::mn;
276  if( plastiter != NULL )
277  *plastiter = *plower >= old_upper && *pupper < old_upper - incr;
278  if ( *pupper < old_upper ) *pupper = old_upper; // tracker C73258
279  }
280  }
281  }
282  break;
283  }
284  case kmp_sch_static_chunked:
285  {
286  register ST span;
287  if ( chunk < 1 ) {
288  chunk = 1;
289  }
290  span = chunk * incr;
291  *pstride = span * nth;
292  *plower = *plower + (span * tid);
293  *pupper = *plower + span - incr;
294  if( plastiter != NULL )
295  *plastiter = (tid == ((trip_count - 1)/( UT )chunk) % nth);
296  break;
297  }
298  default:
299  KMP_ASSERT2( 0, "__kmpc_for_static_init: unknown scheduling type" );
300  break;
301  }
302 
303 #if USE_ITT_BUILD
304  // Report loop metadata
305  if ( KMP_MASTER_TID(tid) && __itt_metadata_add_ptr && __kmp_forkjoin_frames_mode == 3 &&
306 #if OMP_40_ENABLED
307  th->th.th_teams_microtask == NULL &&
308 #endif
309  team->t.t_active_level == 1 )
310  {
311  kmp_uint64 cur_chunk = chunk;
312  // Calculate chunk in case it was not specified; it is specified for kmp_sch_static_chunked
313  if ( schedtype == kmp_sch_static ) {
314  cur_chunk = trip_count / nth + ( ( trip_count % nth ) ? 1 : 0);
315  }
316  // 0 - "static" schedule
317  __kmp_itt_metadata_loop(loc, 0, trip_count, cur_chunk);
318  }
319 #endif
320  #ifdef KMP_DEBUG
321  {
322  const char * buff;
323  // create format specifiers before the debug output
324  buff = __kmp_str_format(
325  "__kmpc_for_static_init: liter=%%d lower=%%%s upper=%%%s stride = %%%s signed?<%s>\n",
326  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec, traits_t< T >::spec );
327  KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pstride ) );
328  __kmp_str_free( &buff );
329  }
330  #endif
331  KE_TRACE( 10, ("__kmpc_for_static_init: T#%d return\n", global_tid ) );
332  return;
333 }
334 
335 template< typename T >
336 static void
337 __kmp_dist_for_static_init(
338  ident_t *loc,
339  kmp_int32 gtid,
340  kmp_int32 schedule,
341  kmp_int32 *plastiter,
342  T *plower,
343  T *pupper,
344  T *pupperDist,
345  typename traits_t< T >::signed_t *pstride,
346  typename traits_t< T >::signed_t incr,
347  typename traits_t< T >::signed_t chunk
348 ) {
349  KMP_COUNT_BLOCK(OMP_DISTR_FOR_static);
350  typedef typename traits_t< T >::unsigned_t UT;
351  typedef typename traits_t< T >::signed_t ST;
352  register kmp_uint32 tid;
353  register kmp_uint32 nth;
354  register kmp_uint32 team_id;
355  register kmp_uint32 nteams;
356  register UT trip_count;
357  register kmp_team_t *team;
358  kmp_info_t * th;
359 
360  KMP_DEBUG_ASSERT( plastiter && plower && pupper && pupperDist && pstride );
361  KE_TRACE( 10, ("__kmpc_dist_for_static_init called (%d)\n", gtid));
362  #ifdef KMP_DEBUG
363  {
364  const char * buff;
365  // create format specifiers before the debug output
366  buff = __kmp_str_format(
367  "__kmpc_dist_for_static_init: T#%%d schedLoop=%%d liter=%%d "\
368  "iter=(%%%s, %%%s, %%%s) chunk=%%%s signed?<%s>\n",
369  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec,
370  traits_t< ST >::spec, traits_t< T >::spec );
371  KD_TRACE(100, ( buff, gtid, schedule, *plastiter,
372  *plower, *pupper, incr, chunk ) );
373  __kmp_str_free( &buff );
374  }
375  #endif
376 
377  if( __kmp_env_consistency_check ) {
378  __kmp_push_workshare( gtid, ct_pdo, loc );
379  if( incr == 0 ) {
380  __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc );
381  }
382  if( incr > 0 ? (*pupper < *plower) : (*plower < *pupper) ) {
383  // The loop is illegal.
384  // Some zero-trip loops maintained by compiler, e.g.:
385  // for(i=10;i<0;++i) // lower >= upper - run-time check
386  // for(i=0;i>10;--i) // lower <= upper - run-time check
387  // for(i=0;i>10;++i) // incr > 0 - compile-time check
388  // for(i=10;i<0;--i) // incr < 0 - compile-time check
389  // Compiler does not check the following illegal loops:
390  // for(i=0;i<10;i+=incr) // where incr<0
391  // for(i=10;i>0;i-=incr) // where incr<0
392  __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc );
393  }
394  }
395  tid = __kmp_tid_from_gtid( gtid );
396  th = __kmp_threads[gtid];
397  KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct
398  nth = th->th.th_team_nproc;
399  team = th->th.th_team;
400  #if OMP_40_ENABLED
401  nteams = th->th.th_teams_size.nteams;
402  #endif
403  team_id = team->t.t_master_tid;
404  KMP_DEBUG_ASSERT(nteams == team->t.t_parent->t.t_nproc);
405 
406  // compute global trip count
407  if( incr == 1 ) {
408  trip_count = *pupper - *plower + 1;
409  } else if(incr == -1) {
410  trip_count = *plower - *pupper + 1;
411  } else {
412  trip_count = (ST)(*pupper - *plower) / incr + 1; // cast to signed to cover incr<0 case
413  }
414  *pstride = *pupper - *plower; // just in case (can be unused)
415  if( trip_count <= nteams ) {
416  KMP_DEBUG_ASSERT(
417  __kmp_static == kmp_sch_static_greedy || \
418  __kmp_static == kmp_sch_static_balanced
419  ); // Unknown static scheduling type.
420  // only masters of some teams get single iteration, other threads get nothing
421  if( team_id < trip_count && tid == 0 ) {
422  *pupper = *pupperDist = *plower = *plower + team_id * incr;
423  } else {
424  *pupperDist = *pupper;
425  *plower = *pupper + incr; // compiler should skip loop body
426  }
427  if( plastiter != NULL )
428  *plastiter = ( tid == 0 && team_id == trip_count - 1 );
429  } else {
430  // Get the team's chunk first (each team gets at most one chunk)
431  if( __kmp_static == kmp_sch_static_balanced ) {
432  register UT chunkD = trip_count / nteams;
433  register UT extras = trip_count % nteams;
434  *plower += incr * ( team_id * chunkD + ( team_id < extras ? team_id : extras ) );
435  *pupperDist = *plower + chunkD * incr - ( team_id < extras ? 0 : incr );
436  if( plastiter != NULL )
437  *plastiter = ( team_id == nteams - 1 );
438  } else {
439  register T chunk_inc_count =
440  ( trip_count / nteams + ( ( trip_count % nteams ) ? 1 : 0) ) * incr;
441  register T upper = *pupper;
442  KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy );
443  // Unknown static scheduling type.
444  *plower += team_id * chunk_inc_count;
445  *pupperDist = *plower + chunk_inc_count - incr;
446  // Check/correct bounds if needed
447  if( incr > 0 ) {
448  if( *pupperDist < *plower )
449  *pupperDist = i_maxmin< T >::mx;
450  if( plastiter != NULL )
451  *plastiter = *plower <= upper && *pupperDist > upper - incr;
452  if( *pupperDist > upper )
453  *pupperDist = upper; // tracker C73258
454  if( *plower > *pupperDist ) {
455  *pupper = *pupperDist; // no iterations available for the team
456  goto end;
457  }
458  } else {
459  if( *pupperDist > *plower )
460  *pupperDist = i_maxmin< T >::mn;
461  if( plastiter != NULL )
462  *plastiter = *plower >= upper && *pupperDist < upper - incr;
463  if( *pupperDist < upper )
464  *pupperDist = upper; // tracker C73258
465  if( *plower < *pupperDist ) {
466  *pupper = *pupperDist; // no iterations available for the team
467  goto end;
468  }
469  }
470  }
471  // Get the parallel loop chunk now (for thread)
472  // compute trip count for team's chunk
473  if( incr == 1 ) {
474  trip_count = *pupperDist - *plower + 1;
475  } else if(incr == -1) {
476  trip_count = *plower - *pupperDist + 1;
477  } else {
478  trip_count = (ST)(*pupperDist - *plower) / incr + 1;
479  }
480  KMP_DEBUG_ASSERT( trip_count );
481  switch( schedule ) {
482  case kmp_sch_static:
483  {
484  if( trip_count <= nth ) {
485  KMP_DEBUG_ASSERT(
486  __kmp_static == kmp_sch_static_greedy || \
487  __kmp_static == kmp_sch_static_balanced
488  ); // Unknown static scheduling type.
489  if( tid < trip_count )
490  *pupper = *plower = *plower + tid * incr;
491  else
492  *plower = *pupper + incr; // no iterations available
493  if( plastiter != NULL )
494  if( *plastiter != 0 && !( tid == trip_count - 1 ) )
495  *plastiter = 0;
496  } else {
497  if( __kmp_static == kmp_sch_static_balanced ) {
498  register UT chunkL = trip_count / nth;
499  register UT extras = trip_count % nth;
500  *plower += incr * (tid * chunkL + (tid < extras ? tid : extras));
501  *pupper = *plower + chunkL * incr - (tid < extras ? 0 : incr);
502  if( plastiter != NULL )
503  if( *plastiter != 0 && !( tid == nth - 1 ) )
504  *plastiter = 0;
505  } else {
506  register T chunk_inc_count =
507  ( trip_count / nth + ( ( trip_count % nth ) ? 1 : 0) ) * incr;
508  register T upper = *pupperDist;
509  KMP_DEBUG_ASSERT( __kmp_static == kmp_sch_static_greedy );
510  // Unknown static scheduling type.
511  *plower += tid * chunk_inc_count;
512  *pupper = *plower + chunk_inc_count - incr;
513  if( incr > 0 ) {
514  if( *pupper < *plower )
515  *pupper = i_maxmin< T >::mx;
516  if( plastiter != NULL )
517  if( *plastiter != 0 && !(*plower <= upper && *pupper > upper - incr) )
518  *plastiter = 0;
519  if( *pupper > upper )
520  *pupper = upper;//tracker C73258
521  } else {
522  if( *pupper > *plower )
523  *pupper = i_maxmin< T >::mn;
524  if( plastiter != NULL )
525  if( *plastiter != 0 && !(*plower >= upper && *pupper < upper - incr) )
526  *plastiter = 0;
527  if( *pupper < upper )
528  *pupper = upper;//tracker C73258
529  }
530  }
531  }
532  break;
533  }
534  case kmp_sch_static_chunked:
535  {
536  register ST span;
537  if( chunk < 1 )
538  chunk = 1;
539  span = chunk * incr;
540  *pstride = span * nth;
541  *plower = *plower + (span * tid);
542  *pupper = *plower + span - incr;
543  if( plastiter != NULL )
544  if( *plastiter != 0 && !(tid == ((trip_count - 1) / ( UT )chunk) % nth) )
545  *plastiter = 0;
546  break;
547  }
548  default:
549  KMP_ASSERT2( 0, "__kmpc_dist_for_static_init: unknown loop scheduling type" );
550  break;
551  }
552  }
553  end:;
554  #ifdef KMP_DEBUG
555  {
556  const char * buff;
557  // create format specifiers before the debug output
558  buff = __kmp_str_format(
559  "__kmpc_dist_for_static_init: last=%%d lo=%%%s up=%%%s upDist=%%%s "\
560  "stride=%%%s signed?<%s>\n",
561  traits_t< T >::spec, traits_t< T >::spec, traits_t< T >::spec,
562  traits_t< ST >::spec, traits_t< T >::spec );
563  KD_TRACE(100, ( buff, *plastiter, *plower, *pupper, *pupperDist, *pstride ) );
564  __kmp_str_free( &buff );
565  }
566  #endif
567  KE_TRACE( 10, ("__kmpc_dist_for_static_init: T#%d return\n", gtid ) );
568  return;
569 }
570 
571 template< typename T >
572 static void
573 __kmp_team_static_init(
574  ident_t *loc,
575  kmp_int32 gtid,
576  kmp_int32 *p_last,
577  T *p_lb,
578  T *p_ub,
579  typename traits_t< T >::signed_t *p_st,
580  typename traits_t< T >::signed_t incr,
581  typename traits_t< T >::signed_t chunk
582 ) {
583  // The routine returns the first chunk distributed to the team and
584  // stride for next chunks calculation.
585  // Last iteration flag set for the team that will execute
586  // the last iteration of the loop.
587  // The routine is called for dist_schedue(static,chunk) only.
588  typedef typename traits_t< T >::unsigned_t UT;
589  typedef typename traits_t< T >::signed_t ST;
590  kmp_uint32 team_id;
591  kmp_uint32 nteams;
592  UT trip_count;
593  T lower;
594  T upper;
595  ST span;
596  kmp_team_t *team;
597  kmp_info_t *th;
598 
599  KMP_DEBUG_ASSERT( p_last && p_lb && p_ub && p_st );
600  KE_TRACE( 10, ("__kmp_team_static_init called (%d)\n", gtid));
601  #ifdef KMP_DEBUG
602  {
603  const char * buff;
604  // create format specifiers before the debug output
605  buff = __kmp_str_format( "__kmp_team_static_init enter: T#%%d liter=%%d "\
606  "iter=(%%%s, %%%s, %%%s) chunk %%%s; signed?<%s>\n",
607  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec,
608  traits_t< ST >::spec, traits_t< T >::spec );
609  KD_TRACE(100, ( buff, gtid, *p_last, *p_lb, *p_ub, *p_st, chunk ) );
610  __kmp_str_free( &buff );
611  }
612  #endif
613 
614  lower = *p_lb;
615  upper = *p_ub;
616  if( __kmp_env_consistency_check ) {
617  if( incr == 0 ) {
618  __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo, loc );
619  }
620  if( incr > 0 ? (upper < lower) : (lower < upper) ) {
621  // The loop is illegal.
622  // Some zero-trip loops maintained by compiler, e.g.:
623  // for(i=10;i<0;++i) // lower >= upper - run-time check
624  // for(i=0;i>10;--i) // lower <= upper - run-time check
625  // for(i=0;i>10;++i) // incr > 0 - compile-time check
626  // for(i=10;i<0;--i) // incr < 0 - compile-time check
627  // Compiler does not check the following illegal loops:
628  // for(i=0;i<10;i+=incr) // where incr<0
629  // for(i=10;i>0;i-=incr) // where incr<0
630  __kmp_error_construct( kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc );
631  }
632  }
633  th = __kmp_threads[gtid];
634  KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct
635  team = th->th.th_team;
636  #if OMP_40_ENABLED
637  nteams = th->th.th_teams_size.nteams;
638  #endif
639  team_id = team->t.t_master_tid;
640  KMP_DEBUG_ASSERT(nteams == team->t.t_parent->t.t_nproc);
641 
642  // compute trip count
643  if( incr == 1 ) {
644  trip_count = upper - lower + 1;
645  } else if(incr == -1) {
646  trip_count = lower - upper + 1;
647  } else {
648  trip_count = (ST)(upper - lower) / incr + 1; // cast to signed to cover incr<0 case
649  }
650  if( chunk < 1 )
651  chunk = 1;
652  span = chunk * incr;
653  *p_st = span * nteams;
654  *p_lb = lower + (span * team_id);
655  *p_ub = *p_lb + span - incr;
656  if ( p_last != NULL )
657  *p_last = (team_id == ((trip_count - 1)/(UT)chunk) % nteams);
658  // Correct upper bound if needed
659  if( incr > 0 ) {
660  if( *p_ub < *p_lb ) // overflow?
661  *p_ub = i_maxmin< T >::mx;
662  if( *p_ub > upper )
663  *p_ub = upper; // tracker C73258
664  } else { // incr < 0
665  if( *p_ub > *p_lb )
666  *p_ub = i_maxmin< T >::mn;
667  if( *p_ub < upper )
668  *p_ub = upper; // tracker C73258
669  }
670  #ifdef KMP_DEBUG
671  {
672  const char * buff;
673  // create format specifiers before the debug output
674  buff = __kmp_str_format( "__kmp_team_static_init exit: T#%%d team%%u liter=%%d "\
675  "iter=(%%%s, %%%s, %%%s) chunk %%%s\n",
676  traits_t< T >::spec, traits_t< T >::spec, traits_t< ST >::spec,
677  traits_t< ST >::spec );
678  KD_TRACE(100, ( buff, gtid, team_id, *p_last, *p_lb, *p_ub, *p_st, chunk ) );
679  __kmp_str_free( &buff );
680  }
681  #endif
682 }
683 
684 //--------------------------------------------------------------------------------------
685 extern "C" {
686 
707 void
708 __kmpc_for_static_init_4( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
709  kmp_int32 *plower, kmp_int32 *pupper,
710  kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk )
711 {
712  __kmp_for_static_init< kmp_int32 >(
713  loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
714 }
715 
719 void
720 __kmpc_for_static_init_4u( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
721  kmp_uint32 *plower, kmp_uint32 *pupper,
722  kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk )
723 {
724  __kmp_for_static_init< kmp_uint32 >(
725  loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
726 }
727 
731 void
732 __kmpc_for_static_init_8( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
733  kmp_int64 *plower, kmp_int64 *pupper,
734  kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk )
735 {
736  __kmp_for_static_init< kmp_int64 >(
737  loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
738 }
739 
743 void
744 __kmpc_for_static_init_8u( ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter,
745  kmp_uint64 *plower, kmp_uint64 *pupper,
746  kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk )
747 {
748  __kmp_for_static_init< kmp_uint64 >(
749  loc, gtid, schedtype, plastiter, plower, pupper, pstride, incr, chunk );
750 }
777 void
779  ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter,
780  kmp_int32 *plower, kmp_int32 *pupper, kmp_int32 *pupperD,
781  kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk )
782 {
783  __kmp_dist_for_static_init< kmp_int32 >(
784  loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk );
785 }
786 
790 void
792  ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter,
793  kmp_uint32 *plower, kmp_uint32 *pupper, kmp_uint32 *pupperD,
794  kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk )
795 {
796  __kmp_dist_for_static_init< kmp_uint32 >(
797  loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk );
798 }
799 
803 void
805  ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter,
806  kmp_int64 *plower, kmp_int64 *pupper, kmp_int64 *pupperD,
807  kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk )
808 {
809  __kmp_dist_for_static_init< kmp_int64 >(
810  loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk );
811 }
812 
816 void
818  ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter,
819  kmp_uint64 *plower, kmp_uint64 *pupper, kmp_uint64 *pupperD,
820  kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk )
821 {
822  __kmp_dist_for_static_init< kmp_uint64 >(
823  loc, gtid, schedule, plastiter, plower, pupper, pupperD, pstride, incr, chunk );
824 }
829 //-----------------------------------------------------------------------------------------
830 // Auxiliary routines for Distribute Parallel Loop construct implementation
831 // Transfer call to template< type T >
832 // __kmp_team_static_init( ident_t *loc, int gtid,
833 // int *p_last, T *lb, T *ub, ST *st, ST incr, ST chunk )
834 
854 void
856  ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
857  kmp_int32 *p_lb, kmp_int32 *p_ub, kmp_int32 *p_st, kmp_int32 incr, kmp_int32 chunk )
858 {
859  KMP_DEBUG_ASSERT( __kmp_init_serial );
860  __kmp_team_static_init< kmp_int32 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk );
861 }
862 
866 void
868  ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
869  kmp_uint32 *p_lb, kmp_uint32 *p_ub, kmp_int32 *p_st, kmp_int32 incr, kmp_int32 chunk )
870 {
871  KMP_DEBUG_ASSERT( __kmp_init_serial );
872  __kmp_team_static_init< kmp_uint32 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk );
873 }
874 
878 void
880  ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
881  kmp_int64 *p_lb, kmp_int64 *p_ub, kmp_int64 *p_st, kmp_int64 incr, kmp_int64 chunk )
882 {
883  KMP_DEBUG_ASSERT( __kmp_init_serial );
884  __kmp_team_static_init< kmp_int64 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk );
885 }
886 
890 void
892  ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last,
893  kmp_uint64 *p_lb, kmp_uint64 *p_ub, kmp_int64 *p_st, kmp_int64 incr, kmp_int64 chunk )
894 {
895  KMP_DEBUG_ASSERT( __kmp_init_serial );
896  __kmp_team_static_init< kmp_uint64 >( loc, gtid, p_last, p_lb, p_ub, p_st, incr, chunk );
897 }
902 } // extern "C"
903 
void __kmpc_team_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_int64 *p_lb, kmp_int64 *p_ub, kmp_int64 *p_st, kmp_int64 incr, kmp_int64 chunk)
Definition: kmp_sched.cpp:879
void __kmpc_dist_for_static_init_4u(ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, kmp_uint32 *plower, kmp_uint32 *pupper, kmp_uint32 *pupperD, kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk)
Definition: kmp_sched.cpp:791
void __kmpc_team_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_int32 *p_lb, kmp_int32 *p_ub, kmp_int32 *p_st, kmp_int32 incr, kmp_int32 chunk)
Definition: kmp_sched.cpp:855
void __kmpc_for_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, kmp_int64 *plower, kmp_int64 *pupper, kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk)
Definition: kmp_sched.cpp:732
#define KMP_COUNT_BLOCK(name)
Increments specified counter (name).
Definition: kmp_stats.h:654
void __kmpc_team_static_init_4u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_uint32 *p_lb, kmp_uint32 *p_ub, kmp_int32 *p_st, kmp_int32 incr, kmp_int32 chunk)
Definition: kmp_sched.cpp:867
void __kmpc_for_static_init_4u(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, kmp_uint32 *plower, kmp_uint32 *pupper, kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk)
Definition: kmp_sched.cpp:720
Definition: kmp.h:221
void __kmpc_dist_for_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, kmp_int32 *plower, kmp_int32 *pupper, kmp_int32 *pupperD, kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk)
Definition: kmp_sched.cpp:778
void __kmpc_team_static_init_8u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_uint64 *p_lb, kmp_uint64 *p_ub, kmp_int64 *p_st, kmp_int64 incr, kmp_int64 chunk)
Definition: kmp_sched.cpp:891
void __kmpc_dist_for_static_init_8u(ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, kmp_uint64 *plower, kmp_uint64 *pupper, kmp_uint64 *pupperD, kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk)
Definition: kmp_sched.cpp:817
void __kmpc_for_static_init_4(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, kmp_int32 *plower, kmp_int32 *pupper, kmp_int32 *pstride, kmp_int32 incr, kmp_int32 chunk)
Definition: kmp_sched.cpp:708
void __kmpc_dist_for_static_init_8(ident_t *loc, kmp_int32 gtid, kmp_int32 schedule, kmp_int32 *plastiter, kmp_int64 *plower, kmp_int64 *pupper, kmp_int64 *pupperD, kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk)
Definition: kmp_sched.cpp:804
char const * psource
Definition: kmp.h:230
void __kmpc_for_static_init_8u(ident_t *loc, kmp_int32 gtid, kmp_int32 schedtype, kmp_int32 *plastiter, kmp_uint64 *plower, kmp_uint64 *pupper, kmp_int64 *pstride, kmp_int64 incr, kmp_int64 chunk)
Definition: kmp_sched.cpp:744