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