30#include "kmp_dispatch.h"
32#include "kmp_dispatch_hier.h"
36#include "ompt-specific.h"
42void __kmp_dispatch_deo_error(
int *gtid_ref,
int *cid_ref,
ident_t *loc_ref) {
45 KMP_DEBUG_ASSERT(gtid_ref);
47 if (__kmp_env_consistency_check) {
48 th = __kmp_threads[*gtid_ref];
49 if (th->th.th_root->r.r_active &&
50 (th->th.th_dispatch->th_dispatch_pr_current->pushed_ws != ct_none)) {
51#if KMP_USE_DYNAMIC_LOCK
52 __kmp_push_sync(*gtid_ref, ct_ordered_in_pdo, loc_ref, NULL, 0);
54 __kmp_push_sync(*gtid_ref, ct_ordered_in_pdo, loc_ref, NULL);
60void __kmp_dispatch_dxo_error(
int *gtid_ref,
int *cid_ref,
ident_t *loc_ref) {
63 if (__kmp_env_consistency_check) {
64 th = __kmp_threads[*gtid_ref];
65 if (th->th.th_dispatch->th_dispatch_pr_current->pushed_ws != ct_none) {
66 __kmp_pop_sync(*gtid_ref, ct_ordered_in_pdo, loc_ref);
73 bool use_hier =
false) {
76 int monotonicity = SCHEDULE_NONMONOTONIC;
80 if (loc != NULL && loc->get_openmp_version() < 50)
81 monotonicity = SCHEDULE_MONOTONIC;
83 if (use_hier || __kmp_force_monotonic)
84 monotonicity = SCHEDULE_MONOTONIC;
85 else if (SCHEDULE_HAS_NONMONOTONIC(schedule))
86 monotonicity = SCHEDULE_NONMONOTONIC;
87 else if (SCHEDULE_HAS_MONOTONIC(schedule))
88 monotonicity = SCHEDULE_MONOTONIC;
93#if KMP_WEIGHTED_ITERATIONS_SUPPORTED
95static inline float __kmp_round_2decimal_val(
float num) {
96 return (
float)(
static_cast<int>(num * 100 + 0.5)) / 100;
98static inline int __kmp_get_round_val(
float num) {
99 return static_cast<int>(num < 0 ? num - 0.5 : num + 0.5);
105__kmp_initialize_self_buffer(kmp_team_t *team, T
id,
106 dispatch_private_info_template<T> *pr,
107 typename traits_t<T>::unsigned_t nchunks, T nproc,
108 typename traits_t<T>::unsigned_t &init,
109 T &small_chunk, T &extras, T &p_extra) {
111#if KMP_WEIGHTED_ITERATIONS_SUPPORTED
112 if (pr->flags.use_hybrid) {
113 kmp_info_t *th = __kmp_threads[__kmp_gtid_from_tid((
int)
id, team)];
114 kmp_hw_core_type_t type =
115 (kmp_hw_core_type_t)th->th.th_topology_attrs.core_type;
116 T pchunks = pr->u.p.pchunks;
117 T echunks = nchunks - pchunks;
118 T num_procs_with_pcore = pr->u.p.num_procs_with_pcore;
119 T num_procs_with_ecore = nproc - num_procs_with_pcore;
120 T first_thread_with_ecore = pr->u.p.first_thread_with_ecore;
122 pchunks / num_procs_with_pcore;
124 echunks / num_procs_with_ecore;
127 (pchunks % num_procs_with_pcore) + (echunks % num_procs_with_ecore);
129 p_extra = (big_chunk - small_chunk);
131 if (type == KMP_HW_CORE_TYPE_CORE) {
132 if (
id < first_thread_with_ecore) {
133 init =
id * small_chunk +
id * p_extra + (
id < extras ? id : extras);
135 init =
id * small_chunk + (
id - num_procs_with_ecore) * p_extra +
136 (
id < extras ?
id : extras);
139 if (
id == first_thread_with_ecore) {
140 init =
id * small_chunk +
id * p_extra + (
id < extras ? id : extras);
142 init =
id * small_chunk + first_thread_with_ecore * p_extra +
143 (
id < extras ? id : extras);
146 p_extra = (type == KMP_HW_CORE_TYPE_CORE) ? p_extra : 0;
151 small_chunk = nchunks / nproc;
152 extras = nchunks % nproc;
154 init =
id * small_chunk + (
id < extras ? id : extras);
157#if KMP_STATIC_STEAL_ENABLED
184void __kmp_dispatch_init_algorithm(
ident_t *loc,
int gtid,
185 dispatch_private_info_template<T> *pr,
187 typename traits_t<T>::signed_t st,
189 kmp_uint64 *cur_chunk,
191 typename traits_t<T>::signed_t chunk,
193 typedef typename traits_t<T>::unsigned_t UT;
194 typedef typename traits_t<T>::floating_t DBL;
204 typedef typename traits_t<T>::signed_t ST;
208 buff = __kmp_str_format(
"__kmp_dispatch_init_algorithm: T#%%d called "
209 "pr:%%p lb:%%%s ub:%%%s st:%%%s "
210 "schedule:%%d chunk:%%%s nproc:%%%s tid:%%%s\n",
211 traits_t<T>::spec, traits_t<T>::spec,
212 traits_t<ST>::spec, traits_t<ST>::spec,
213 traits_t<T>::spec, traits_t<T>::spec);
214 KD_TRACE(10, (buff, gtid, pr, lb, ub, st, schedule, chunk, nproc, tid));
215 __kmp_str_free(&buff);
219 th = __kmp_threads[gtid];
220 team = th->th.th_team;
221 active = !team->t.t_serialized;
224 int itt_need_metadata_reporting =
225 __itt_metadata_add_ptr && __kmp_forkjoin_frames_mode == 3 &&
226 KMP_MASTER_GTID(gtid) && th->th.th_teams_microtask == NULL &&
227 team->t.t_active_level == 1;
230#if KMP_USE_HIER_SCHED
231 use_hier = pr->flags.use_hier;
237 monotonicity = __kmp_get_monotonicity(loc, schedule, use_hier);
238 schedule = SCHEDULE_WITHOUT_MODIFIERS(schedule);
242 pr->flags.nomerge = TRUE;
246 pr->flags.nomerge = FALSE;
248 pr->type_size = traits_t<T>::type_size;
250 pr->flags.ordered = TRUE;
254 pr->flags.ordered = FALSE;
257 if (pr->flags.ordered) {
258 monotonicity = SCHEDULE_MONOTONIC;
262 schedule = __kmp_static;
264 if (schedule == kmp_sch_runtime) {
267 schedule = team->t.t_sched.r_sched_type;
268#if KMP_STATIC_STEAL_ENABLED
271 if (SCHEDULE_WITHOUT_MODIFIERS(schedule) == kmp_sch_static_steal)
272 schedule = (
enum sched_type)(kmp_sch_dynamic_chunked |
275 monotonicity = __kmp_get_monotonicity(loc, schedule, use_hier);
276 schedule = SCHEDULE_WITHOUT_MODIFIERS(schedule);
277 if (pr->flags.ordered)
278 monotonicity = SCHEDULE_MONOTONIC;
282 schedule = __kmp_guided;
284 schedule = __kmp_static;
288 chunk = team->t.t_sched.chunk;
297 buff = __kmp_str_format(
"__kmp_dispatch_init_algorithm: T#%%d new: "
298 "schedule:%%d chunk:%%%s\n",
300 KD_TRACE(10, (buff, gtid, schedule, chunk));
301 __kmp_str_free(&buff);
306 schedule = __kmp_guided;
309 chunk = KMP_DEFAULT_CHUNK;
315 schedule = __kmp_auto;
320 buff = __kmp_str_format(
321 "__kmp_dispatch_init_algorithm: kmp_sch_auto: T#%%d new: "
322 "schedule:%%d chunk:%%%s\n",
324 KD_TRACE(10, (buff, gtid, schedule, chunk));
325 __kmp_str_free(&buff);
329#if KMP_STATIC_STEAL_ENABLED
331 if (schedule == kmp_sch_dynamic_chunked) {
332 if (monotonicity == SCHEDULE_NONMONOTONIC)
333 schedule = kmp_sch_static_steal;
337 if (schedule == kmp_sch_guided_analytical_chunked && nproc > 1 << 20) {
338 schedule = kmp_sch_guided_iterative_chunked;
339 KMP_WARNING(DispatchManyThreads);
343 schedule = team->t.t_sched.r_sched_type;
344 monotonicity = __kmp_get_monotonicity(loc, schedule, use_hier);
345 schedule = SCHEDULE_WITHOUT_MODIFIERS(schedule);
349 schedule == __kmp_static) {
350 schedule = kmp_sch_static_balanced_chunked;
355 chunk = team->t.t_sched.chunk * chunk;
365 buff = __kmp_str_format(
366 "__kmp_dispatch_init_algorithm: T#%%d new: schedule:%%d"
369 KD_TRACE(10, (buff, gtid, schedule, chunk));
370 __kmp_str_free(&buff);
374 pr->u.p.parm1 = chunk;
377 "unknown scheduling type");
381 if (__kmp_env_consistency_check) {
383 __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited,
384 (pr->flags.ordered ? ct_pdo_ordered : ct_pdo), loc);
398 tc = (UT)(lb - ub) / (-st) + 1;
406 tc = (UT)(ub - lb) / st + 1;
413 if (KMP_MASTER_GTID(gtid)) {
424 pr->u.p.last_upper = ub + st;
430 if (pr->flags.ordered) {
431 pr->ordered_bumped = 0;
432 pr->u.p.ordered_lower = 1;
433 pr->u.p.ordered_upper = 0;
438#if KMP_STATIC_STEAL_ENABLED
439 case kmp_sch_static_steal: {
443 (
"__kmp_dispatch_init_algorithm: T#%d kmp_sch_static_steal case\n",
446 ntc = (tc % chunk ? 1 : 0) + tc / chunk;
447 if (nproc > 1 && ntc >= nproc) {
450 T small_chunk, extras, p_extra = 0;
451 kmp_uint32 old = UNUSED;
452 int claimed = pr->steal_flag.compare_exchange_strong(old, CLAIMED);
453 if (traits_t<T>::type_size > 4) {
459 pr->u.p.steal_lock = (kmp_lock_t *)__kmp_allocate(
sizeof(kmp_lock_t));
460 __kmp_init_lock(pr->u.p.steal_lock);
463#if KMP_WEIGHTED_ITERATIONS_SUPPORTED
466 bool use_hybrid =
false;
467 kmp_hw_core_type_t core_type = KMP_HW_CORE_TYPE_UNKNOWN;
468 T first_thread_with_ecore = 0;
469 T num_procs_with_pcore = 0;
470 T num_procs_with_ecore = 0;
471 T p_ntc = 0, e_ntc = 0;
472 if (__kmp_is_hybrid_cpu() && __kmp_affinity.type != affinity_none &&
473 __kmp_affinity.type != affinity_explicit) {
475 core_type = (kmp_hw_core_type_t)th->th.th_topology_attrs.core_type;
476 if (core_type != KMP_HW_CORE_TYPE_UNKNOWN &&
477 __kmp_first_osid_with_ecore > -1) {
478 for (
int i = 0; i < team->t.t_nproc; ++i) {
479 kmp_hw_core_type_t type = (kmp_hw_core_type_t)team->t.t_threads[i]
480 ->th.th_topology_attrs.core_type;
481 int id = team->t.t_threads[i]->th.th_topology_ids.os_id;
482 if (
id == __kmp_first_osid_with_ecore) {
483 first_thread_with_ecore =
484 team->t.t_threads[i]->th.th_info.ds.ds_tid;
486 if (type == KMP_HW_CORE_TYPE_CORE) {
487 num_procs_with_pcore++;
488 }
else if (type == KMP_HW_CORE_TYPE_ATOM) {
489 num_procs_with_ecore++;
496 if (num_procs_with_pcore > 0 && num_procs_with_ecore > 0) {
497 float multiplier = 60.0 / 40.0;
498 float p_ratio = (float)num_procs_with_pcore / nproc;
499 float e_ratio = (float)num_procs_with_ecore / nproc;
502 (((multiplier * num_procs_with_pcore) / nproc) + e_ratio);
503 float p_multiplier = multiplier * e_multiplier;
504 p_ntc = __kmp_get_round_val(ntc * p_ratio * p_multiplier);
505 if ((
int)p_ntc > (
int)(ntc * p_ratio * p_multiplier))
507 (int)(__kmp_round_2decimal_val(ntc * e_ratio * e_multiplier));
509 e_ntc = __kmp_get_round_val(ntc * e_ratio * e_multiplier);
510 KMP_DEBUG_ASSERT(ntc == p_ntc + e_ntc);
514 use_hybrid = (use_hybrid && (p_ntc >= num_procs_with_pcore &&
515 e_ntc >= num_procs_with_ecore)
522 pr->flags.use_hybrid = use_hybrid;
523 pr->u.p.pchunks = p_ntc;
524 pr->u.p.num_procs_with_pcore = num_procs_with_pcore;
525 pr->u.p.first_thread_with_ecore = first_thread_with_ecore;
528 KMP_DEBUG_ASSERT(nproc == num_procs_with_pcore + num_procs_with_ecore);
529 T big_chunk = p_ntc / num_procs_with_pcore;
530 small_chunk = e_ntc / num_procs_with_ecore;
533 (p_ntc % num_procs_with_pcore) + (e_ntc % num_procs_with_ecore);
535 p_extra = (big_chunk - small_chunk);
537 if (core_type == KMP_HW_CORE_TYPE_CORE) {
538 if (
id < first_thread_with_ecore) {
540 id * small_chunk +
id * p_extra + (
id < extras ? id : extras);
542 init =
id * small_chunk + (
id - num_procs_with_ecore) * p_extra +
543 (
id < extras ?
id : extras);
546 if (
id == first_thread_with_ecore) {
548 id * small_chunk +
id * p_extra + (
id < extras ? id : extras);
550 init =
id * small_chunk + first_thread_with_ecore * p_extra +
551 (
id < extras ? id : extras);
554 p_extra = (core_type == KMP_HW_CORE_TYPE_CORE) ? p_extra : 0;
558 small_chunk = ntc / nproc;
559 extras = ntc % nproc;
560 init =
id * small_chunk + (
id < extras ? id : extras);
563 pr->u.p.count = init;
565 pr->u.p.ub = init + small_chunk + p_extra + (
id < extras ? 1 : 0);
568 KMP_ATOMIC_ST_REL(&pr->steal_flag, READY);
571 KMP_DEBUG_ASSERT(pr->steal_flag == THIEF);
577 pr->u.p.parm3 = nproc;
578 pr->u.p.parm4 = (
id + 1) % nproc;
582 schedule = kmp_sch_dynamic_chunked;
583 KD_TRACE(100, (
"__kmp_dispatch_init_algorithm: T#%d switching to "
584 "kmp_sch_dynamic_chunked\n",
591 case kmp_sch_static_balanced: {
596 (
"__kmp_dispatch_init_algorithm: T#%d kmp_sch_static_balanced case\n",
606 pr->u.p.parm1 = (
id == tc - 1);
609 pr->u.p.parm1 = FALSE;
613 T small_chunk = tc / nproc;
614 T extras = tc % nproc;
615 init =
id * small_chunk + (
id < extras ? id : extras);
616 limit = init + small_chunk - (
id < extras ? 0 : 1);
617 pr->u.p.parm1 = (
id == nproc - 1);
623 pr->u.p.parm1 = TRUE;
627 pr->u.p.parm1 = FALSE;
633 if (itt_need_metadata_reporting)
635 *cur_chunk = limit - init + 1;
638 pr->u.p.lb = lb + init;
639 pr->u.p.ub = lb + limit;
642 T ub_tmp = lb + limit * st;
643 pr->u.p.lb = lb + init * st;
647 pr->u.p.ub = (ub_tmp + st > ub ? ub : ub_tmp);
649 pr->u.p.ub = (ub_tmp + st < ub ? ub : ub_tmp);
652 if (pr->flags.ordered) {
653 pr->u.p.ordered_lower = init;
654 pr->u.p.ordered_upper = limit;
658 case kmp_sch_static_balanced_chunked: {
661 KD_TRACE(100, (
"__kmp_dispatch_init_algorithm: T#%d runtime(simd:static)"
662 " -> falling-through to static_greedy\n",
664 schedule = kmp_sch_static_greedy;
666 pr->u.p.parm1 = ((tc + nth - 1) / nth + chunk - 1) & ~(chunk - 1);
672 case kmp_sch_guided_iterative_chunked: {
675 (
"__kmp_dispatch_init_algorithm: T#%d kmp_sch_guided_iterative_chunked"
680 if ((2L * chunk + 1) * nproc >= tc) {
682 schedule = kmp_sch_dynamic_chunked;
686 pr->u.p.parm2 = guided_int_param * nproc * (chunk + 1);
687 *(
double *)&pr->u.p.parm3 =
688 guided_flt_param / (
double)nproc;
691 KD_TRACE(100, (
"__kmp_dispatch_init_algorithm: T#%d falling-through to "
692 "kmp_sch_static_greedy\n",
694 schedule = kmp_sch_static_greedy;
698 (
"__kmp_dispatch_init_algorithm: T#%d kmp_sch_static_greedy case\n",
704 case kmp_sch_guided_analytical_chunked: {
705 KD_TRACE(100, (
"__kmp_dispatch_init_algorithm: T#%d "
706 "kmp_sch_guided_analytical_chunked case\n",
710 if ((2L * chunk + 1) * nproc >= tc) {
712 schedule = kmp_sch_dynamic_chunked;
718#if KMP_USE_X87CONTROL
728 unsigned int oldFpcw = _control87(0, 0);
729 _control87(_PC_64, _MCW_PC);
733 long double target = ((
long double)chunk * 2 + 1) * nproc / tc;
740 x = 1.0 - 0.5 / (double)nproc;
751 ptrdiff_t natural_alignment =
752 (ptrdiff_t)&t.b - (ptrdiff_t)&t - (ptrdiff_t)1;
756 (((ptrdiff_t)&pr->u.p.parm3) & (natural_alignment)) == 0);
761 *(DBL *)&pr->u.p.parm3 = x;
774 p = __kmp_pow<UT>(x, right);
779 }
while (p > target && right < (1 << 27));
787 while (left + 1 < right) {
788 mid = (left + right) / 2;
789 if (__kmp_pow<UT>(x, mid) > target) {
798 KMP_ASSERT(cross && __kmp_pow<UT>(x, cross - 1) > target &&
799 __kmp_pow<UT>(x, cross) <= target);
802 pr->u.p.parm2 = cross;
805#if ((KMP_OS_LINUX || KMP_OS_WINDOWS) && KMP_ARCH_X86) && (!defined(KMP_I8))
806#define GUIDED_ANALYTICAL_WORKAROUND (*(DBL *)&pr->u.p.parm3)
808#define GUIDED_ANALYTICAL_WORKAROUND (x)
812 __kmp_dispatch_guided_remaining(
813 tc, GUIDED_ANALYTICAL_WORKAROUND, cross) -
815#if KMP_USE_X87CONTROL
817 _control87(oldFpcw, _MCW_PC);
821 KD_TRACE(100, (
"__kmp_dispatch_init_algorithm: T#%d falling-through to "
822 "kmp_sch_static_greedy\n",
824 schedule = kmp_sch_static_greedy;
830 case kmp_sch_static_greedy:
833 (
"__kmp_dispatch_init_algorithm: T#%d kmp_sch_static_greedy case\n",
835 pr->u.p.parm1 = (nproc > 1) ? (tc + nproc - 1) / nproc : tc;
837 case kmp_sch_static_chunked:
838 case kmp_sch_dynamic_chunked:
842 if (pr->u.p.parm1 <= 0)
843 pr->u.p.parm1 = KMP_DEFAULT_CHUNK;
844 else if (pr->u.p.parm1 > tc)
848 pr->u.p.parm2 = (tc / pr->u.p.parm1) + (tc % pr->u.p.parm1 ? 1 : 0);
849 KD_TRACE(100, (
"__kmp_dispatch_init_algorithm: T#%d "
850 "kmp_sch_static_chunked/kmp_sch_dynamic_chunked cases\n",
853 case kmp_sch_trapezoidal: {
856 T parm1, parm2, parm3, parm4;
858 (
"__kmp_dispatch_init_algorithm: T#%d kmp_sch_trapezoidal case\n",
864 parm2 = (tc / (2 * nproc));
874 }
else if (parm1 > parm2) {
879 parm3 = (parm2 + parm1);
880 parm3 = (2 * tc + parm3 - 1) / parm3;
888 parm4 = (parm2 - parm1) / parm4;
895 pr->u.p.parm1 = parm1;
896 pr->u.p.parm2 = parm2;
897 pr->u.p.parm3 = parm3;
898 pr->u.p.parm4 = parm4;
903 __kmp_fatal(KMP_MSG(UnknownSchedTypeDetected),
904 KMP_HNT(GetNewerLibrary),
909 pr->schedule = schedule;
912#if KMP_USE_HIER_SCHED
914inline void __kmp_dispatch_init_hier_runtime(
ident_t *loc, T lb, T ub,
915 typename traits_t<T>::signed_t st);
918__kmp_dispatch_init_hier_runtime<kmp_int32>(
ident_t *loc, kmp_int32 lb,
919 kmp_int32 ub, kmp_int32 st) {
920 __kmp_dispatch_init_hierarchy<kmp_int32>(
921 loc, __kmp_hier_scheds.size, __kmp_hier_scheds.layers,
922 __kmp_hier_scheds.scheds, __kmp_hier_scheds.small_chunks, lb, ub, st);
926__kmp_dispatch_init_hier_runtime<kmp_uint32>(
ident_t *loc, kmp_uint32 lb,
927 kmp_uint32 ub, kmp_int32 st) {
928 __kmp_dispatch_init_hierarchy<kmp_uint32>(
929 loc, __kmp_hier_scheds.size, __kmp_hier_scheds.layers,
930 __kmp_hier_scheds.scheds, __kmp_hier_scheds.small_chunks, lb, ub, st);
934__kmp_dispatch_init_hier_runtime<kmp_int64>(
ident_t *loc, kmp_int64 lb,
935 kmp_int64 ub, kmp_int64 st) {
936 __kmp_dispatch_init_hierarchy<kmp_int64>(
937 loc, __kmp_hier_scheds.size, __kmp_hier_scheds.layers,
938 __kmp_hier_scheds.scheds, __kmp_hier_scheds.large_chunks, lb, ub, st);
942__kmp_dispatch_init_hier_runtime<kmp_uint64>(
ident_t *loc, kmp_uint64 lb,
943 kmp_uint64 ub, kmp_int64 st) {
944 __kmp_dispatch_init_hierarchy<kmp_uint64>(
945 loc, __kmp_hier_scheds.size, __kmp_hier_scheds.layers,
946 __kmp_hier_scheds.scheds, __kmp_hier_scheds.large_chunks, lb, ub, st);
950void __kmp_dispatch_free_hierarchies(kmp_team_t *team) {
951 int num_disp_buff = team->t.t_max_nproc > 1 ? __kmp_dispatch_num_buffers : 2;
952 for (
int i = 0; i < num_disp_buff; ++i) {
955 reinterpret_cast<dispatch_shared_info_template<kmp_int32>
volatile *
>(
956 &team->t.t_disp_buffer[i]);
958 sh->hier->deallocate();
959 __kmp_free(sh->hier);
970 T ub,
typename traits_t<T>::signed_t st,
971 typename traits_t<T>::signed_t chunk,
int push_ws) {
972 typedef typename traits_t<T>::unsigned_t UT;
977 kmp_uint32 my_buffer_index;
978 dispatch_private_info_template<T> *pr;
979 dispatch_shared_info_template<T>
volatile *sh;
981 KMP_BUILD_ASSERT(
sizeof(dispatch_private_info_template<T>) ==
982 sizeof(dispatch_private_info));
983 KMP_BUILD_ASSERT(
sizeof(dispatch_shared_info_template<UT>) ==
984 sizeof(dispatch_shared_info));
985 __kmp_assert_valid_gtid(gtid);
987 if (!TCR_4(__kmp_init_parallel))
988 __kmp_parallel_initialize();
990 __kmp_resume_if_soft_paused();
993 SSC_MARK_DISPATCH_INIT();
996 typedef typename traits_t<T>::signed_t ST;
1000 buff = __kmp_str_format(
"__kmp_dispatch_init: T#%%d called: schedule:%%d "
1001 "chunk:%%%s lb:%%%s ub:%%%s st:%%%s\n",
1002 traits_t<ST>::spec, traits_t<T>::spec,
1003 traits_t<T>::spec, traits_t<ST>::spec);
1004 KD_TRACE(10, (buff, gtid, schedule, chunk, lb, ub, st));
1005 __kmp_str_free(&buff);
1009 th = __kmp_threads[gtid];
1010 team = th->th.th_team;
1011 active = !team->t.t_serialized;
1012 th->th.th_ident = loc;
1017 if (schedule == __kmp_static) {
1023#if KMP_USE_HIER_SCHED
1029 my_buffer_index = th->th.th_dispatch->th_disp_index;
1030 pr =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1032 ->th_disp_buffer[my_buffer_index % __kmp_dispatch_num_buffers]);
1033 my_sched = SCHEDULE_WITHOUT_MODIFIERS(my_sched);
1038 if (pr->flags.use_hier) {
1040 KD_TRACE(100, (
"__kmp_dispatch_init: T#%d ordered loop detected. "
1041 "Disabling hierarchical scheduling.\n",
1043 pr->flags.use_hier = FALSE;
1046 if (schedule == kmp_sch_runtime && __kmp_hier_scheds.size > 0) {
1049 if (!ordered && !pr->flags.use_hier)
1050 __kmp_dispatch_init_hier_runtime<T>(loc, lb, ub, st);
1055 kmp_uint64 cur_chunk = chunk;
1056 int itt_need_metadata_reporting =
1057 __itt_metadata_add_ptr && __kmp_forkjoin_frames_mode == 3 &&
1058 KMP_MASTER_GTID(gtid) && th->th.th_teams_microtask == NULL &&
1059 team->t.t_active_level == 1;
1062 pr =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1063 th->th.th_dispatch->th_disp_buffer);
1065 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
1066 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
1068 my_buffer_index = th->th.th_dispatch->th_disp_index++;
1071 pr =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1073 ->th_disp_buffer[my_buffer_index % __kmp_dispatch_num_buffers]);
1074 sh =
reinterpret_cast<dispatch_shared_info_template<T>
volatile *
>(
1075 &team->t.t_disp_buffer[my_buffer_index % __kmp_dispatch_num_buffers]);
1076 KD_TRACE(10, (
"__kmp_dispatch_init: T#%d my_buffer_index:%d\n", gtid,
1078 if (sh->buffer_index != my_buffer_index) {
1079 KD_TRACE(100, (
"__kmp_dispatch_init: T#%d before wait: my_buffer_index:%d"
1080 " sh->buffer_index:%d\n",
1081 gtid, my_buffer_index, sh->buffer_index));
1082 __kmp_wait<kmp_uint32>(&sh->buffer_index, my_buffer_index,
1083 __kmp_eq<kmp_uint32> USE_ITT_BUILD_ARG(NULL));
1086 KD_TRACE(100, (
"__kmp_dispatch_init: T#%d after wait: my_buffer_index:%d "
1087 "sh->buffer_index:%d\n",
1088 gtid, my_buffer_index, sh->buffer_index));
1092 __kmp_dispatch_init_algorithm(loc, gtid, pr, schedule, lb, ub, st,
1096 chunk, (T)th->th.th_team_nproc,
1097 (T)th->th.th_info.ds.ds_tid);
1099 if (pr->flags.ordered == 0) {
1100 th->th.th_dispatch->th_deo_fcn = __kmp_dispatch_deo_error;
1101 th->th.th_dispatch->th_dxo_fcn = __kmp_dispatch_dxo_error;
1103 th->th.th_dispatch->th_deo_fcn = __kmp_dispatch_deo<UT>;
1104 th->th.th_dispatch->th_dxo_fcn = __kmp_dispatch_dxo<UT>;
1106 th->th.th_dispatch->th_dispatch_pr_current = (dispatch_private_info_t *)pr;
1107 th->th.th_dispatch->th_dispatch_sh_current =
1108 CCAST(dispatch_shared_info_t *, (
volatile dispatch_shared_info_t *)sh);
1110 if (pr->flags.ordered) {
1111 __kmp_itt_ordered_init(gtid);
1114 if (itt_need_metadata_reporting) {
1116 kmp_uint64 schedtype = 0;
1118 case kmp_sch_static_chunked:
1119 case kmp_sch_static_balanced:
1121 case kmp_sch_static_greedy:
1122 cur_chunk = pr->u.p.parm1;
1124 case kmp_sch_dynamic_chunked:
1127 case kmp_sch_guided_iterative_chunked:
1128 case kmp_sch_guided_analytical_chunked:
1138 __kmp_itt_metadata_loop(loc, schedtype, pr->u.p.tc, cur_chunk);
1140#if KMP_USE_HIER_SCHED
1141 if (pr->flags.use_hier) {
1143 pr->u.p.ub = pr->u.p.lb = pr->u.p.st = pr->u.p.tc = 0;
1153 buff = __kmp_str_format(
1154 "__kmp_dispatch_init: T#%%d returning: schedule:%%d ordered:%%%s "
1156 " st:%%%s tc:%%%s count:%%%s\n\tordered_lower:%%%s ordered_upper:%%%s"
1157 " parm1:%%%s parm2:%%%s parm3:%%%s parm4:%%%s\n",
1158 traits_t<UT>::spec, traits_t<T>::spec, traits_t<T>::spec,
1159 traits_t<ST>::spec, traits_t<UT>::spec, traits_t<UT>::spec,
1160 traits_t<UT>::spec, traits_t<UT>::spec, traits_t<T>::spec,
1161 traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec);
1162 KD_TRACE(10, (buff, gtid, pr->schedule, pr->flags.ordered, pr->u.p.lb,
1163 pr->u.p.ub, pr->u.p.st, pr->u.p.tc, pr->u.p.count,
1164 pr->u.p.ordered_lower, pr->u.p.ordered_upper, pr->u.p.parm1,
1165 pr->u.p.parm2, pr->u.p.parm3, pr->u.p.parm4));
1166 __kmp_str_free(&buff);
1169#if OMPT_SUPPORT && OMPT_OPTIONAL
1170 if (ompt_enabled.ompt_callback_work) {
1171 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
1172 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
1173 ompt_callbacks.ompt_callback(ompt_callback_work)(
1174 ompt_get_work_schedule(pr->schedule), ompt_scope_begin,
1175 &(team_info->parallel_data), &(task_info->task_data), pr->u.p.tc,
1176 OMPT_LOAD_RETURN_ADDRESS(gtid));
1179 KMP_PUSH_PARTITIONED_TIMER(OMP_loop_dynamic);
1187template <
typename UT>
1188static void __kmp_dispatch_finish(
int gtid,
ident_t *loc) {
1189 typedef typename traits_t<UT>::signed_t ST;
1190 __kmp_assert_valid_gtid(gtid);
1191 kmp_info_t *th = __kmp_threads[gtid];
1193 KD_TRACE(100, (
"__kmp_dispatch_finish: T#%d called\n", gtid));
1194 if (!th->th.th_team->t.t_serialized) {
1196 dispatch_private_info_template<UT> *pr =
1197 reinterpret_cast<dispatch_private_info_template<UT> *
>(
1198 th->th.th_dispatch->th_dispatch_pr_current);
1199 dispatch_shared_info_template<UT>
volatile *sh =
1200 reinterpret_cast<dispatch_shared_info_template<UT>
volatile *
>(
1201 th->th.th_dispatch->th_dispatch_sh_current);
1202 KMP_DEBUG_ASSERT(pr);
1203 KMP_DEBUG_ASSERT(sh);
1204 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
1205 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
1207 if (pr->ordered_bumped) {
1210 (
"__kmp_dispatch_finish: T#%d resetting ordered_bumped to zero\n",
1212 pr->ordered_bumped = 0;
1214 UT lower = pr->u.p.ordered_lower;
1220 buff = __kmp_str_format(
"__kmp_dispatch_finish: T#%%d before wait: "
1221 "ordered_iteration:%%%s lower:%%%s\n",
1222 traits_t<UT>::spec, traits_t<UT>::spec);
1223 KD_TRACE(1000, (buff, gtid, sh->u.s.ordered_iteration, lower));
1224 __kmp_str_free(&buff);
1228 __kmp_wait<UT>(&sh->u.s.ordered_iteration, lower,
1229 __kmp_ge<UT> USE_ITT_BUILD_ARG(NULL));
1235 buff = __kmp_str_format(
"__kmp_dispatch_finish: T#%%d after wait: "
1236 "ordered_iteration:%%%s lower:%%%s\n",
1237 traits_t<UT>::spec, traits_t<UT>::spec);
1238 KD_TRACE(1000, (buff, gtid, sh->u.s.ordered_iteration, lower));
1239 __kmp_str_free(&buff);
1243 test_then_inc<ST>((
volatile ST *)&sh->u.s.ordered_iteration);
1246 KD_TRACE(100, (
"__kmp_dispatch_finish: T#%d returned\n", gtid));
1249#ifdef KMP_GOMP_COMPAT
1251template <
typename UT>
1252static void __kmp_dispatch_finish_chunk(
int gtid,
ident_t *loc) {
1253 typedef typename traits_t<UT>::signed_t ST;
1254 __kmp_assert_valid_gtid(gtid);
1255 kmp_info_t *th = __kmp_threads[gtid];
1257 KD_TRACE(100, (
"__kmp_dispatch_finish_chunk: T#%d called\n", gtid));
1258 if (!th->th.th_team->t.t_serialized) {
1259 dispatch_private_info_template<UT> *pr =
1260 reinterpret_cast<dispatch_private_info_template<UT> *
>(
1261 th->th.th_dispatch->th_dispatch_pr_current);
1262 dispatch_shared_info_template<UT>
volatile *sh =
1263 reinterpret_cast<dispatch_shared_info_template<UT>
volatile *
>(
1264 th->th.th_dispatch->th_dispatch_sh_current);
1265 KMP_DEBUG_ASSERT(pr);
1266 KMP_DEBUG_ASSERT(sh);
1267 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
1268 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
1270 UT lower = pr->u.p.ordered_lower;
1271 UT upper = pr->u.p.ordered_upper;
1272 UT inc = upper - lower + 1;
1274 if (pr->ordered_bumped == inc) {
1277 (
"__kmp_dispatch_finish: T#%d resetting ordered_bumped to zero\n",
1279 pr->ordered_bumped = 0;
1281 inc -= pr->ordered_bumped;
1287 buff = __kmp_str_format(
1288 "__kmp_dispatch_finish_chunk: T#%%d before wait: "
1289 "ordered_iteration:%%%s lower:%%%s upper:%%%s\n",
1290 traits_t<UT>::spec, traits_t<UT>::spec, traits_t<UT>::spec);
1291 KD_TRACE(1000, (buff, gtid, sh->u.s.ordered_iteration, lower, upper));
1292 __kmp_str_free(&buff);
1296 __kmp_wait<UT>(&sh->u.s.ordered_iteration, lower,
1297 __kmp_ge<UT> USE_ITT_BUILD_ARG(NULL));
1300 KD_TRACE(1000, (
"__kmp_dispatch_finish_chunk: T#%d resetting "
1301 "ordered_bumped to zero\n",
1303 pr->ordered_bumped = 0;
1309 buff = __kmp_str_format(
1310 "__kmp_dispatch_finish_chunk: T#%%d after wait: "
1311 "ordered_iteration:%%%s inc:%%%s lower:%%%s upper:%%%s\n",
1312 traits_t<UT>::spec, traits_t<UT>::spec, traits_t<UT>::spec,
1313 traits_t<UT>::spec);
1315 (buff, gtid, sh->u.s.ordered_iteration, inc, lower, upper));
1316 __kmp_str_free(&buff);
1320 test_then_add<ST>((
volatile ST *)&sh->u.s.ordered_iteration, inc);
1324 KD_TRACE(100, (
"__kmp_dispatch_finish_chunk: T#%d returned\n", gtid));
1329template <
typename T>
1330int __kmp_dispatch_next_algorithm(
int gtid,
1331 dispatch_private_info_template<T> *pr,
1332 dispatch_shared_info_template<T>
volatile *sh,
1333 kmp_int32 *p_last, T *p_lb, T *p_ub,
1334 typename traits_t<T>::signed_t *p_st, T nproc,
1336 typedef typename traits_t<T>::unsigned_t UT;
1337 typedef typename traits_t<T>::signed_t ST;
1338 typedef typename traits_t<T>::floating_t DBL;
1343 UT limit, trip, init;
1344 kmp_info_t *th = __kmp_threads[gtid];
1345 kmp_team_t *team = th->th.th_team;
1347 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
1348 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
1349 KMP_DEBUG_ASSERT(pr);
1350 KMP_DEBUG_ASSERT(sh);
1351 KMP_DEBUG_ASSERT(tid >= 0 && tid < nproc);
1357 __kmp_str_format(
"__kmp_dispatch_next_algorithm: T#%%d called pr:%%p "
1358 "sh:%%p nproc:%%%s tid:%%%s\n",
1359 traits_t<T>::spec, traits_t<T>::spec);
1360 KD_TRACE(10, (buff, gtid, pr, sh, nproc, tid));
1361 __kmp_str_free(&buff);
1366 if (pr->u.p.tc == 0) {
1368 (
"__kmp_dispatch_next_algorithm: T#%d early exit trip count is "
1374 switch (pr->schedule) {
1375#if KMP_STATIC_STEAL_ENABLED
1376 case kmp_sch_static_steal: {
1377 T chunk = pr->u.p.parm1;
1378 UT nchunks = pr->u.p.parm2;
1380 (
"__kmp_dispatch_next_algorithm: T#%d kmp_sch_static_steal case\n",
1383 trip = pr->u.p.tc - 1;
1385 if (traits_t<T>::type_size > 4) {
1388 kmp_lock_t *lck = pr->u.p.steal_lock;
1389 KMP_DEBUG_ASSERT(lck != NULL);
1390 if (pr->u.p.count < (UT)pr->u.p.ub) {
1391 KMP_DEBUG_ASSERT(pr->steal_flag == READY);
1392 __kmp_acquire_lock(lck, gtid);
1394 init = (pr->u.p.count)++;
1395 status = (init < (UT)pr->u.p.ub);
1396 __kmp_release_lock(lck, gtid);
1402 T while_limit = pr->u.p.parm3;
1404 int idx = (th->th.th_dispatch->th_disp_index - 1) %
1405 __kmp_dispatch_num_buffers;
1407 KMP_ATOMIC_ST_REL(&pr->steal_flag, THIEF);
1408 while ((!status) && (while_limit != ++while_index)) {
1409 dispatch_private_info_template<T> *v;
1411 T victimId = pr->u.p.parm4;
1412 T oldVictimId = victimId ? victimId - 1 : nproc - 1;
1413 v =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1414 &team->t.t_dispatch[victimId].th_disp_buffer[idx]);
1415 KMP_DEBUG_ASSERT(v);
1416 while ((v == pr || KMP_ATOMIC_LD_RLX(&v->steal_flag) == THIEF) &&
1417 oldVictimId != victimId) {
1418 victimId = (victimId + 1) % nproc;
1419 v =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1420 &team->t.t_dispatch[victimId].th_disp_buffer[idx]);
1421 KMP_DEBUG_ASSERT(v);
1423 if (v == pr || KMP_ATOMIC_LD_RLX(&v->steal_flag) == THIEF) {
1426 if (KMP_ATOMIC_LD_RLX(&v->steal_flag) == UNUSED) {
1427 kmp_uint32 old = UNUSED;
1429 status = v->steal_flag.compare_exchange_strong(old, THIEF);
1433 T small_chunk = 0, extras = 0, p_extra = 0;
1434 __kmp_initialize_self_buffer<T>(team,
id, pr, nchunks, nproc,
1435 init, small_chunk, extras,
1437 __kmp_acquire_lock(lck, gtid);
1438 pr->u.p.count = init + 1;
1439 pr->u.p.ub = init + small_chunk + p_extra + (
id < extras ? 1 : 0);
1440 __kmp_release_lock(lck, gtid);
1441 pr->u.p.parm4 = (
id + 1) % nproc;
1447 buff = __kmp_str_format(
"__kmp_dispatch_next_algorithm: T#%%d "
1448 "stolen chunks from T#%%d, "
1449 "count:%%%s ub:%%%s\n",
1450 traits_t<UT>::spec, traits_t<T>::spec);
1451 KD_TRACE(10, (buff, gtid,
id, pr->u.p.count, pr->u.p.ub));
1452 __kmp_str_free(&buff);
1456 if (pr->u.p.count < (UT)pr->u.p.ub)
1457 KMP_ATOMIC_ST_REL(&pr->steal_flag, READY);
1461 if (KMP_ATOMIC_LD_ACQ(&v->steal_flag) != READY ||
1462 v->u.p.count >= (UT)v->u.p.ub) {
1463 pr->u.p.parm4 = (victimId + 1) % nproc;
1466 lckv = v->u.p.steal_lock;
1467 KMP_ASSERT(lckv != NULL);
1468 __kmp_acquire_lock(lckv, gtid);
1470 if (v->u.p.count >= limit) {
1471 __kmp_release_lock(lckv, gtid);
1472 pr->u.p.parm4 = (victimId + 1) % nproc;
1478 remaining = limit - v->u.p.count;
1479 if (remaining > 7) {
1481 KMP_COUNT_DEVELOPER_VALUE(FOR_static_steal_stolen, remaining >> 2);
1482 init = (v->u.p.ub -= (remaining >> 2));
1485 KMP_COUNT_DEVELOPER_VALUE(FOR_static_steal_stolen, 1);
1486 init = (v->u.p.ub -= 1);
1488 __kmp_release_lock(lckv, gtid);
1493 buff = __kmp_str_format(
1494 "__kmp_dispatch_next: T#%%d stolen chunks from T#%%d, "
1495 "count:%%%s ub:%%%s\n",
1496 traits_t<UT>::spec, traits_t<UT>::spec);
1497 KD_TRACE(10, (buff, gtid, victimId, init, limit));
1498 __kmp_str_free(&buff);
1501 KMP_DEBUG_ASSERT(init + 1 <= limit);
1502 pr->u.p.parm4 = victimId;
1505 __kmp_acquire_lock(lck, gtid);
1506 pr->u.p.count = init + 1;
1508 __kmp_release_lock(lck, gtid);
1510 if (init + 1 < limit)
1511 KMP_ATOMIC_ST_REL(&pr->steal_flag, READY);
1524 union_i4 vold, vnew;
1525 if (pr->u.p.count < (UT)pr->u.p.ub) {
1526 KMP_DEBUG_ASSERT(pr->steal_flag == READY);
1527 vold.b = *(
volatile kmp_int64 *)(&pr->u.p.count);
1530 while (!KMP_COMPARE_AND_STORE_REL64(
1531 (
volatile kmp_int64 *)&pr->u.p.count,
1532 *VOLATILE_CAST(kmp_int64 *) & vold.b,
1533 *VOLATILE_CAST(kmp_int64 *) & vnew.b)) {
1535 vold.b = *(
volatile kmp_int64 *)(&pr->u.p.count);
1539 init = vold.p.count;
1540 status = (init < (UT)vold.p.ub);
1545 T while_limit = pr->u.p.parm3;
1547 int idx = (th->th.th_dispatch->th_disp_index - 1) %
1548 __kmp_dispatch_num_buffers;
1550 KMP_ATOMIC_ST_REL(&pr->steal_flag, THIEF);
1551 while ((!status) && (while_limit != ++while_index)) {
1552 dispatch_private_info_template<T> *v;
1554 T victimId = pr->u.p.parm4;
1555 T oldVictimId = victimId ? victimId - 1 : nproc - 1;
1556 v =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1557 &team->t.t_dispatch[victimId].th_disp_buffer[idx]);
1558 KMP_DEBUG_ASSERT(v);
1559 while ((v == pr || KMP_ATOMIC_LD_RLX(&v->steal_flag) == THIEF) &&
1560 oldVictimId != victimId) {
1561 victimId = (victimId + 1) % nproc;
1562 v =
reinterpret_cast<dispatch_private_info_template<T> *
>(
1563 &team->t.t_dispatch[victimId].th_disp_buffer[idx]);
1564 KMP_DEBUG_ASSERT(v);
1566 if (v == pr || KMP_ATOMIC_LD_RLX(&v->steal_flag) == THIEF) {
1569 if (KMP_ATOMIC_LD_RLX(&v->steal_flag) == UNUSED) {
1570 kmp_uint32 old = UNUSED;
1572 status = v->steal_flag.compare_exchange_strong(old, THIEF);
1576 T small_chunk = 0, extras = 0, p_extra = 0;
1577 __kmp_initialize_self_buffer<T>(team,
id, pr, nchunks, nproc,
1578 init, small_chunk, extras,
1580 vnew.p.count = init + 1;
1581 vnew.p.ub = init + small_chunk + p_extra + (
id < extras ? 1 : 0);
1584 KMP_XCHG_FIXED64((
volatile kmp_int64 *)(&pr->u.p.count), vnew.b);
1586 *(
volatile kmp_int64 *)(&pr->u.p.count) = vnew.b;
1588 pr->u.p.parm4 = (
id + 1) % nproc;
1594 buff = __kmp_str_format(
"__kmp_dispatch_next_algorithm: T#%%d "
1595 "stolen chunks from T#%%d, "
1596 "count:%%%s ub:%%%s\n",
1597 traits_t<UT>::spec, traits_t<T>::spec);
1598 KD_TRACE(10, (buff, gtid,
id, pr->u.p.count, pr->u.p.ub));
1599 __kmp_str_free(&buff);
1603 if (pr->u.p.count < (UT)pr->u.p.ub)
1604 KMP_ATOMIC_ST_REL(&pr->steal_flag, READY);
1610 vold.b = *(
volatile kmp_int64 *)(&v->u.p.count);
1611 if (KMP_ATOMIC_LD_ACQ(&v->steal_flag) != READY ||
1612 vold.p.count >= (UT)vold.p.ub) {
1613 pr->u.p.parm4 = (victimId + 1) % nproc;
1617 remaining = vold.p.ub - vold.p.count;
1620 if (remaining > 7) {
1621 vnew.p.ub -= remaining >> 2;
1625 KMP_DEBUG_ASSERT(vnew.p.ub * (UT)chunk <= trip);
1626 if (KMP_COMPARE_AND_STORE_REL64(
1627 (
volatile kmp_int64 *)&v->u.p.count,
1628 *VOLATILE_CAST(kmp_int64 *) & vold.b,
1629 *VOLATILE_CAST(kmp_int64 *) & vnew.b)) {
1635 buff = __kmp_str_format(
1636 "__kmp_dispatch_next: T#%%d stolen chunks from T#%%d, "
1637 "count:%%%s ub:%%%s\n",
1638 traits_t<T>::spec, traits_t<T>::spec);
1639 KD_TRACE(10, (buff, gtid, victimId, vnew.p.ub, vold.p.ub));
1640 __kmp_str_free(&buff);
1643 KMP_COUNT_DEVELOPER_VALUE(FOR_static_steal_stolen,
1644 vold.p.ub - vnew.p.ub);
1646 pr->u.p.parm4 = victimId;
1649 vold.p.count = init + 1;
1651 KMP_XCHG_FIXED64((
volatile kmp_int64 *)(&pr->u.p.count), vold.b);
1653 *(
volatile kmp_int64 *)(&pr->u.p.count) = vold.b;
1656 if (vold.p.count < (UT)vold.p.ub)
1657 KMP_ATOMIC_ST_REL(&pr->steal_flag, READY);
1673 limit = chunk + init - 1;
1675 KMP_COUNT_DEVELOPER_VALUE(FOR_static_steal_chunks, 1);
1677 KMP_DEBUG_ASSERT(init <= trip);
1681 if ((last = (limit >= trip)) != 0)
1687 *p_lb = start + init;
1688 *p_ub = start + limit;
1690 *p_lb = start + init * incr;
1691 *p_ub = start + limit * incr;
1697 case kmp_sch_static_balanced: {
1700 (
"__kmp_dispatch_next_algorithm: T#%d kmp_sch_static_balanced case\n",
1703 if ((status = !pr->u.p.count) != 0) {
1707 last = (pr->u.p.parm1 != 0);
1711 pr->u.p.lb = pr->u.p.ub + pr->u.p.st;
1715 case kmp_sch_static_greedy:
1717 case kmp_sch_static_chunked: {
1720 KD_TRACE(100, (
"__kmp_dispatch_next_algorithm: T#%d "
1721 "kmp_sch_static_[affinity|chunked] case\n",
1723 parm1 = pr->u.p.parm1;
1725 trip = pr->u.p.tc - 1;
1726 init = parm1 * (pr->u.p.count + tid);
1728 if ((status = (init <= trip)) != 0) {
1731 limit = parm1 + init - 1;
1733 if ((last = (limit >= trip)) != 0)
1739 pr->u.p.count += nproc;
1742 *p_lb = start + init;
1743 *p_ub = start + limit;
1745 *p_lb = start + init * incr;
1746 *p_ub = start + limit * incr;
1749 if (pr->flags.ordered) {
1750 pr->u.p.ordered_lower = init;
1751 pr->u.p.ordered_upper = limit;
1757 case kmp_sch_dynamic_chunked: {
1759 UT chunk_size = pr->u.p.parm1;
1760 UT nchunks = pr->u.p.parm2;
1764 (
"__kmp_dispatch_next_algorithm: T#%d kmp_sch_dynamic_chunked case\n",
1767 chunk_number = test_then_inc_acq<ST>((
volatile ST *)&sh->u.s.iteration);
1768 status = (chunk_number < nchunks);
1775 init = chunk_size * chunk_number;
1776 trip = pr->u.p.tc - 1;
1780 if ((last = (trip - init < (UT)chunk_size)))
1783 limit = chunk_size + init - 1;
1789 *p_lb = start + init;
1790 *p_ub = start + limit;
1792 *p_lb = start + init * incr;
1793 *p_ub = start + limit * incr;
1796 if (pr->flags.ordered) {
1797 pr->u.p.ordered_lower = init;
1798 pr->u.p.ordered_upper = limit;
1804 case kmp_sch_guided_iterative_chunked: {
1805 T chunkspec = pr->u.p.parm1;
1806 KD_TRACE(100, (
"__kmp_dispatch_next_algorithm: T#%d kmp_sch_guided_chunked "
1813 init = sh->u.s.iteration;
1814 remaining = trip - init;
1815 if (remaining <= 0) {
1824 init = test_then_add<ST>(RCAST(
volatile ST *, &sh->u.s.iteration),
1826 remaining = trip - init;
1827 if (remaining <= 0) {
1832 if ((T)remaining > chunkspec) {
1833 limit = init + chunkspec - 1;
1836 limit = init + remaining - 1;
1841 limit = init + (UT)((
double)remaining *
1842 *(
double *)&pr->u.p.parm3);
1843 if (compare_and_swap<ST>(RCAST(
volatile ST *, &sh->u.s.iteration),
1844 (ST)init, (ST)limit)) {
1856 *p_lb = start + init * incr;
1857 *p_ub = start + limit * incr;
1858 if (pr->flags.ordered) {
1859 pr->u.p.ordered_lower = init;
1860 pr->u.p.ordered_upper = limit;
1874 T chunk = pr->u.p.parm1;
1876 (
"__kmp_dispatch_next_algorithm: T#%d kmp_sch_guided_simd case\n",
1882 init = sh->u.s.iteration;
1883 remaining = trip - init;
1884 if (remaining <= 0) {
1888 KMP_DEBUG_ASSERT(chunk && init % chunk == 0);
1890 if ((T)remaining < pr->u.p.parm2) {
1893 init = test_then_add<ST>(RCAST(
volatile ST *, &sh->u.s.iteration),
1895 remaining = trip - init;
1896 if (remaining <= 0) {
1901 if ((T)remaining > chunk) {
1902 limit = init + chunk - 1;
1905 limit = init + remaining - 1;
1912 __kmp_type_convert((
double)remaining * (*(
double *)&pr->u.p.parm3),
1914 UT rem = span % chunk;
1916 span += chunk - rem;
1917 limit = init + span;
1918 if (compare_and_swap<ST>(RCAST(
volatile ST *, &sh->u.s.iteration),
1919 (ST)init, (ST)limit)) {
1931 *p_lb = start + init * incr;
1932 *p_ub = start + limit * incr;
1933 if (pr->flags.ordered) {
1934 pr->u.p.ordered_lower = init;
1935 pr->u.p.ordered_upper = limit;
1946 case kmp_sch_guided_analytical_chunked: {
1947 T chunkspec = pr->u.p.parm1;
1949#if KMP_USE_X87CONTROL
1952 unsigned int oldFpcw;
1953 unsigned int fpcwSet = 0;
1955 KD_TRACE(100, (
"__kmp_dispatch_next_algorithm: T#%d "
1956 "kmp_sch_guided_analytical_chunked case\n",
1961 KMP_DEBUG_ASSERT(nproc > 1);
1962 KMP_DEBUG_ASSERT((2UL * chunkspec + 1) * (UT)nproc < trip);
1966 chunkIdx = test_then_inc_acq<ST>((
volatile ST *)&sh->u.s.iteration);
1967 if (chunkIdx >= (UT)pr->u.p.parm2) {
1970 init = chunkIdx * chunkspec + pr->u.p.count;
1973 if ((status = (init > 0 && init <= trip)) != 0) {
1974 limit = init + chunkspec - 1;
1976 if ((last = (limit >= trip)) != 0)
1986#if KMP_USE_X87CONTROL
1991 oldFpcw = _control87(0, 0);
1992 _control87(_PC_64, _MCW_PC);
1997 init = __kmp_dispatch_guided_remaining<T>(
1998 trip, *(DBL *)&pr->u.p.parm3, chunkIdx);
1999 KMP_DEBUG_ASSERT(init);
2003 limit = trip - __kmp_dispatch_guided_remaining<T>(
2004 trip, *(DBL *)&pr->u.p.parm3, chunkIdx + 1);
2005 KMP_ASSERT(init <= limit);
2007 KMP_DEBUG_ASSERT(limit <= trip);
2014#if KMP_USE_X87CONTROL
2018 if (fpcwSet && (oldFpcw & fpcwSet))
2019 _control87(oldFpcw, _MCW_PC);
2026 *p_lb = start + init * incr;
2027 *p_ub = start + limit * incr;
2028 if (pr->flags.ordered) {
2029 pr->u.p.ordered_lower = init;
2030 pr->u.p.ordered_upper = limit;
2041 case kmp_sch_trapezoidal: {
2043 T parm2 = pr->u.p.parm2;
2044 T parm3 = pr->u.p.parm3;
2045 T parm4 = pr->u.p.parm4;
2047 (
"__kmp_dispatch_next_algorithm: T#%d kmp_sch_trapezoidal case\n",
2050 index = test_then_inc<ST>((
volatile ST *)&sh->u.s.iteration);
2052 init = (index * ((2 * parm2) - (index - 1) * parm4)) / 2;
2053 trip = pr->u.p.tc - 1;
2055 if ((status = ((T)index < parm3 && init <= trip)) == 0) {
2062 limit = ((index + 1) * (2 * parm2 - index * parm4)) / 2 - 1;
2065 if ((last = (limit >= trip)) != 0)
2072 *p_lb = start + init;
2073 *p_ub = start + limit;
2075 *p_lb = start + init * incr;
2076 *p_ub = start + limit * incr;
2079 if (pr->flags.ordered) {
2080 pr->u.p.ordered_lower = init;
2081 pr->u.p.ordered_upper = limit;
2088 __kmp_fatal(KMP_MSG(UnknownSchedTypeDetected),
2089 KMP_HNT(GetNewerLibrary),
2097 if (pr->flags.ordered) {
2100 buff = __kmp_str_format(
"__kmp_dispatch_next_algorithm: T#%%d "
2101 "ordered_lower:%%%s ordered_upper:%%%s\n",
2102 traits_t<UT>::spec, traits_t<UT>::spec);
2103 KD_TRACE(1000, (buff, gtid, pr->u.p.ordered_lower, pr->u.p.ordered_upper));
2104 __kmp_str_free(&buff);
2109 buff = __kmp_str_format(
2110 "__kmp_dispatch_next_algorithm: T#%%d exit status:%%d p_last:%%d "
2111 "p_lb:%%%s p_ub:%%%s p_st:%%%s\n",
2112 traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec);
2113 KMP_DEBUG_ASSERT(p_last);
2114 KMP_DEBUG_ASSERT(p_st);
2115 KD_TRACE(10, (buff, gtid, status, *p_last, *p_lb, *p_ub, *p_st));
2116 __kmp_str_free(&buff);
2125#if OMPT_SUPPORT && OMPT_OPTIONAL
2126#define OMPT_LOOP_END \
2127 if (status == 0) { \
2128 if (ompt_enabled.ompt_callback_work) { \
2129 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); \
2130 ompt_task_info_t *task_info = __ompt_get_task_info_object(0); \
2131 ompt_callbacks.ompt_callback(ompt_callback_work)( \
2132 ompt_get_work_schedule(pr->schedule), ompt_scope_end, \
2133 &(team_info->parallel_data), &(task_info->task_data), 0, codeptr); \
2136#define OMPT_LOOP_DISPATCH(lb, ub, st, status) \
2137 if (ompt_enabled.ompt_callback_dispatch && status) { \
2138 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); \
2139 ompt_task_info_t *task_info = __ompt_get_task_info_object(0); \
2140 ompt_dispatch_chunk_t chunk; \
2141 ompt_data_t instance = ompt_data_none; \
2142 OMPT_GET_DISPATCH_CHUNK(chunk, lb, ub, st); \
2143 instance.ptr = &chunk; \
2144 ompt_callbacks.ompt_callback(ompt_callback_dispatch)( \
2145 &(team_info->parallel_data), &(task_info->task_data), \
2146 ompt_dispatch_ws_loop_chunk, instance); \
2150#define OMPT_LOOP_END
2151#define OMPT_LOOP_DISPATCH(lb, ub, st, status)
2154#if KMP_STATS_ENABLED
2155#define KMP_STATS_LOOP_END \
2157 kmp_int64 u, l, t, i; \
2158 l = (kmp_int64)(*p_lb); \
2159 u = (kmp_int64)(*p_ub); \
2160 i = (kmp_int64)(pr->u.p.st); \
2161 if (status == 0) { \
2163 KMP_POP_PARTITIONED_TIMER(); \
2164 } else if (i == 1) { \
2169 } else if (i < 0) { \
2171 t = (l - u) / (-i) + 1; \
2176 t = (u - l) / i + 1; \
2180 KMP_COUNT_VALUE(OMP_loop_dynamic_iterations, t); \
2183#define KMP_STATS_LOOP_END
2186template <
typename T>
2187static int __kmp_dispatch_next(
ident_t *loc,
int gtid, kmp_int32 *p_last,
2189 typename traits_t<T>::signed_t *p_st
2190#
if OMPT_SUPPORT && OMPT_OPTIONAL
2196 typedef typename traits_t<T>::unsigned_t UT;
2197 typedef typename traits_t<T>::signed_t ST;
2202 KMP_TIME_PARTITIONED_BLOCK(OMP_loop_dynamic_scheduling);
2205 dispatch_private_info_template<T> *pr;
2206 __kmp_assert_valid_gtid(gtid);
2207 kmp_info_t *th = __kmp_threads[gtid];
2208 kmp_team_t *team = th->th.th_team;
2210 KMP_DEBUG_ASSERT(p_lb && p_ub && p_st);
2213 (
"__kmp_dispatch_next: T#%d called p_lb:%p p_ub:%p p_st:%p p_last: %p\n",
2214 gtid, p_lb, p_ub, p_st, p_last));
2216 if (team->t.t_serialized) {
2218 pr =
reinterpret_cast<dispatch_private_info_template<T> *
>(
2219 th->th.th_dispatch->th_disp_buffer);
2220 KMP_DEBUG_ASSERT(pr);
2222 if ((status = (pr->u.p.tc != 0)) == 0) {
2229 if (__kmp_env_consistency_check) {
2230 if (pr->pushed_ws != ct_none) {
2231 pr->pushed_ws = __kmp_pop_workshare(gtid, pr->pushed_ws, loc);
2234 }
else if (pr->flags.nomerge) {
2237 UT limit, trip, init;
2239 T chunk = pr->u.p.parm1;
2241 KD_TRACE(100, (
"__kmp_dispatch_next: T#%d kmp_sch_dynamic_chunked case\n",
2244 init = chunk * pr->u.p.count++;
2245 trip = pr->u.p.tc - 1;
2247 if ((status = (init <= trip)) == 0) {
2254 if (__kmp_env_consistency_check) {
2255 if (pr->pushed_ws != ct_none) {
2256 pr->pushed_ws = __kmp_pop_workshare(gtid, pr->pushed_ws, loc);
2261 limit = chunk + init - 1;
2264 if ((last = (limit >= trip)) != 0) {
2267 pr->u.p.last_upper = pr->u.p.ub;
2275 *p_lb = start + init;
2276 *p_ub = start + limit;
2278 *p_lb = start + init * incr;
2279 *p_ub = start + limit * incr;
2282 if (pr->flags.ordered) {
2283 pr->u.p.ordered_lower = init;
2284 pr->u.p.ordered_upper = limit;
2289 buff = __kmp_str_format(
"__kmp_dispatch_next: T#%%d "
2290 "ordered_lower:%%%s ordered_upper:%%%s\n",
2291 traits_t<UT>::spec, traits_t<UT>::spec);
2292 KD_TRACE(1000, (buff, gtid, pr->u.p.ordered_lower,
2293 pr->u.p.ordered_upper));
2294 __kmp_str_free(&buff);
2304 pr->u.p.last_upper = *p_ub;
2315 buff = __kmp_str_format(
2316 "__kmp_dispatch_next: T#%%d serialized case: p_lb:%%%s "
2317 "p_ub:%%%s p_st:%%%s p_last:%%p %%d returning:%%d\n",
2318 traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec);
2319 KD_TRACE(10, (buff, gtid, *p_lb, *p_ub, *p_st, p_last,
2320 (p_last ? *p_last : 0), status));
2321 __kmp_str_free(&buff);
2324#if INCLUDE_SSC_MARKS
2325 SSC_MARK_DISPATCH_NEXT();
2327 OMPT_LOOP_DISPATCH(*p_lb, *p_ub, pr->u.p.st, status);
2333 dispatch_shared_info_template<T>
volatile *sh;
2335 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
2336 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
2338 pr =
reinterpret_cast<dispatch_private_info_template<T> *
>(
2339 th->th.th_dispatch->th_dispatch_pr_current);
2340 KMP_DEBUG_ASSERT(pr);
2341 sh =
reinterpret_cast<dispatch_shared_info_template<T>
volatile *
>(
2342 th->th.th_dispatch->th_dispatch_sh_current);
2343 KMP_DEBUG_ASSERT(sh);
2345#if KMP_USE_HIER_SCHED
2346 if (pr->flags.use_hier)
2347 status = sh->hier->next(loc, gtid, pr, &last, p_lb, p_ub, p_st);
2350 status = __kmp_dispatch_next_algorithm<T>(gtid, pr, sh, &last, p_lb, p_ub,
2351 p_st, th->th.th_team_nproc,
2352 th->th.th_info.ds.ds_tid);
2356 num_done = test_then_inc<ST>(&sh->u.s.num_done);
2361 buff = __kmp_str_format(
2362 "__kmp_dispatch_next: T#%%d increment num_done:%%%s\n",
2363 traits_t<ST>::spec);
2364 KD_TRACE(10, (buff, gtid, sh->u.s.num_done));
2365 __kmp_str_free(&buff);
2369#if KMP_USE_HIER_SCHED
2370 pr->flags.use_hier = FALSE;
2372 if (num_done == th->th.th_team_nproc - 1) {
2373#if KMP_STATIC_STEAL_ENABLED
2374 if (pr->schedule == kmp_sch_static_steal) {
2376 int idx = (th->th.th_dispatch->th_disp_index - 1) %
2377 __kmp_dispatch_num_buffers;
2379 for (i = 0; i < th->th.th_team_nproc; ++i) {
2380 dispatch_private_info_template<T> *buf =
2381 reinterpret_cast<dispatch_private_info_template<T> *
>(
2382 &team->t.t_dispatch[i].th_disp_buffer[idx]);
2383 KMP_ASSERT(buf->steal_flag == THIEF);
2384 KMP_ATOMIC_ST_RLX(&buf->steal_flag, UNUSED);
2385 if (traits_t<T>::type_size > 4) {
2387 kmp_lock_t *lck = buf->u.p.steal_lock;
2388 KMP_ASSERT(lck != NULL);
2389 __kmp_destroy_lock(lck);
2391 buf->u.p.steal_lock = NULL;
2400 sh->u.s.num_done = 0;
2401 sh->u.s.iteration = 0;
2404 if (pr->flags.ordered) {
2405 sh->u.s.ordered_iteration = 0;
2410 sh->buffer_index += __kmp_dispatch_num_buffers;
2411 KD_TRACE(100, (
"__kmp_dispatch_next: T#%d change buffer_index:%d\n",
2412 gtid, sh->buffer_index));
2417 if (__kmp_env_consistency_check) {
2418 if (pr->pushed_ws != ct_none) {
2419 pr->pushed_ws = __kmp_pop_workshare(gtid, pr->pushed_ws, loc);
2423 th->th.th_dispatch->th_deo_fcn = NULL;
2424 th->th.th_dispatch->th_dxo_fcn = NULL;
2425 th->th.th_dispatch->th_dispatch_sh_current = NULL;
2426 th->th.th_dispatch->th_dispatch_pr_current = NULL;
2430 pr->u.p.last_upper = pr->u.p.ub;
2433 if (p_last != NULL && status != 0)
2441 buff = __kmp_str_format(
2442 "__kmp_dispatch_next: T#%%d normal case: "
2443 "p_lb:%%%s p_ub:%%%s p_st:%%%s p_last:%%p (%%d) returning:%%d\n",
2444 traits_t<T>::spec, traits_t<T>::spec, traits_t<ST>::spec);
2445 KD_TRACE(10, (buff, gtid, *p_lb, *p_ub, p_st ? *p_st : 0, p_last,
2446 (p_last ? *p_last : 0), status));
2447 __kmp_str_free(&buff);
2450#if INCLUDE_SSC_MARKS
2451 SSC_MARK_DISPATCH_NEXT();
2453 OMPT_LOOP_DISPATCH(*p_lb, *p_ub, pr->u.p.st, status);
2479 kmp_uint32 my_buffer_index;
2480 dispatch_shared_info_template<kmp_int32>
volatile *sh;
2482 KMP_DEBUG_ASSERT(__kmp_init_serial);
2484 if (!TCR_4(__kmp_init_parallel))
2485 __kmp_parallel_initialize();
2486 __kmp_resume_if_soft_paused();
2489 th = __kmp_threads[gtid];
2490 team = th->th.th_team;
2491 active = !team->t.t_serialized;
2492 th->th.th_ident = loc;
2495 KD_TRACE(10, (
"__kmpc_sections: called by T#%d\n", gtid));
2502 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
2503 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
2505 my_buffer_index = th->th.th_dispatch->th_disp_index++;
2508 sh =
reinterpret_cast<dispatch_shared_info_template<kmp_int32>
volatile *
>(
2509 &team->t.t_disp_buffer[my_buffer_index % __kmp_dispatch_num_buffers]);
2510 KD_TRACE(10, (
"__kmpc_sections_init: T#%d my_buffer_index:%d\n", gtid,
2513 th->th.th_dispatch->th_deo_fcn = __kmp_dispatch_deo_error;
2514 th->th.th_dispatch->th_dxo_fcn = __kmp_dispatch_dxo_error;
2516 KD_TRACE(100, (
"__kmpc_sections_init: T#%d before wait: my_buffer_index:%d "
2517 "sh->buffer_index:%d\n",
2518 gtid, my_buffer_index, sh->buffer_index));
2519 __kmp_wait<kmp_uint32>(&sh->buffer_index, my_buffer_index,
2520 __kmp_eq<kmp_uint32> USE_ITT_BUILD_ARG(NULL));
2524 KD_TRACE(100, (
"__kmpc_sections_init: T#%d after wait: my_buffer_index:%d "
2525 "sh->buffer_index:%d\n",
2526 gtid, my_buffer_index, sh->buffer_index));
2528 th->th.th_dispatch->th_dispatch_pr_current =
2530 th->th.th_dispatch->th_dispatch_sh_current =
2531 CCAST(dispatch_shared_info_t *, (
volatile dispatch_shared_info_t *)sh);
2534#if OMPT_SUPPORT && OMPT_OPTIONAL
2535 if (ompt_enabled.ompt_callback_work) {
2536 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
2537 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
2538 ompt_callbacks.ompt_callback(ompt_callback_work)(
2539 ompt_work_sections, ompt_scope_begin, &(team_info->parallel_data),
2540 &(task_info->task_data), 0, OMPT_GET_RETURN_ADDRESS(0));
2543 KMP_PUSH_PARTITIONED_TIMER(OMP_sections);
2559 kmp_int32 numberOfSections) {
2561 KMP_TIME_PARTITIONED_BLOCK(OMP_sections_overhead);
2563 kmp_info_t *th = __kmp_threads[gtid];
2565 kmp_team_t *team = th->th.th_team;
2568 KD_TRACE(1000, (
"__kmp_dispatch_next: T#%d; number of sections:%d\n", gtid,
2572 KMP_DEBUG_ASSERT(!team->t.t_serialized);
2574 dispatch_shared_info_template<kmp_int32>
volatile *sh;
2576 KMP_DEBUG_ASSERT(th->th.th_dispatch ==
2577 &th->th.th_team->t.t_dispatch[th->th.th_info.ds.ds_tid]);
2579 KMP_DEBUG_ASSERT(!(th->th.th_dispatch->th_dispatch_pr_current));
2580 sh =
reinterpret_cast<dispatch_shared_info_template<kmp_int32>
volatile *
>(
2581 th->th.th_dispatch->th_dispatch_sh_current);
2582 KMP_DEBUG_ASSERT(sh);
2584 kmp_int32 sectionIndex = 0;
2585 bool moreSectionsToExecute =
true;
2588 sectionIndex = test_then_inc<kmp_int32>((kmp_int32 *)&sh->u.s.iteration);
2589 if (sectionIndex >= numberOfSections) {
2590 moreSectionsToExecute =
false;
2595 if (!moreSectionsToExecute) {
2598 num_done = test_then_inc<kmp_int32>((kmp_int32 *)(&sh->u.s.num_done));
2600 if (num_done == th->th.th_team_nproc - 1) {
2605 sh->u.s.num_done = 0;
2606 sh->u.s.iteration = 0;
2610 sh->buffer_index += __kmp_dispatch_num_buffers;
2611 KD_TRACE(100, (
"__kmpc_next_section: T#%d change buffer_index:%d\n", gtid,
2618 th->th.th_dispatch->th_deo_fcn = NULL;
2619 th->th.th_dispatch->th_dxo_fcn = NULL;
2620 th->th.th_dispatch->th_dispatch_sh_current = NULL;
2621 th->th.th_dispatch->th_dispatch_pr_current = NULL;
2623#if OMPT_SUPPORT && OMPT_OPTIONAL
2624 if (ompt_enabled.ompt_callback_dispatch) {
2625 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
2626 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
2627 ompt_data_t instance = ompt_data_none;
2628 instance.ptr = OMPT_GET_RETURN_ADDRESS(0);
2629 ompt_callbacks.ompt_callback(ompt_callback_dispatch)(
2630 &(team_info->parallel_data), &(task_info->task_data),
2631 ompt_dispatch_section, instance);
2636 return sectionIndex;
2649 kmp_info_t *th = __kmp_threads[gtid];
2650 int active = !th->th.th_team->t.t_serialized;
2652 KD_TRACE(100, (
"__kmpc_end_sections: T#%d called\n", gtid));
2656#if OMPT_SUPPORT && OMPT_OPTIONAL
2657 if (ompt_enabled.ompt_callback_work) {
2658 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
2659 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
2660 ompt_callbacks.ompt_callback(ompt_callback_work)(
2661 ompt_work_sections, ompt_scope_end, &(team_info->parallel_data),
2662 &(task_info->task_data), 0, OMPT_GET_RETURN_ADDRESS(0));
2667 KMP_POP_PARTITIONED_TIMER();
2668 KD_TRACE(100, (
"__kmpc_end_sections: T#%d returned\n", gtid));
2671template <
typename T>
2672static void __kmp_dist_get_bounds(
ident_t *loc, kmp_int32 gtid,
2673 kmp_int32 *plastiter, T *plower, T *pupper,
2674 typename traits_t<T>::signed_t incr) {
2675 typedef typename traits_t<T>::unsigned_t UT;
2682 KMP_DEBUG_ASSERT(plastiter && plower && pupper);
2683 KE_TRACE(10, (
"__kmpc_dist_get_bounds called (%d)\n", gtid));
2685 typedef typename traits_t<T>::signed_t ST;
2689 buff = __kmp_str_format(
"__kmpc_dist_get_bounds: T#%%d liter=%%d "
2690 "iter=(%%%s, %%%s, %%%s) signed?<%s>\n",
2691 traits_t<T>::spec, traits_t<T>::spec,
2692 traits_t<ST>::spec, traits_t<T>::spec);
2693 KD_TRACE(100, (buff, gtid, *plastiter, *plower, *pupper, incr));
2694 __kmp_str_free(&buff);
2698 if (__kmp_env_consistency_check) {
2700 __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrZeroProhibited, ct_pdo,
2703 if (incr > 0 ? (*pupper < *plower) : (*plower < *pupper)) {
2713 __kmp_error_construct(kmp_i18n_msg_CnsLoopIncrIllegal, ct_pdo, loc);
2716 __kmp_assert_valid_gtid(gtid);
2717 th = __kmp_threads[gtid];
2718 team = th->th.th_team;
2719 KMP_DEBUG_ASSERT(th->th.th_teams_microtask);
2720 nteams = th->th.th_teams_size.nteams;
2721 team_id = team->t.t_master_tid;
2722 KMP_DEBUG_ASSERT(nteams == (kmp_uint32)team->t.t_parent->t.t_nproc);
2726 trip_count = *pupper - *plower + 1;
2727 }
else if (incr == -1) {
2728 trip_count = *plower - *pupper + 1;
2729 }
else if (incr > 0) {
2731 trip_count = (UT)(*pupper - *plower) / incr + 1;
2733 trip_count = (UT)(*plower - *pupper) / (-incr) + 1;
2736 if (trip_count <= nteams) {
2738 __kmp_static == kmp_sch_static_greedy ||
2740 kmp_sch_static_balanced);
2742 if (team_id < trip_count) {
2743 *pupper = *plower = *plower + team_id * incr;
2745 *plower = *pupper + incr;
2747 if (plastiter != NULL)
2748 *plastiter = (team_id == trip_count - 1);
2750 if (__kmp_static == kmp_sch_static_balanced) {
2751 UT chunk = trip_count / nteams;
2752 UT extras = trip_count % nteams;
2754 incr * (team_id * chunk + (team_id < extras ? team_id : extras));
2755 *pupper = *plower + chunk * incr - (team_id < extras ? 0 : incr);
2756 if (plastiter != NULL)
2757 *plastiter = (team_id == nteams - 1);
2760 (trip_count / nteams + ((trip_count % nteams) ? 1 : 0)) * incr;
2762 KMP_DEBUG_ASSERT(__kmp_static == kmp_sch_static_greedy);
2764 *plower += team_id * chunk_inc_count;
2765 *pupper = *plower + chunk_inc_count - incr;
2768 if (*pupper < *plower)
2769 *pupper = traits_t<T>::max_value;
2770 if (plastiter != NULL)
2771 *plastiter = *plower <= upper && *pupper > upper - incr;
2772 if (*pupper > upper)
2775 if (*pupper > *plower)
2776 *pupper = traits_t<T>::min_value;
2777 if (plastiter != NULL)
2778 *plastiter = *plower >= upper && *pupper < upper - incr;
2779 if (*pupper < upper)
2811 kmp_int32 ub, kmp_int32 st, kmp_int32 chunk) {
2812 KMP_DEBUG_ASSERT(__kmp_init_serial);
2813#if OMPT_SUPPORT && OMPT_OPTIONAL
2814 OMPT_STORE_RETURN_ADDRESS(gtid);
2816 __kmp_dispatch_init<kmp_int32>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2823 kmp_uint32 ub, kmp_int32 st, kmp_int32 chunk) {
2824 KMP_DEBUG_ASSERT(__kmp_init_serial);
2825#if OMPT_SUPPORT && OMPT_OPTIONAL
2826 OMPT_STORE_RETURN_ADDRESS(gtid);
2828 __kmp_dispatch_init<kmp_uint32>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2836 kmp_int64 ub, kmp_int64 st, kmp_int64 chunk) {
2837 KMP_DEBUG_ASSERT(__kmp_init_serial);
2838#if OMPT_SUPPORT && OMPT_OPTIONAL
2839 OMPT_STORE_RETURN_ADDRESS(gtid);
2841 __kmp_dispatch_init<kmp_int64>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2849 kmp_uint64 ub, kmp_int64 st, kmp_int64 chunk) {
2850 KMP_DEBUG_ASSERT(__kmp_init_serial);
2851#if OMPT_SUPPORT && OMPT_OPTIONAL
2852 OMPT_STORE_RETURN_ADDRESS(gtid);
2854 __kmp_dispatch_init<kmp_uint64>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2868 kmp_int32 lb, kmp_int32 ub, kmp_int32 st,
2870 KMP_DEBUG_ASSERT(__kmp_init_serial);
2871#if OMPT_SUPPORT && OMPT_OPTIONAL
2872 OMPT_STORE_RETURN_ADDRESS(gtid);
2874 __kmp_dist_get_bounds<kmp_int32>(loc, gtid, p_last, &lb, &ub, st);
2875 __kmp_dispatch_init<kmp_int32>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2878void __kmpc_dist_dispatch_init_4u(
ident_t *loc, kmp_int32 gtid,
2880 kmp_uint32 lb, kmp_uint32 ub, kmp_int32 st,
2882 KMP_DEBUG_ASSERT(__kmp_init_serial);
2883#if OMPT_SUPPORT && OMPT_OPTIONAL
2884 OMPT_STORE_RETURN_ADDRESS(gtid);
2886 __kmp_dist_get_bounds<kmp_uint32>(loc, gtid, p_last, &lb, &ub, st);
2887 __kmp_dispatch_init<kmp_uint32>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2890void __kmpc_dist_dispatch_init_8(
ident_t *loc, kmp_int32 gtid,
2892 kmp_int64 lb, kmp_int64 ub, kmp_int64 st,
2894 KMP_DEBUG_ASSERT(__kmp_init_serial);
2895#if OMPT_SUPPORT && OMPT_OPTIONAL
2896 OMPT_STORE_RETURN_ADDRESS(gtid);
2898 __kmp_dist_get_bounds<kmp_int64>(loc, gtid, p_last, &lb, &ub, st);
2899 __kmp_dispatch_init<kmp_int64>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2902void __kmpc_dist_dispatch_init_8u(
ident_t *loc, kmp_int32 gtid,
2904 kmp_uint64 lb, kmp_uint64 ub, kmp_int64 st,
2906 KMP_DEBUG_ASSERT(__kmp_init_serial);
2907#if OMPT_SUPPORT && OMPT_OPTIONAL
2908 OMPT_STORE_RETURN_ADDRESS(gtid);
2910 __kmp_dist_get_bounds<kmp_uint64>(loc, gtid, p_last, &lb, &ub, st);
2911 __kmp_dispatch_init<kmp_uint64>(loc, gtid, schedule, lb, ub, st, chunk,
true);
2928 kmp_int32 *p_lb, kmp_int32 *p_ub, kmp_int32 *p_st) {
2929#if OMPT_SUPPORT && OMPT_OPTIONAL
2930 OMPT_STORE_RETURN_ADDRESS(gtid);
2932 return __kmp_dispatch_next<kmp_int32>(loc, gtid, p_last, p_lb, p_ub, p_st
2933#
if OMPT_SUPPORT && OMPT_OPTIONAL
2935 OMPT_LOAD_RETURN_ADDRESS(gtid)
2944 kmp_uint32 *p_lb, kmp_uint32 *p_ub,
2946#if OMPT_SUPPORT && OMPT_OPTIONAL
2947 OMPT_STORE_RETURN_ADDRESS(gtid);
2949 return __kmp_dispatch_next<kmp_uint32>(loc, gtid, p_last, p_lb, p_ub, p_st
2950#
if OMPT_SUPPORT && OMPT_OPTIONAL
2952 OMPT_LOAD_RETURN_ADDRESS(gtid)
2961 kmp_int64 *p_lb, kmp_int64 *p_ub, kmp_int64 *p_st) {
2962#if OMPT_SUPPORT && OMPT_OPTIONAL
2963 OMPT_STORE_RETURN_ADDRESS(gtid);
2965 return __kmp_dispatch_next<kmp_int64>(loc, gtid, p_last, p_lb, p_ub, p_st
2966#
if OMPT_SUPPORT && OMPT_OPTIONAL
2968 OMPT_LOAD_RETURN_ADDRESS(gtid)
2977 kmp_uint64 *p_lb, kmp_uint64 *p_ub,
2979#if OMPT_SUPPORT && OMPT_OPTIONAL
2980 OMPT_STORE_RETURN_ADDRESS(gtid);
2982 return __kmp_dispatch_next<kmp_uint64>(loc, gtid, p_last, p_lb, p_ub, p_st
2983#
if OMPT_SUPPORT && OMPT_OPTIONAL
2985 OMPT_LOAD_RETURN_ADDRESS(gtid)
2997 __kmp_dispatch_finish<kmp_uint32>(gtid, loc);
3004 __kmp_dispatch_finish<kmp_uint64>(gtid, loc);
3011 __kmp_dispatch_finish<kmp_uint32>(gtid, loc);
3018 __kmp_dispatch_finish<kmp_uint64>(gtid, loc);
3030kmp_uint32 __kmp_eq_4(kmp_uint32 value, kmp_uint32 checker) {
3031 return value == checker;
3034kmp_uint32 __kmp_neq_4(kmp_uint32 value, kmp_uint32 checker) {
3035 return value != checker;
3038kmp_uint32 __kmp_lt_4(kmp_uint32 value, kmp_uint32 checker) {
3039 return value < checker;
3042kmp_uint32 __kmp_ge_4(kmp_uint32 value, kmp_uint32 checker) {
3043 return value >= checker;
3046kmp_uint32 __kmp_le_4(kmp_uint32 value, kmp_uint32 checker) {
3047 return value <= checker;
3051__kmp_wait_4(
volatile kmp_uint32 *spinner, kmp_uint32 checker,
3052 kmp_uint32 (*pred)(kmp_uint32, kmp_uint32),
3056 volatile kmp_uint32 *spin = spinner;
3057 kmp_uint32 check = checker;
3059 kmp_uint32 (*f)(kmp_uint32, kmp_uint32) = pred;
3063 KMP_FSYNC_SPIN_INIT(obj, CCAST(kmp_uint32 *, spin));
3064 KMP_INIT_YIELD(spins);
3065 KMP_INIT_BACKOFF(time);
3067 while (!f(r = TCR_4(*spin), check)) {
3068 KMP_FSYNC_SPIN_PREPARE(obj);
3073 KMP_YIELD_OVERSUB_ELSE_SPIN(spins, time);
3075 KMP_FSYNC_SPIN_ACQUIRED(obj);
3079void __kmp_wait_4_ptr(
void *spinner, kmp_uint32 checker,
3080 kmp_uint32 (*pred)(
void *, kmp_uint32),
3084 void *spin = spinner;
3085 kmp_uint32 check = checker;
3087 kmp_uint32 (*f)(
void *, kmp_uint32) = pred;
3090 KMP_FSYNC_SPIN_INIT(obj, spin);
3091 KMP_INIT_YIELD(spins);
3092 KMP_INIT_BACKOFF(time);
3094 while (!f(spin, check)) {
3095 KMP_FSYNC_SPIN_PREPARE(obj);
3098 KMP_YIELD_OVERSUB_ELSE_SPIN(spins, time);
3100 KMP_FSYNC_SPIN_ACQUIRED(obj);
3105#ifdef KMP_GOMP_COMPAT
3107void __kmp_aux_dispatch_init_4(
ident_t *loc, kmp_int32 gtid,
3109 kmp_int32 ub, kmp_int32 st, kmp_int32 chunk,
3111 __kmp_dispatch_init<kmp_int32>(loc, gtid, schedule, lb, ub, st, chunk,
3115void __kmp_aux_dispatch_init_4u(
ident_t *loc, kmp_int32 gtid,
3117 kmp_uint32 ub, kmp_int32 st, kmp_int32 chunk,
3119 __kmp_dispatch_init<kmp_uint32>(loc, gtid, schedule, lb, ub, st, chunk,
3123void __kmp_aux_dispatch_init_8(
ident_t *loc, kmp_int32 gtid,
3125 kmp_int64 ub, kmp_int64 st, kmp_int64 chunk,
3127 __kmp_dispatch_init<kmp_int64>(loc, gtid, schedule, lb, ub, st, chunk,
3131void __kmp_aux_dispatch_init_8u(
ident_t *loc, kmp_int32 gtid,
3133 kmp_uint64 ub, kmp_int64 st, kmp_int64 chunk,
3135 __kmp_dispatch_init<kmp_uint64>(loc, gtid, schedule, lb, ub, st, chunk,
3139void __kmp_aux_dispatch_fini_chunk_4(
ident_t *loc, kmp_int32 gtid) {
3140 __kmp_dispatch_finish_chunk<kmp_uint32>(gtid, loc);
3143void __kmp_aux_dispatch_fini_chunk_8(
ident_t *loc, kmp_int32 gtid) {
3144 __kmp_dispatch_finish_chunk<kmp_uint64>(gtid, loc);
3147void __kmp_aux_dispatch_fini_chunk_4u(
ident_t *loc, kmp_int32 gtid) {
3148 __kmp_dispatch_finish_chunk<kmp_uint32>(gtid, loc);
3151void __kmp_aux_dispatch_fini_chunk_8u(
ident_t *loc, kmp_int32 gtid) {
3152 __kmp_dispatch_finish_chunk<kmp_uint64>(gtid, loc);
#define KMP_COUNT_VALUE(name, value)
Adds value to specified timer (name).
#define KMP_COUNT_BLOCK(name)
Increments specified counter (name).
int __kmpc_dispatch_next_4(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_int32 *p_lb, kmp_int32 *p_ub, kmp_int32 *p_st)
void __kmpc_dispatch_fini_4(ident_t *loc, kmp_int32 gtid)
void __kmpc_dispatch_deinit(ident_t *loc, kmp_int32 gtid)
kmp_int32 __kmpc_next_section(ident_t *loc, kmp_int32 gtid, kmp_int32 numberOfSections)
void __kmpc_dist_dispatch_init_4(ident_t *loc, kmp_int32 gtid, enum sched_type schedule, kmp_int32 *p_last, kmp_int32 lb, kmp_int32 ub, kmp_int32 st, kmp_int32 chunk)
int __kmpc_dispatch_next_4u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_uint32 *p_lb, kmp_uint32 *p_ub, kmp_int32 *p_st)
void __kmpc_end_sections(ident_t *loc, kmp_int32 gtid)
int __kmpc_dispatch_next_8u(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_uint64 *p_lb, kmp_uint64 *p_ub, kmp_int64 *p_st)
void __kmpc_dispatch_fini_8(ident_t *loc, kmp_int32 gtid)
kmp_int32 __kmpc_sections_init(ident_t *loc, kmp_int32 gtid)
int __kmpc_dispatch_next_8(ident_t *loc, kmp_int32 gtid, kmp_int32 *p_last, kmp_int64 *p_lb, kmp_int64 *p_ub, kmp_int64 *p_st)
void __kmpc_dispatch_fini_8u(ident_t *loc, kmp_int32 gtid)
void __kmpc_dispatch_init_4(ident_t *loc, kmp_int32 gtid, enum sched_type schedule, kmp_int32 lb, kmp_int32 ub, kmp_int32 st, kmp_int32 chunk)
void __kmpc_dispatch_init_4u(ident_t *loc, kmp_int32 gtid, enum sched_type schedule, kmp_uint32 lb, kmp_uint32 ub, kmp_int32 st, kmp_int32 chunk)
void __kmpc_dispatch_init_8u(ident_t *loc, kmp_int32 gtid, enum sched_type schedule, kmp_uint64 lb, kmp_uint64 ub, kmp_int64 st, kmp_int64 chunk)
void __kmpc_dispatch_fini_4u(ident_t *loc, kmp_int32 gtid)
void __kmpc_dispatch_init_8(ident_t *loc, kmp_int32 gtid, enum sched_type schedule, kmp_int64 lb, kmp_int64 ub, kmp_int64 st, kmp_int64 chunk)
@ kmp_sch_modifier_nonmonotonic