17#include "kmp_wait_release.h"
18#include "kmp_taskdeps.h"
21#include "ompt-specific.h"
24#if ENABLE_LIBOMPTARGET
25static void (*tgt_target_nowait_query)(
void **);
27void __kmp_init_target_task() {
28 *(
void **)(&tgt_target_nowait_query) = KMP_DLSYM(
"__tgt_target_nowait_query");
33static void __kmp_enable_tasking(kmp_task_team_t *task_team,
34 kmp_info_t *this_thr);
35static void __kmp_alloc_task_deque(kmp_info_t *thread,
36 kmp_thread_data_t *thread_data);
37static int __kmp_realloc_task_threads_data(kmp_info_t *thread,
38 kmp_task_team_t *task_team);
39static void __kmp_bottom_half_finish_proxy(kmp_int32 gtid, kmp_task_t *ptask);
40#if OMP_TASKGRAPH_EXPERIMENTAL
41static kmp_tdg_info_t *__kmp_find_tdg(kmp_int32 tdg_id);
42int __kmp_taskloop_task(
int gtid,
void *ptask);
48static bool __kmp_task_is_allowed(
int gtid,
const kmp_int32 is_constrained,
49 const kmp_taskdata_t *tasknew,
50 const kmp_taskdata_t *taskcurr) {
51 if (is_constrained && (tasknew->td_flags.tiedness == TASK_TIED)) {
55 kmp_taskdata_t *current = taskcurr->td_last_tied;
56 KMP_DEBUG_ASSERT(current != NULL);
58 if (current->td_flags.tasktype == TASK_EXPLICIT ||
59 current->td_taskwait_thread > 0) {
60 kmp_int32 level = current->td_level;
61 kmp_taskdata_t *parent = tasknew->td_parent;
62 while (parent != current && parent->td_level > level) {
64 parent = parent->td_parent;
65 KMP_DEBUG_ASSERT(parent != NULL);
67 if (parent != current)
72 kmp_depnode_t *node = tasknew->td_depnode;
73#if OMP_TASKGRAPH_EXPERIMENTAL
74 if (!tasknew->is_taskgraph && UNLIKELY(node && (node->dn.mtx_num_locks > 0))) {
76 if (UNLIKELY(node && (node->dn.mtx_num_locks > 0))) {
78 for (
int i = 0; i < node->dn.mtx_num_locks; ++i) {
79 KMP_DEBUG_ASSERT(node->dn.mtx_locks[i] != NULL);
80 if (__kmp_test_lock(node->dn.mtx_locks[i], gtid))
83 for (
int j = i - 1; j >= 0; --j)
84 __kmp_release_lock(node->dn.mtx_locks[j], gtid);
88 node->dn.mtx_num_locks = -node->dn.mtx_num_locks;
97static void __kmp_realloc_task_deque(kmp_info_t *thread,
98 kmp_thread_data_t *thread_data) {
99 kmp_int32 size = TASK_DEQUE_SIZE(thread_data->td);
100 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) == size);
101 kmp_int32 new_size = 2 * size;
103 KE_TRACE(10, (
"__kmp_realloc_task_deque: T#%d reallocating deque[from %d to "
104 "%d] for thread_data %p\n",
105 __kmp_gtid_from_thread(thread), size, new_size, thread_data));
107 kmp_taskdata_t **new_deque =
108 (kmp_taskdata_t **)__kmp_allocate(new_size *
sizeof(kmp_taskdata_t *));
111 for (i = thread_data->td.td_deque_head, j = 0; j < size;
112 i = (i + 1) & TASK_DEQUE_MASK(thread_data->td), j++)
113 new_deque[j] = thread_data->td.td_deque[i];
115 __kmp_free(thread_data->td.td_deque);
117 thread_data->td.td_deque_head = 0;
118 thread_data->td.td_deque_tail = size;
119 thread_data->td.td_deque = new_deque;
120 thread_data->td.td_deque_size = new_size;
123static kmp_task_pri_t *__kmp_alloc_task_pri_list() {
124 kmp_task_pri_t *l = (kmp_task_pri_t *)__kmp_allocate(
sizeof(kmp_task_pri_t));
125 kmp_thread_data_t *thread_data = &l->td;
126 __kmp_init_bootstrap_lock(&thread_data->td.td_deque_lock);
127 thread_data->td.td_deque_last_stolen = -1;
128 KE_TRACE(20, (
"__kmp_alloc_task_pri_list: T#%d allocating deque[%d] "
129 "for thread_data %p\n",
130 __kmp_get_gtid(), INITIAL_TASK_DEQUE_SIZE, thread_data));
131 thread_data->td.td_deque = (kmp_taskdata_t **)__kmp_allocate(
132 INITIAL_TASK_DEQUE_SIZE *
sizeof(kmp_taskdata_t *));
133 thread_data->td.td_deque_size = INITIAL_TASK_DEQUE_SIZE;
142static kmp_thread_data_t *
143__kmp_get_priority_deque_data(kmp_task_team_t *task_team, kmp_int32 pri) {
144 kmp_thread_data_t *thread_data;
145 kmp_task_pri_t *lst = task_team->tt.tt_task_pri_list;
146 if (lst->priority == pri) {
148 thread_data = &lst->td;
149 }
else if (lst->priority < pri) {
152 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
153 thread_data = &list->td;
154 list->priority = pri;
156 task_team->tt.tt_task_pri_list = list;
158 kmp_task_pri_t *next_queue = lst->next;
159 while (next_queue && next_queue->priority > pri) {
161 next_queue = lst->next;
164 if (next_queue == NULL) {
166 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
167 thread_data = &list->td;
168 list->priority = pri;
171 }
else if (next_queue->priority == pri) {
173 thread_data = &next_queue->td;
176 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
177 thread_data = &list->td;
178 list->priority = pri;
179 list->next = next_queue;
187static kmp_int32 __kmp_push_priority_task(kmp_int32 gtid, kmp_info_t *thread,
188 kmp_taskdata_t *taskdata,
189 kmp_task_team_t *task_team,
191 kmp_thread_data_t *thread_data = NULL;
193 (
"__kmp_push_priority_task: T#%d trying to push task %p, pri %d.\n",
194 gtid, taskdata, pri));
197 kmp_task_pri_t *lst = task_team->tt.tt_task_pri_list;
198 if (UNLIKELY(lst == NULL)) {
199 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
200 if (task_team->tt.tt_task_pri_list == NULL) {
202 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
203 thread_data = &list->td;
204 list->priority = pri;
206 task_team->tt.tt_task_pri_list = list;
209 thread_data = __kmp_get_priority_deque_data(task_team, pri);
211 __kmp_release_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
213 if (lst->priority == pri) {
215 thread_data = &lst->td;
217 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
218 thread_data = __kmp_get_priority_deque_data(task_team, pri);
219 __kmp_release_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
222 KMP_DEBUG_ASSERT(thread_data);
224 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
226 if (TCR_4(thread_data->td.td_deque_ntasks) >=
227 TASK_DEQUE_SIZE(thread_data->td)) {
228 if (__kmp_enable_task_throttling &&
229 __kmp_task_is_allowed(gtid, __kmp_task_stealing_constraint, taskdata,
230 thread->th.th_current_task)) {
231 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
232 KA_TRACE(20, (
"__kmp_push_priority_task: T#%d deque is full; returning "
233 "TASK_NOT_PUSHED for task %p\n",
235 return TASK_NOT_PUSHED;
238 __kmp_realloc_task_deque(thread, thread_data);
241 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) <
242 TASK_DEQUE_SIZE(thread_data->td));
244 thread_data->td.td_deque[thread_data->td.td_deque_tail] = taskdata;
246 thread_data->td.td_deque_tail =
247 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td);
248 TCW_4(thread_data->td.td_deque_ntasks,
249 TCR_4(thread_data->td.td_deque_ntasks) + 1);
250 KMP_FSYNC_RELEASING(thread->th.th_current_task);
251 KMP_FSYNC_RELEASING(taskdata);
252 KA_TRACE(20, (
"__kmp_push_priority_task: T#%d returning "
253 "TASK_SUCCESSFULLY_PUSHED: task=%p ntasks=%d head=%u tail=%u\n",
254 gtid, taskdata, thread_data->td.td_deque_ntasks,
255 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
256 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
257 task_team->tt.tt_num_task_pri++;
258 return TASK_SUCCESSFULLY_PUSHED;
262static kmp_int32 __kmp_push_task(kmp_int32 gtid, kmp_task_t *task) {
263 kmp_info_t *thread = __kmp_threads[gtid];
264 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
269 if (UNLIKELY(taskdata->td_flags.hidden_helper &&
270 !KMP_HIDDEN_HELPER_THREAD(gtid))) {
271 kmp_int32 shadow_gtid = KMP_GTID_TO_SHADOW_GTID(gtid);
272 __kmpc_give_task(task, __kmp_tid_from_gtid(shadow_gtid));
274 __kmp_hidden_helper_worker_thread_signal();
275 return TASK_SUCCESSFULLY_PUSHED;
278 kmp_task_team_t *task_team = thread->th.th_task_team;
279 kmp_int32 tid = __kmp_tid_from_gtid(gtid);
280 kmp_thread_data_t *thread_data;
283 (
"__kmp_push_task: T#%d trying to push task %p.\n", gtid, taskdata));
285 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
288 kmp_int32 counter = 1 + KMP_ATOMIC_INC(&taskdata->td_untied_count);
289 KMP_DEBUG_USE_VAR(counter);
292 (
"__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n",
293 gtid, counter, taskdata));
297 if (UNLIKELY(taskdata->td_flags.task_serial)) {
298 KA_TRACE(20, (
"__kmp_push_task: T#%d team serialized; returning "
299 "TASK_NOT_PUSHED for task %p\n",
301 return TASK_NOT_PUSHED;
306 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
307 if (UNLIKELY(!KMP_TASKING_ENABLED(task_team))) {
308 __kmp_enable_tasking(task_team, thread);
310 KMP_DEBUG_ASSERT(TCR_4(task_team->tt.tt_found_tasks) == TRUE);
311 KMP_DEBUG_ASSERT(TCR_PTR(task_team->tt.tt_threads_data) != NULL);
313 if (taskdata->td_flags.priority_specified && task->data2.priority > 0 &&
314 __kmp_max_task_priority > 0) {
315 int pri = KMP_MIN(task->data2.priority, __kmp_max_task_priority);
316 return __kmp_push_priority_task(gtid, thread, taskdata, task_team, pri);
320 thread_data = &task_team->tt.tt_threads_data[tid];
325 if (UNLIKELY(thread_data->td.td_deque == NULL)) {
326 __kmp_alloc_task_deque(thread, thread_data);
331 if (TCR_4(thread_data->td.td_deque_ntasks) >=
332 TASK_DEQUE_SIZE(thread_data->td)) {
333 if (__kmp_enable_task_throttling &&
334 __kmp_task_is_allowed(gtid, __kmp_task_stealing_constraint, taskdata,
335 thread->th.th_current_task)) {
336 KA_TRACE(20, (
"__kmp_push_task: T#%d deque is full; returning "
337 "TASK_NOT_PUSHED for task %p\n",
339 return TASK_NOT_PUSHED;
341 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
343 if (TCR_4(thread_data->td.td_deque_ntasks) >=
344 TASK_DEQUE_SIZE(thread_data->td)) {
346 __kmp_realloc_task_deque(thread, thread_data);
352 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
354 if (TCR_4(thread_data->td.td_deque_ntasks) >=
355 TASK_DEQUE_SIZE(thread_data->td)) {
356 if (__kmp_enable_task_throttling &&
357 __kmp_task_is_allowed(gtid, __kmp_task_stealing_constraint, taskdata,
358 thread->th.th_current_task)) {
359 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
360 KA_TRACE(20, (
"__kmp_push_task: T#%d deque is full on 2nd check; "
361 "returning TASK_NOT_PUSHED for task %p\n",
363 return TASK_NOT_PUSHED;
366 __kmp_realloc_task_deque(thread, thread_data);
371 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) <
372 TASK_DEQUE_SIZE(thread_data->td));
374 thread_data->td.td_deque[thread_data->td.td_deque_tail] =
377 thread_data->td.td_deque_tail =
378 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td);
379 TCW_4(thread_data->td.td_deque_ntasks,
380 TCR_4(thread_data->td.td_deque_ntasks) + 1);
381 KMP_FSYNC_RELEASING(thread->th.th_current_task);
382 KMP_FSYNC_RELEASING(taskdata);
383 KA_TRACE(20, (
"__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "
384 "task=%p ntasks=%d head=%u tail=%u\n",
385 gtid, taskdata, thread_data->td.td_deque_ntasks,
386 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
388 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
390 return TASK_SUCCESSFULLY_PUSHED;
397void __kmp_pop_current_task_from_thread(kmp_info_t *this_thr) {
398 KF_TRACE(10, (
"__kmp_pop_current_task_from_thread(enter): T#%d "
399 "this_thread=%p, curtask=%p, "
400 "curtask_parent=%p\n",
401 0, this_thr, this_thr->th.th_current_task,
402 this_thr->th.th_current_task->td_parent));
404 this_thr->th.th_current_task = this_thr->th.th_current_task->td_parent;
406 KF_TRACE(10, (
"__kmp_pop_current_task_from_thread(exit): T#%d "
407 "this_thread=%p, curtask=%p, "
408 "curtask_parent=%p\n",
409 0, this_thr, this_thr->th.th_current_task,
410 this_thr->th.th_current_task->td_parent));
419void __kmp_push_current_task_to_thread(kmp_info_t *this_thr, kmp_team_t *team,
423 KF_TRACE(10, (
"__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
426 tid, this_thr, this_thr->th.th_current_task,
427 team->t.t_implicit_task_taskdata[tid].td_parent));
429 KMP_DEBUG_ASSERT(this_thr != NULL);
432 if (this_thr->th.th_current_task != &team->t.t_implicit_task_taskdata[0]) {
433 team->t.t_implicit_task_taskdata[0].td_parent =
434 this_thr->th.th_current_task;
435 this_thr->th.th_current_task = &team->t.t_implicit_task_taskdata[0];
438 team->t.t_implicit_task_taskdata[tid].td_parent =
439 team->t.t_implicit_task_taskdata[0].td_parent;
440 this_thr->th.th_current_task = &team->t.t_implicit_task_taskdata[tid];
443 KF_TRACE(10, (
"__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
446 tid, this_thr, this_thr->th.th_current_task,
447 team->t.t_implicit_task_taskdata[tid].td_parent));
455static void __kmp_task_start(kmp_int32 gtid, kmp_task_t *task,
456 kmp_taskdata_t *current_task) {
457 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
458 kmp_info_t *thread = __kmp_threads[gtid];
461 (
"__kmp_task_start(enter): T#%d starting task %p: current_task=%p\n",
462 gtid, taskdata, current_task));
464 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
469 current_task->td_flags.executing = 0;
479 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
480 taskdata->td_last_tied = current_task->td_last_tied;
481 KMP_DEBUG_ASSERT(taskdata->td_last_tied);
485 thread->th.th_current_task = taskdata;
487 KMP_DEBUG_ASSERT(taskdata->td_flags.started == 0 ||
488 taskdata->td_flags.tiedness == TASK_UNTIED);
489 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 0 ||
490 taskdata->td_flags.tiedness == TASK_UNTIED);
491 taskdata->td_flags.started = 1;
492 taskdata->td_flags.executing = 1;
493 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
494 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
501 KA_TRACE(10, (
"__kmp_task_start(exit): T#%d task=%p\n", gtid, taskdata));
511static inline void __ompt_task_start(kmp_task_t *task,
512 kmp_taskdata_t *current_task,
514 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
515 ompt_task_status_t status = ompt_task_switch;
516 if (__kmp_threads[gtid]->th.ompt_thread_info.ompt_task_yielded) {
517 status = ompt_task_yield;
518 __kmp_threads[gtid]->th.ompt_thread_info.ompt_task_yielded = 0;
521 if (ompt_enabled.ompt_callback_task_schedule) {
522 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
523 &(current_task->ompt_task_info.task_data), status,
524 &(taskdata->ompt_task_info.task_data));
526 taskdata->ompt_task_info.scheduling_parent = current_task;
531static inline void __ompt_task_finish(kmp_task_t *task,
532 kmp_taskdata_t *resumed_task,
533 ompt_task_status_t status) {
534 if (ompt_enabled.ompt_callback_task_schedule) {
535 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
536 if (__kmp_omp_cancellation && taskdata->td_taskgroup &&
537 taskdata->td_taskgroup->cancel_request == cancel_taskgroup) {
538 status = ompt_task_cancel;
542 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
543 &(taskdata->ompt_task_info.task_data), status,
544 (resumed_task ? &(resumed_task->ompt_task_info.task_data) : NULL));
550static void __kmpc_omp_task_begin_if0_template(
ident_t *loc_ref, kmp_int32 gtid,
553 void *return_address) {
554 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
555 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
557 KA_TRACE(10, (
"__kmpc_omp_task_begin_if0(enter): T#%d loc=%p task=%p "
559 gtid, loc_ref, taskdata, current_task));
561 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
564 kmp_int32 counter = 1 + KMP_ATOMIC_INC(&taskdata->td_untied_count);
565 KMP_DEBUG_USE_VAR(counter);
566 KA_TRACE(20, (
"__kmpc_omp_task_begin_if0: T#%d untied_count (%d) "
567 "incremented for task %p\n",
568 gtid, counter, taskdata));
571 taskdata->td_flags.task_serial =
573 __kmp_task_start(gtid, task, current_task);
577 if (current_task->ompt_task_info.frame.enter_frame.ptr == NULL) {
578 current_task->ompt_task_info.frame.enter_frame.ptr =
579 taskdata->ompt_task_info.frame.exit_frame.ptr = frame_address;
580 current_task->ompt_task_info.frame.enter_frame_flags =
581 taskdata->ompt_task_info.frame.exit_frame_flags =
582 OMPT_FRAME_FLAGS_APP;
584 if (ompt_enabled.ompt_callback_task_create) {
585 ompt_task_info_t *parent_info = &(current_task->ompt_task_info);
586 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
587 &(parent_info->task_data), &(parent_info->frame),
588 &(taskdata->ompt_task_info.task_data),
589 TASK_TYPE_DETAILS_FORMAT(taskdata), 0, return_address);
591 __ompt_task_start(task, current_task, gtid);
595 KA_TRACE(10, (
"__kmpc_omp_task_begin_if0(exit): T#%d loc=%p task=%p,\n", gtid,
601static void __kmpc_omp_task_begin_if0_ompt(
ident_t *loc_ref, kmp_int32 gtid,
604 void *return_address) {
605 __kmpc_omp_task_begin_if0_template<true>(loc_ref, gtid, task, frame_address,
622__attribute__((target(
"backchain")))
624void __kmpc_omp_task_begin_if0(
ident_t *loc_ref, kmp_int32 gtid,
627 if (UNLIKELY(ompt_enabled.enabled)) {
628 OMPT_STORE_RETURN_ADDRESS(gtid);
629 __kmpc_omp_task_begin_if0_ompt(loc_ref, gtid, task,
630 OMPT_GET_FRAME_ADDRESS(1),
631 OMPT_LOAD_RETURN_ADDRESS(gtid));
635 __kmpc_omp_task_begin_if0_template<false>(loc_ref, gtid, task, NULL, NULL);
641void __kmpc_omp_task_begin(
ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *task) {
642 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
646 (
"__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n",
647 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task), current_task));
649 __kmp_task_start(gtid, task, current_task);
651 KA_TRACE(10, (
"__kmpc_omp_task_begin(exit): T#%d loc=%p task=%p,\n", gtid,
652 loc_ref, KMP_TASK_TO_TASKDATA(task)));
662static void __kmp_free_task(kmp_int32 gtid, kmp_taskdata_t *taskdata,
663 kmp_info_t *thread) {
664 KA_TRACE(30, (
"__kmp_free_task: T#%d freeing data from task %p\n", gtid,
668 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
669 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 0);
670 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 1);
671 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
672 KMP_DEBUG_ASSERT(taskdata->td_allocated_child_tasks == 0 ||
673 taskdata->td_flags.task_serial == 1);
674 KMP_DEBUG_ASSERT(taskdata->td_incomplete_child_tasks == 0);
675 kmp_task_t *task = KMP_TASKDATA_TO_TASK(taskdata);
677 task->data1.destructors = NULL;
678 task->data2.priority = 0;
680 taskdata->td_flags.freed = 1;
681#if OMP_TASKGRAPH_EXPERIMENTAL
683 if (!taskdata->is_taskgraph) {
687 __kmp_fast_free(thread, taskdata);
689 __kmp_thread_free(thread, taskdata);
691#if OMP_TASKGRAPH_EXPERIMENTAL
693 taskdata->td_flags.complete = 0;
694 taskdata->td_flags.started = 0;
695 taskdata->td_flags.freed = 0;
696 taskdata->td_flags.executing = 0;
697 taskdata->td_flags.task_serial =
698 (taskdata->td_parent->td_flags.final ||
699 taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser);
702 KMP_ATOMIC_ST_RLX(&taskdata->td_untied_count, 0);
703 KMP_ATOMIC_ST_RLX(&taskdata->td_incomplete_child_tasks, 0);
705 KMP_ATOMIC_ST_RLX(&taskdata->td_allocated_child_tasks, 1);
709 KA_TRACE(20, (
"__kmp_free_task: T#%d freed task %p\n", gtid, taskdata));
718static void __kmp_free_task_and_ancestors(kmp_int32 gtid,
719 kmp_taskdata_t *taskdata,
720 kmp_info_t *thread) {
723 kmp_int32 team_serial =
724 (taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser) &&
725 !taskdata->td_flags.proxy;
726 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
728 kmp_int32 children = KMP_ATOMIC_DEC(&taskdata->td_allocated_child_tasks) - 1;
729 KMP_DEBUG_ASSERT(children >= 0);
732 while (children == 0) {
733 kmp_taskdata_t *parent_taskdata = taskdata->td_parent;
735 KA_TRACE(20, (
"__kmp_free_task_and_ancestors(enter): T#%d task %p complete "
736 "and freeing itself\n",
740 __kmp_free_task(gtid, taskdata, thread);
742 taskdata = parent_taskdata;
748 if (taskdata->td_flags.tasktype == TASK_IMPLICIT) {
749 if (taskdata->td_dephash) {
750 int children = KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks);
751 kmp_tasking_flags_t flags_old = taskdata->td_flags;
752 if (children == 0 && flags_old.complete == 1) {
753 kmp_tasking_flags_t flags_new = flags_old;
754 flags_new.complete = 0;
755 if (KMP_COMPARE_AND_STORE_ACQ32(
756 RCAST(kmp_int32 *, &taskdata->td_flags),
757 *RCAST(kmp_int32 *, &flags_old),
758 *RCAST(kmp_int32 *, &flags_new))) {
759 KA_TRACE(100, (
"__kmp_free_task_and_ancestors: T#%d cleans "
760 "dephash of implicit task %p\n",
763 __kmp_dephash_free_entries(thread, taskdata->td_dephash);
770 children = KMP_ATOMIC_DEC(&taskdata->td_allocated_child_tasks) - 1;
771 KMP_DEBUG_ASSERT(children >= 0);
775 20, (
"__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
776 "not freeing it yet\n",
777 gtid, taskdata, children));
788static bool __kmp_track_children_task(kmp_taskdata_t *taskdata) {
789 kmp_tasking_flags_t flags = taskdata->td_flags;
790 bool ret = !(flags.team_serial || flags.tasking_ser);
791 ret = ret || flags.proxy == TASK_PROXY ||
792 flags.detachable == TASK_DETACHABLE || flags.hidden_helper;
794 KMP_ATOMIC_LD_ACQ(&taskdata->td_parent->td_incomplete_child_tasks) > 0;
795#if OMP_TASKGRAPH_EXPERIMENTAL
796 if (taskdata->td_taskgroup && taskdata->is_taskgraph)
797 ret = ret || KMP_ATOMIC_LD_ACQ(&taskdata->td_taskgroup->count) > 0;
812static void __kmp_task_finish(kmp_int32 gtid, kmp_task_t *task,
813 kmp_taskdata_t *resumed_task) {
814 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
815 kmp_info_t *thread = __kmp_threads[gtid];
816 kmp_task_team_t *task_team =
817 thread->th.th_task_team;
818#if OMP_TASKGRAPH_EXPERIMENTAL
823 kmp_int32 children = 0;
825 KA_TRACE(10, (
"__kmp_task_finish(enter): T#%d finishing task %p and resuming "
827 gtid, taskdata, resumed_task));
829 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
831#if OMP_TASKGRAPH_EXPERIMENTAL
832 is_taskgraph = taskdata->is_taskgraph;
835 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
838 kmp_int32 counter = KMP_ATOMIC_DEC(&taskdata->td_untied_count) - 1;
841 (
"__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n",
842 gtid, counter, taskdata));
846 if (resumed_task == NULL) {
847 KMP_DEBUG_ASSERT(taskdata->td_flags.task_serial);
848 resumed_task = taskdata->td_parent;
851 thread->th.th_current_task = resumed_task;
852 resumed_task->td_flags.executing = 1;
853 KA_TRACE(10, (
"__kmp_task_finish(exit): T#%d partially done task %p, "
854 "resuming task %p\n",
855 gtid, taskdata, resumed_task));
863 (taskdata->td_flags.tasking_ser || taskdata->td_flags.task_serial) ==
864 taskdata->td_flags.task_serial);
865 if (taskdata->td_flags.task_serial) {
866 if (resumed_task == NULL) {
867 resumed_task = taskdata->td_parent;
871 KMP_DEBUG_ASSERT(resumed_task !=
881 if (UNLIKELY(taskdata->td_flags.destructors_thunk)) {
882 kmp_routine_entry_t destr_thunk = task->data1.destructors;
883 KMP_ASSERT(destr_thunk);
884 destr_thunk(gtid, task);
887 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
888 KMP_DEBUG_ASSERT(taskdata->td_flags.started == 1);
889 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
891 bool completed =
true;
892 if (UNLIKELY(taskdata->td_flags.detachable == TASK_DETACHABLE)) {
893 if (taskdata->td_allow_completion_event.type ==
894 KMP_EVENT_ALLOW_COMPLETION) {
896 __kmp_acquire_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
897 if (taskdata->td_allow_completion_event.type ==
898 KMP_EVENT_ALLOW_COMPLETION) {
900 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 1);
901 taskdata->td_flags.executing = 0;
908 __ompt_task_finish(task, resumed_task, ompt_task_detach);
914 taskdata->td_flags.proxy = TASK_PROXY;
917 __kmp_release_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
922 if (taskdata->td_target_data.async_handle != NULL) {
928 __ompt_task_finish(task, resumed_task, ompt_task_switch);
931 __kmpc_give_task(task, __kmp_tid_from_gtid(gtid));
932 if (KMP_HIDDEN_HELPER_THREAD(gtid))
933 __kmp_hidden_helper_worker_thread_signal();
938 taskdata->td_flags.complete = 1;
939#if OMP_TASKGRAPH_EXPERIMENTAL
940 taskdata->td_flags.onced = 1;
946 __ompt_task_finish(task, resumed_task, ompt_task_complete);
950 if (__kmp_track_children_task(taskdata)) {
951 __kmp_release_deps(gtid, taskdata);
956 KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks);
957 KMP_DEBUG_ASSERT(children >= 0);
958#if OMP_TASKGRAPH_EXPERIMENTAL
959 if (taskdata->td_taskgroup && !taskdata->is_taskgraph)
961 if (taskdata->td_taskgroup)
963 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
964 }
else if (task_team && (task_team->tt.tt_found_proxy_tasks ||
965 task_team->tt.tt_hidden_helper_task_encountered)) {
968 __kmp_release_deps(gtid, taskdata);
974 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 1);
975 taskdata->td_flags.executing = 0;
978 if (taskdata->td_flags.hidden_helper) {
980 KMP_ASSERT(KMP_HIDDEN_HELPER_THREAD(gtid));
981 KMP_ATOMIC_DEC(&__kmp_unexecuted_hidden_helper_tasks);
986 20, (
"__kmp_task_finish: T#%d finished task %p, %d incomplete children\n",
987 gtid, taskdata, children));
993 thread->th.th_current_task = resumed_task;
995 __kmp_free_task_and_ancestors(gtid, taskdata, thread);
999 resumed_task->td_flags.executing = 1;
1001#if OMP_TASKGRAPH_EXPERIMENTAL
1002 if (is_taskgraph && __kmp_track_children_task(taskdata) &&
1003 taskdata->td_taskgroup) {
1010 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
1015 10, (
"__kmp_task_finish(exit): T#%d finished task %p, resuming task %p\n",
1016 gtid, taskdata, resumed_task));
1022static void __kmpc_omp_task_complete_if0_template(
ident_t *loc_ref,
1025 KA_TRACE(10, (
"__kmpc_omp_task_complete_if0(enter): T#%d loc=%p task=%p\n",
1026 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task)));
1027 KMP_DEBUG_ASSERT(gtid >= 0);
1029 __kmp_task_finish<ompt>(gtid, task, NULL);
1031 KA_TRACE(10, (
"__kmpc_omp_task_complete_if0(exit): T#%d loc=%p task=%p\n",
1032 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task)));
1036 ompt_frame_t *ompt_frame;
1037 __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
1038 ompt_frame->enter_frame = ompt_data_none;
1039 ompt_frame->enter_frame_flags = OMPT_FRAME_FLAGS_RUNTIME;
1048void __kmpc_omp_task_complete_if0_ompt(
ident_t *loc_ref, kmp_int32 gtid,
1050 __kmpc_omp_task_complete_if0_template<true>(loc_ref, gtid, task);
1059void __kmpc_omp_task_complete_if0(
ident_t *loc_ref, kmp_int32 gtid,
1062 if (UNLIKELY(ompt_enabled.enabled)) {
1063 __kmpc_omp_task_complete_if0_ompt(loc_ref, gtid, task);
1067 __kmpc_omp_task_complete_if0_template<false>(loc_ref, gtid, task);
1073void __kmpc_omp_task_complete(
ident_t *loc_ref, kmp_int32 gtid,
1075 KA_TRACE(10, (
"__kmpc_omp_task_complete(enter): T#%d loc=%p task=%p\n", gtid,
1076 loc_ref, KMP_TASK_TO_TASKDATA(task)));
1078 __kmp_task_finish<false>(gtid, task,
1081 KA_TRACE(10, (
"__kmpc_omp_task_complete(exit): T#%d loc=%p task=%p\n", gtid,
1082 loc_ref, KMP_TASK_TO_TASKDATA(task)));
1098void __kmp_init_implicit_task(
ident_t *loc_ref, kmp_info_t *this_thr,
1099 kmp_team_t *team,
int tid,
int set_curr_task) {
1100 kmp_taskdata_t *task = &team->t.t_implicit_task_taskdata[tid];
1104 (
"__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n",
1105 tid, team, task, set_curr_task ?
"TRUE" :
"FALSE"));
1107 task->td_task_id = KMP_GEN_TASK_ID();
1108 task->td_team = team;
1111 task->td_ident = loc_ref;
1112 task->td_taskwait_ident = NULL;
1113 task->td_taskwait_counter = 0;
1114 task->td_taskwait_thread = 0;
1116 task->td_flags.tiedness = TASK_TIED;
1117 task->td_flags.tasktype = TASK_IMPLICIT;
1118 task->td_flags.proxy = TASK_FULL;
1121 task->td_flags.task_serial = 1;
1122 task->td_flags.tasking_ser = (__kmp_tasking_mode == tskm_immediate_exec);
1123 task->td_flags.team_serial = (team->t.t_serialized) ? 1 : 0;
1125 task->td_flags.started = 1;
1126 task->td_flags.executing = 1;
1127 task->td_flags.complete = 0;
1128 task->td_flags.freed = 0;
1129#if OMP_TASKGRAPH_EXPERIMENTAL
1130 task->td_flags.onced = 0;
1133 task->td_depnode = NULL;
1134 task->td_last_tied = task;
1135 task->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
1137 if (set_curr_task) {
1138 KMP_ATOMIC_ST_REL(&task->td_incomplete_child_tasks, 0);
1140 KMP_ATOMIC_ST_REL(&task->td_allocated_child_tasks, 0);
1141 task->td_taskgroup = NULL;
1142 task->td_dephash = NULL;
1143 __kmp_push_current_task_to_thread(this_thr, team, tid);
1145 KMP_DEBUG_ASSERT(task->td_incomplete_child_tasks == 0);
1146 KMP_DEBUG_ASSERT(task->td_allocated_child_tasks == 0);
1150 if (UNLIKELY(ompt_enabled.enabled))
1151 __ompt_task_init(task, tid);
1154 KF_TRACE(10, (
"__kmp_init_implicit_task(exit): T#:%d team=%p task=%p\n", tid,
1163void __kmp_finish_implicit_task(kmp_info_t *thread) {
1164 kmp_taskdata_t *task = thread->th.th_current_task;
1165#if ENABLE_LIBOMPTARGET
1168 if (UNLIKELY(kmp_target_sync_cb != NULL))
1169 (*kmp_target_sync_cb)(NULL, thread->th.th_info.ds.ds_gtid,
1170 KMP_TASKDATA_TO_TASK(task), NULL);
1172 if (task->td_dephash) {
1174 task->td_flags.complete = 1;
1175#if OMP_TASKGRAPH_EXPERIMENTAL
1176 task->td_flags.onced = 1;
1178 children = KMP_ATOMIC_LD_ACQ(&task->td_incomplete_child_tasks);
1179 kmp_tasking_flags_t flags_old = task->td_flags;
1180 if (children == 0 && flags_old.complete == 1) {
1181 kmp_tasking_flags_t flags_new = flags_old;
1182 flags_new.complete = 0;
1183 if (KMP_COMPARE_AND_STORE_ACQ32(RCAST(kmp_int32 *, &task->td_flags),
1184 *RCAST(kmp_int32 *, &flags_old),
1185 *RCAST(kmp_int32 *, &flags_new))) {
1186 KA_TRACE(100, (
"__kmp_finish_implicit_task: T#%d cleans "
1187 "dephash of implicit task %p\n",
1188 thread->th.th_info.ds.ds_gtid, task));
1189 __kmp_dephash_free_entries(thread, task->td_dephash);
1199void __kmp_free_implicit_task(kmp_info_t *thread) {
1200 kmp_taskdata_t *task = thread->th.th_current_task;
1201 if (task && task->td_dephash) {
1202 __kmp_dephash_free(thread, task->td_dephash);
1203 task->td_dephash = NULL;
1209static size_t __kmp_round_up_to_val(
size_t size,
size_t val) {
1210 if (size & (val - 1)) {
1212 if (size <= KMP_SIZE_T_MAX - val) {
1231kmp_task_t *__kmp_task_alloc(
ident_t *loc_ref, kmp_int32 gtid,
1232 kmp_tasking_flags_t *flags,
1233 size_t sizeof_kmp_task_t,
size_t sizeof_shareds,
1234 kmp_routine_entry_t task_entry) {
1236 kmp_taskdata_t *taskdata;
1237 kmp_info_t *thread = __kmp_threads[gtid];
1238 kmp_team_t *team = thread->th.th_team;
1239 kmp_taskdata_t *parent_task = thread->th.th_current_task;
1240 size_t shareds_offset;
1242 if (UNLIKELY(!TCR_4(__kmp_init_middle)))
1243 __kmp_middle_initialize();
1245 if (flags->hidden_helper) {
1246 if (__kmp_enable_hidden_helper) {
1247 if (!TCR_4(__kmp_init_hidden_helper))
1248 __kmp_hidden_helper_initialize();
1251 flags->hidden_helper = FALSE;
1255 KA_TRACE(10, (
"__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "
1256 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
1257 gtid, loc_ref, *((kmp_int32 *)flags), sizeof_kmp_task_t,
1258 sizeof_shareds, task_entry));
1260 KMP_DEBUG_ASSERT(parent_task);
1261 if (parent_task->td_flags.final) {
1262 if (flags->merged_if0) {
1267 if (flags->tiedness == TASK_UNTIED && !team->t.t_serialized) {
1271 KMP_CHECK_UPDATE(thread->th.th_task_team->tt.tt_untied_task_encountered, 1);
1277 if (UNLIKELY(flags->proxy == TASK_PROXY ||
1278 flags->detachable == TASK_DETACHABLE || flags->hidden_helper)) {
1279 if (flags->proxy == TASK_PROXY) {
1280 flags->tiedness = TASK_UNTIED;
1281 flags->merged_if0 = 1;
1285 if ((thread->th.th_task_team) == NULL) {
1288 KMP_DEBUG_ASSERT(team->t.t_serialized);
1290 (
"T#%d creating task team in __kmp_task_alloc for proxy task\n",
1292 __kmp_task_team_setup(thread, team);
1293 thread->th.th_task_team = team->t.t_task_team[thread->th.th_task_state];
1295 kmp_task_team_t *task_team = thread->th.th_task_team;
1298 if (!KMP_TASKING_ENABLED(task_team)) {
1301 (
"T#%d enabling tasking in __kmp_task_alloc for proxy task\n", gtid));
1302 __kmp_enable_tasking(task_team, thread);
1303 kmp_int32 tid = thread->th.th_info.ds.ds_tid;
1304 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[tid];
1306 if (thread_data->td.td_deque == NULL) {
1307 __kmp_alloc_task_deque(thread, thread_data);
1311 if ((flags->proxy == TASK_PROXY || flags->detachable == TASK_DETACHABLE) &&
1312 task_team->tt.tt_found_proxy_tasks == FALSE)
1313 TCW_4(task_team->tt.tt_found_proxy_tasks, TRUE);
1314 if (flags->hidden_helper &&
1315 task_team->tt.tt_hidden_helper_task_encountered == FALSE)
1316 TCW_4(task_team->tt.tt_hidden_helper_task_encountered, TRUE);
1321 shareds_offset =
sizeof(kmp_taskdata_t) + sizeof_kmp_task_t;
1322 shareds_offset = __kmp_round_up_to_val(shareds_offset,
sizeof(kmp_uint64));
1325 KA_TRACE(30, (
"__kmp_task_alloc: T#%d First malloc size: %ld\n", gtid,
1327 KA_TRACE(30, (
"__kmp_task_alloc: T#%d Second malloc size: %ld\n", gtid,
1332 taskdata = (kmp_taskdata_t *)__kmp_fast_allocate(thread, shareds_offset +
1335 taskdata = (kmp_taskdata_t *)__kmp_thread_malloc(thread, shareds_offset +
1339 task = KMP_TASKDATA_TO_TASK(taskdata);
1342#if KMP_ARCH_X86 || KMP_ARCH_PPC64 || KMP_ARCH_S390X || !KMP_HAVE_QUAD
1343 KMP_DEBUG_ASSERT((((kmp_uintptr_t)taskdata) & (
sizeof(
double) - 1)) == 0);
1344 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task) & (
sizeof(
double) - 1)) == 0);
1346 KMP_DEBUG_ASSERT((((kmp_uintptr_t)taskdata) & (
sizeof(_Quad) - 1)) == 0);
1347 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task) & (
sizeof(_Quad) - 1)) == 0);
1349 if (sizeof_shareds > 0) {
1351 task->shareds = &((
char *)taskdata)[shareds_offset];
1353 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task->shareds) & (
sizeof(
void *) - 1)) ==
1356 task->shareds = NULL;
1358 task->routine = task_entry;
1361 taskdata->td_task_id = KMP_GEN_TASK_ID();
1362 taskdata->td_team = thread->th.th_team;
1363 taskdata->td_alloc_thread = thread;
1364 taskdata->td_parent = parent_task;
1365 taskdata->td_level = parent_task->td_level + 1;
1366 KMP_ATOMIC_ST_RLX(&taskdata->td_untied_count, 0);
1367 taskdata->td_ident = loc_ref;
1368 taskdata->td_taskwait_ident = NULL;
1369 taskdata->td_taskwait_counter = 0;
1370 taskdata->td_taskwait_thread = 0;
1371 KMP_DEBUG_ASSERT(taskdata->td_parent != NULL);
1373 if (flags->proxy == TASK_FULL)
1374 copy_icvs(&taskdata->td_icvs, &taskdata->td_parent->td_icvs);
1376 taskdata->td_flags = *flags;
1377 taskdata->td_task_team = thread->th.th_task_team;
1378 taskdata->td_size_alloc = shareds_offset + sizeof_shareds;
1379 taskdata->td_flags.tasktype = TASK_EXPLICIT;
1382 if (flags->hidden_helper) {
1383 kmp_info_t *shadow_thread = __kmp_threads[KMP_GTID_TO_SHADOW_GTID(gtid)];
1384 taskdata->td_team = shadow_thread->th.th_team;
1385 taskdata->td_task_team = shadow_thread->th.th_task_team;
1389 taskdata->td_flags.tasking_ser = (__kmp_tasking_mode == tskm_immediate_exec);
1392 taskdata->td_flags.team_serial = (team->t.t_serialized) ? 1 : 0;
1398 taskdata->td_flags.task_serial =
1399 (parent_task->td_flags.final || taskdata->td_flags.team_serial ||
1400 taskdata->td_flags.tasking_ser || flags->merged_if0);
1402 taskdata->td_flags.started = 0;
1403 taskdata->td_flags.executing = 0;
1404 taskdata->td_flags.complete = 0;
1405 taskdata->td_flags.freed = 0;
1406#if OMP_TASKGRAPH_EXPERIMENTAL
1407 taskdata->td_flags.onced = 0;
1408 taskdata->is_taskgraph = 0;
1409 taskdata->tdg =
nullptr;
1411 KMP_ATOMIC_ST_RLX(&taskdata->td_incomplete_child_tasks, 0);
1413 KMP_ATOMIC_ST_RLX(&taskdata->td_allocated_child_tasks, 1);
1414 taskdata->td_taskgroup =
1415 parent_task->td_taskgroup;
1416 taskdata->td_dephash = NULL;
1417 taskdata->td_depnode = NULL;
1418 taskdata->td_target_data.async_handle = NULL;
1419 if (flags->tiedness == TASK_UNTIED)
1420 taskdata->td_last_tied = NULL;
1422 taskdata->td_last_tied = taskdata;
1423 taskdata->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
1425 if (UNLIKELY(ompt_enabled.enabled))
1426 __ompt_task_init(taskdata, gtid);
1430 if (__kmp_track_children_task(taskdata)) {
1431 KMP_ATOMIC_INC(&parent_task->td_incomplete_child_tasks);
1432 if (parent_task->td_taskgroup)
1433 KMP_ATOMIC_INC(&parent_task->td_taskgroup->count);
1436 if (taskdata->td_parent->td_flags.tasktype == TASK_EXPLICIT) {
1437 KMP_ATOMIC_INC(&taskdata->td_parent->td_allocated_child_tasks);
1439 if (flags->hidden_helper) {
1440 taskdata->td_flags.task_serial = FALSE;
1442 KMP_ATOMIC_INC(&__kmp_unexecuted_hidden_helper_tasks);
1446#if OMP_TASKGRAPH_EXPERIMENTAL
1447 kmp_tdg_info_t *tdg = __kmp_find_tdg(__kmp_curr_tdg_idx);
1448 if (tdg && __kmp_tdg_is_recording(tdg->tdg_status) &&
1449 (task_entry != (kmp_routine_entry_t)__kmp_taskloop_task)) {
1450 taskdata->is_taskgraph = 1;
1451 taskdata->tdg = __kmp_global_tdgs[__kmp_curr_tdg_idx];
1452 taskdata->td_task_id = KMP_GEN_TASK_ID();
1453 taskdata->td_tdg_task_id = KMP_ATOMIC_INC(&__kmp_tdg_task_id);
1456 KA_TRACE(20, (
"__kmp_task_alloc(exit): T#%d created task %p parent=%p\n",
1457 gtid, taskdata, taskdata->td_parent));
1462kmp_task_t *__kmpc_omp_task_alloc(
ident_t *loc_ref, kmp_int32 gtid,
1463 kmp_int32 flags,
size_t sizeof_kmp_task_t,
1464 size_t sizeof_shareds,
1465 kmp_routine_entry_t task_entry) {
1467 kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
1468 __kmp_assert_valid_gtid(gtid);
1469 input_flags->native = FALSE;
1471 KA_TRACE(10, (
"__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s %s) "
1472 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
1473 gtid, loc_ref, input_flags->tiedness ?
"tied " :
"untied",
1474 input_flags->proxy ?
"proxy" :
"",
1475 input_flags->detachable ?
"detachable" :
"", sizeof_kmp_task_t,
1476 sizeof_shareds, task_entry));
1478 retval = __kmp_task_alloc(loc_ref, gtid, input_flags, sizeof_kmp_task_t,
1479 sizeof_shareds, task_entry);
1481 KA_TRACE(20, (
"__kmpc_omp_task_alloc(exit): T#%d retval %p\n", gtid, retval));
1486kmp_task_t *__kmpc_omp_target_task_alloc(
ident_t *loc_ref, kmp_int32 gtid,
1488 size_t sizeof_kmp_task_t,
1489 size_t sizeof_shareds,
1490 kmp_routine_entry_t task_entry,
1491 kmp_int64 device_id) {
1492 auto &input_flags =
reinterpret_cast<kmp_tasking_flags_t &
>(flags);
1494 input_flags.tiedness = TASK_UNTIED;
1495 input_flags.target = 1;
1497 if (__kmp_enable_hidden_helper)
1498 input_flags.hidden_helper = TRUE;
1500 return __kmpc_omp_task_alloc(loc_ref, gtid, flags, sizeof_kmp_task_t,
1501 sizeof_shareds, task_entry);
1519 kmp_task_t *new_task, kmp_int32 naffins,
1520 kmp_task_affinity_info_t *affin_list) {
1522 KMP_DEBUG_ASSERT(affin_list != NULL);
1524 for (kmp_int32 i = 0; i < naffins; ++i) {
1525 KA_TRACE(30, (
"__kmpc_omp_reg_task_with_affinity: T#%d aff[%d] "
1526 "base_addr=0x%llx len=%zu flags={%d,%d,%d}\n",
1527 gtid, i, (
unsigned long long)affin_list[i].base_addr,
1528 affin_list[i].len, (
int)affin_list[i].flags.flag1,
1529 (
int)affin_list[i].flags.flag2,
1530 (
int)affin_list[i].flags.reserved));
1542__attribute__((target(
"backchain")))
1545__kmp_invoke_task(kmp_int32 gtid, kmp_task_t *task,
1546 kmp_taskdata_t *current_task) {
1547 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
1551 30, (
"__kmp_invoke_task(enter): T#%d invoking task %p, current_task=%p\n",
1552 gtid, taskdata, current_task));
1553 KMP_DEBUG_ASSERT(task);
1554 if (UNLIKELY(taskdata->td_flags.proxy == TASK_PROXY &&
1555 taskdata->td_flags.complete == 1)) {
1560 (
"__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n",
1563 __kmp_bottom_half_finish_proxy(gtid, task);
1565 KA_TRACE(30, (
"__kmp_invoke_task(exit): T#%d completed bottom finish for "
1566 "proxy task %p, resuming task %p\n",
1567 gtid, taskdata, current_task));
1575 ompt_thread_info_t oldInfo;
1576 if (UNLIKELY(ompt_enabled.enabled)) {
1578 thread = __kmp_threads[gtid];
1579 oldInfo = thread->th.ompt_thread_info;
1580 thread->th.ompt_thread_info.wait_id = 0;
1581 thread->th.ompt_thread_info.state = (thread->th.th_team_serialized)
1582 ? ompt_state_work_serial
1583 : ompt_state_work_parallel;
1584 taskdata->ompt_task_info.frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1591 if (taskdata->td_flags.proxy != TASK_PROXY) {
1592 __kmp_task_start(gtid, task, current_task);
1598 if (UNLIKELY(__kmp_omp_cancellation)) {
1599 thread = __kmp_threads[gtid];
1600 kmp_team_t *this_team = thread->th.th_team;
1601 kmp_taskgroup_t *taskgroup = taskdata->td_taskgroup;
1602 if ((taskgroup && taskgroup->cancel_request) ||
1603 (this_team->t.t_cancel_request == cancel_parallel)) {
1604#if OMPT_SUPPORT && OMPT_OPTIONAL
1605 ompt_data_t *task_data;
1606 if (UNLIKELY(ompt_enabled.ompt_callback_cancel)) {
1607 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL, NULL);
1608 ompt_callbacks.ompt_callback(ompt_callback_cancel)(
1610 ((taskgroup && taskgroup->cancel_request) ? ompt_cancel_taskgroup
1611 : ompt_cancel_parallel) |
1612 ompt_cancel_discarded_task,
1625#if KMP_STATS_ENABLED
1627 switch (KMP_GET_THREAD_STATE()) {
1628 case FORK_JOIN_BARRIER:
1629 KMP_PUSH_PARTITIONED_TIMER(OMP_task_join_bar);
1632 KMP_PUSH_PARTITIONED_TIMER(OMP_task_plain_bar);
1635 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskyield);
1638 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskwait);
1641 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskgroup);
1644 KMP_PUSH_PARTITIONED_TIMER(OMP_task_immediate);
1651 if (UNLIKELY(ompt_enabled.enabled))
1652 __ompt_task_start(task, current_task, gtid);
1654#if OMPT_SUPPORT && OMPT_OPTIONAL
1655 if (UNLIKELY(ompt_enabled.ompt_callback_dispatch &&
1656 taskdata->ompt_task_info.dispatch_chunk.iterations > 0)) {
1657 ompt_data_t instance = ompt_data_none;
1658 instance.ptr = &(taskdata->ompt_task_info.dispatch_chunk);
1659 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
1660 ompt_callbacks.ompt_callback(ompt_callback_dispatch)(
1661 &(team_info->parallel_data), &(taskdata->ompt_task_info.task_data),
1662 ompt_dispatch_taskloop_chunk, instance);
1663 taskdata->ompt_task_info.dispatch_chunk = {0, 0};
1668 if (ompd_state & OMPD_ENABLE_BP)
1669 ompd_bp_task_begin();
1672#if USE_ITT_BUILD && USE_ITT_NOTIFY
1673 kmp_uint64 cur_time;
1674 kmp_int32 kmp_itt_count_task =
1675 __kmp_forkjoin_frames_mode == 3 && !taskdata->td_flags.task_serial &&
1676 current_task->td_flags.tasktype == TASK_IMPLICIT;
1677 if (kmp_itt_count_task) {
1678 thread = __kmp_threads[gtid];
1680 if (thread->th.th_bar_arrive_time)
1681 cur_time = __itt_get_timestamp();
1683 kmp_itt_count_task = 0;
1685 KMP_FSYNC_ACQUIRED(taskdata);
1688#if ENABLE_LIBOMPTARGET
1689 if (taskdata->td_target_data.async_handle != NULL) {
1693 KMP_ASSERT(tgt_target_nowait_query);
1694 tgt_target_nowait_query(&taskdata->td_target_data.async_handle);
1697 if (task->routine != NULL) {
1698#ifdef KMP_GOMP_COMPAT
1699 if (taskdata->td_flags.native) {
1700 ((void (*)(
void *))(*(task->routine)))(task->shareds);
1704 (*(task->routine))(gtid, task);
1707 KMP_POP_PARTITIONED_TIMER();
1709#if USE_ITT_BUILD && USE_ITT_NOTIFY
1710 if (kmp_itt_count_task) {
1712 thread->th.th_bar_arrive_time += (__itt_get_timestamp() - cur_time);
1714 KMP_FSYNC_CANCEL(taskdata);
1715 KMP_FSYNC_RELEASING(taskdata->td_parent);
1720 if (ompd_state & OMPD_ENABLE_BP)
1725 if (taskdata->td_flags.proxy != TASK_PROXY) {
1727 if (UNLIKELY(ompt_enabled.enabled)) {
1728 thread->th.ompt_thread_info = oldInfo;
1729 if (taskdata->td_flags.tiedness == TASK_TIED) {
1730 taskdata->ompt_task_info.frame.exit_frame = ompt_data_none;
1732 __kmp_task_finish<true>(gtid, task, current_task);
1735 __kmp_task_finish<false>(gtid, task, current_task);
1738 else if (UNLIKELY(ompt_enabled.enabled && taskdata->td_flags.target)) {
1739 __ompt_task_finish(task, current_task, ompt_task_switch);
1745 (
"__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n",
1746 gtid, taskdata, current_task));
1760kmp_int32 __kmpc_omp_task_parts(
ident_t *loc_ref, kmp_int32 gtid,
1761 kmp_task_t *new_task) {
1762 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1764 KA_TRACE(10, (
"__kmpc_omp_task_parts(enter): T#%d loc=%p task=%p\n", gtid,
1765 loc_ref, new_taskdata));
1768 kmp_taskdata_t *parent;
1769 if (UNLIKELY(ompt_enabled.enabled)) {
1770 parent = new_taskdata->td_parent;
1771 if (ompt_enabled.ompt_callback_task_create) {
1772 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
1773 &(parent->ompt_task_info.task_data), &(parent->ompt_task_info.frame),
1774 &(new_taskdata->ompt_task_info.task_data),
1775 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 0,
1776 OMPT_GET_RETURN_ADDRESS(0));
1784 if (__kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED)
1786 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
1787 new_taskdata->td_flags.task_serial = 1;
1788 __kmp_invoke_task(gtid, new_task, current_task);
1793 (
"__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
1794 "loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n",
1795 gtid, loc_ref, new_taskdata));
1798 if (UNLIKELY(ompt_enabled.enabled)) {
1799 parent->ompt_task_info.frame.enter_frame = ompt_data_none;
1800 parent->ompt_task_info.frame.enter_frame_flags = OMPT_FRAME_FLAGS_RUNTIME;
1803 return TASK_CURRENT_NOT_QUEUED;
1817kmp_int32 __kmp_omp_task(kmp_int32 gtid, kmp_task_t *new_task,
1818 bool serialize_immediate) {
1819 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1821#if OMP_TASKGRAPH_EXPERIMENTAL
1822 if (new_taskdata->is_taskgraph &&
1823 __kmp_tdg_is_recording(new_taskdata->tdg->tdg_status)) {
1824 kmp_tdg_info_t *tdg = new_taskdata->tdg;
1826 if (new_taskdata->td_tdg_task_id >= new_taskdata->tdg->map_size) {
1827 __kmp_acquire_bootstrap_lock(&tdg->graph_lock);
1830 if (new_taskdata->td_tdg_task_id >= tdg->map_size) {
1831 kmp_uint old_size = tdg->map_size;
1832 kmp_uint new_size = old_size * 2;
1833 kmp_node_info_t *old_record = tdg->record_map;
1834 kmp_node_info_t *new_record = (kmp_node_info_t *)__kmp_allocate(
1835 new_size *
sizeof(kmp_node_info_t));
1837 KMP_MEMCPY(new_record, old_record, old_size *
sizeof(kmp_node_info_t));
1838 tdg->record_map = new_record;
1840 __kmp_free(old_record);
1842 for (kmp_uint i = old_size; i < new_size; i++) {
1843 kmp_int32 *successorsList = (kmp_int32 *)__kmp_allocate(
1844 __kmp_successors_size *
sizeof(kmp_int32));
1845 new_record[i].task =
nullptr;
1846 new_record[i].successors = successorsList;
1847 new_record[i].nsuccessors = 0;
1848 new_record[i].npredecessors = 0;
1849 new_record[i].successors_size = __kmp_successors_size;
1850 KMP_ATOMIC_ST_REL(&new_record[i].npredecessors_counter, 0);
1854 tdg->map_size = new_size;
1856 __kmp_release_bootstrap_lock(&tdg->graph_lock);
1859 if (tdg->record_map[new_taskdata->td_tdg_task_id].task ==
nullptr) {
1860 tdg->record_map[new_taskdata->td_tdg_task_id].task = new_task;
1861 tdg->record_map[new_taskdata->td_tdg_task_id].parent_task =
1862 new_taskdata->td_parent;
1863 KMP_ATOMIC_INC(&tdg->num_tasks);
1870 if (new_taskdata->td_flags.proxy == TASK_PROXY ||
1871 __kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED)
1873 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
1874 if (serialize_immediate)
1875 new_taskdata->td_flags.task_serial = 1;
1876 __kmp_invoke_task(gtid, new_task, current_task);
1877 }
else if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME &&
1878 __kmp_wpolicy_passive) {
1879 kmp_info_t *this_thr = __kmp_threads[gtid];
1880 kmp_team_t *team = this_thr->th.th_team;
1881 kmp_int32 nthreads = this_thr->th.th_team_nproc;
1882 for (
int i = 0; i < nthreads; ++i) {
1883 kmp_info_t *thread = team->t.t_threads[i];
1884 if (thread == this_thr)
1886 if (thread->th.th_sleep_loc != NULL) {
1887 __kmp_null_resume_wrapper(thread);
1892 return TASK_CURRENT_NOT_QUEUED;
1907kmp_int32 __kmpc_omp_task(
ident_t *loc_ref, kmp_int32 gtid,
1908 kmp_task_t *new_task) {
1910 KMP_SET_THREAD_STATE_BLOCK(EXPLICIT_TASK);
1912#if KMP_DEBUG || OMPT_SUPPORT
1913 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1915 KA_TRACE(10, (
"__kmpc_omp_task(enter): T#%d loc=%p task=%p\n", gtid, loc_ref,
1917 __kmp_assert_valid_gtid(gtid);
1920 kmp_taskdata_t *parent = NULL;
1921 if (UNLIKELY(ompt_enabled.enabled)) {
1922 if (!new_taskdata->td_flags.started) {
1923 OMPT_STORE_RETURN_ADDRESS(gtid);
1924 parent = new_taskdata->td_parent;
1925 if (!parent->ompt_task_info.frame.enter_frame.ptr) {
1926 parent->ompt_task_info.frame.enter_frame.ptr =
1927 OMPT_GET_FRAME_ADDRESS(0);
1929 if (ompt_enabled.ompt_callback_task_create) {
1930 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
1931 &(parent->ompt_task_info.task_data),
1932 &(parent->ompt_task_info.frame),
1933 &(new_taskdata->ompt_task_info.task_data),
1934 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 0,
1935 OMPT_LOAD_RETURN_ADDRESS(gtid));
1940 __ompt_task_finish(new_task,
1941 new_taskdata->ompt_task_info.scheduling_parent,
1943 new_taskdata->ompt_task_info.frame.exit_frame = ompt_data_none;
1948 res = __kmp_omp_task(gtid, new_task,
true);
1950 KA_TRACE(10, (
"__kmpc_omp_task(exit): T#%d returning "
1951 "TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n",
1952 gtid, loc_ref, new_taskdata));
1954 if (UNLIKELY(ompt_enabled.enabled && parent != NULL)) {
1955 parent->ompt_task_info.frame.enter_frame = ompt_data_none;
1974kmp_int32 __kmp_omp_taskloop_task(
ident_t *loc_ref, kmp_int32 gtid,
1975 kmp_task_t *new_task,
void *codeptr_ra) {
1977 KMP_SET_THREAD_STATE_BLOCK(EXPLICIT_TASK);
1979#if KMP_DEBUG || OMPT_SUPPORT
1980 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1982 KA_TRACE(10, (
"__kmpc_omp_task(enter): T#%d loc=%p task=%p\n", gtid, loc_ref,
1986 kmp_taskdata_t *parent = NULL;
1987 if (UNLIKELY(ompt_enabled.enabled && !new_taskdata->td_flags.started)) {
1988 parent = new_taskdata->td_parent;
1989 if (!parent->ompt_task_info.frame.enter_frame.ptr)
1990 parent->ompt_task_info.frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1991 if (ompt_enabled.ompt_callback_task_create) {
1992 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
1993 &(parent->ompt_task_info.task_data), &(parent->ompt_task_info.frame),
1994 &(new_taskdata->ompt_task_info.task_data),
1995 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 0, codeptr_ra);
2000 res = __kmp_omp_task(gtid, new_task,
true);
2002 KA_TRACE(10, (
"__kmpc_omp_task(exit): T#%d returning "
2003 "TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n",
2004 gtid, loc_ref, new_taskdata));
2006 if (UNLIKELY(ompt_enabled.enabled && parent != NULL)) {
2007 parent->ompt_task_info.frame.enter_frame = ompt_data_none;
2014static kmp_int32 __kmpc_omp_taskwait_template(
ident_t *loc_ref, kmp_int32 gtid,
2015 void *frame_address,
2016 void *return_address) {
2017 kmp_taskdata_t *taskdata =
nullptr;
2019 int thread_finished = FALSE;
2020 KMP_SET_THREAD_STATE_BLOCK(TASKWAIT);
2022 KA_TRACE(10, (
"__kmpc_omp_taskwait(enter): T#%d loc=%p\n", gtid, loc_ref));
2023 KMP_DEBUG_ASSERT(gtid >= 0);
2025 if (__kmp_tasking_mode != tskm_immediate_exec) {
2026 thread = __kmp_threads[gtid];
2027 taskdata = thread->th.th_current_task;
2029#if OMPT_SUPPORT && OMPT_OPTIONAL
2030 ompt_data_t *my_task_data;
2031 ompt_data_t *my_parallel_data;
2034 my_task_data = &(taskdata->ompt_task_info.task_data);
2035 my_parallel_data = OMPT_CUR_TEAM_DATA(thread);
2037 taskdata->ompt_task_info.frame.enter_frame.ptr = frame_address;
2039 if (ompt_enabled.ompt_callback_sync_region) {
2040 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
2041 ompt_sync_region_taskwait, ompt_scope_begin, my_parallel_data,
2042 my_task_data, return_address);
2045 if (ompt_enabled.ompt_callback_sync_region_wait) {
2046 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
2047 ompt_sync_region_taskwait, ompt_scope_begin, my_parallel_data,
2048 my_task_data, return_address);
2053#if ENABLE_LIBOMPTARGET
2056 if (UNLIKELY(kmp_target_sync_cb))
2057 (*kmp_target_sync_cb)(loc_ref, gtid, KMP_TASKDATA_TO_TASK(taskdata),
2066 taskdata->td_taskwait_counter += 1;
2067 taskdata->td_taskwait_ident = loc_ref;
2068 taskdata->td_taskwait_thread = gtid + 1;
2071 void *itt_sync_obj = NULL;
2073 KMP_ITT_TASKWAIT_STARTING(itt_sync_obj);
2078 !taskdata->td_flags.team_serial && !taskdata->td_flags.final;
2080 must_wait = must_wait || (thread->th.th_task_team != NULL &&
2081 thread->th.th_task_team->tt.tt_found_proxy_tasks);
2085 (__kmp_enable_hidden_helper && thread->th.th_task_team != NULL &&
2086 thread->th.th_task_team->tt.tt_hidden_helper_task_encountered);
2089 kmp_flag_32<false, false> flag(
2090 RCAST(std::atomic<kmp_uint32> *,
2091 &(taskdata->td_incomplete_child_tasks)),
2093 while (KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks) != 0) {
2094 flag.execute_tasks(thread, gtid, FALSE,
2095 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj),
2096 __kmp_task_stealing_constraint);
2100 KMP_ITT_TASKWAIT_FINISHED(itt_sync_obj);
2101 KMP_FSYNC_ACQUIRED(taskdata);
2106 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
2108#if OMPT_SUPPORT && OMPT_OPTIONAL
2110 if (ompt_enabled.ompt_callback_sync_region_wait) {
2111 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
2112 ompt_sync_region_taskwait, ompt_scope_end, my_parallel_data,
2113 my_task_data, return_address);
2115 if (ompt_enabled.ompt_callback_sync_region) {
2116 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
2117 ompt_sync_region_taskwait, ompt_scope_end, my_parallel_data,
2118 my_task_data, return_address);
2120 taskdata->ompt_task_info.frame.enter_frame = ompt_data_none;
2125 KA_TRACE(10, (
"__kmpc_omp_taskwait(exit): T#%d task %p finished waiting, "
2126 "returning TASK_CURRENT_NOT_QUEUED\n",
2129 return TASK_CURRENT_NOT_QUEUED;
2132#if OMPT_SUPPORT && OMPT_OPTIONAL
2134static kmp_int32 __kmpc_omp_taskwait_ompt(
ident_t *loc_ref, kmp_int32 gtid,
2135 void *frame_address,
2136 void *return_address) {
2137 return __kmpc_omp_taskwait_template<true>(loc_ref, gtid, frame_address,
2144kmp_int32 __kmpc_omp_taskwait(
ident_t *loc_ref, kmp_int32 gtid) {
2145#if OMPT_SUPPORT && OMPT_OPTIONAL
2146 if (UNLIKELY(ompt_enabled.enabled)) {
2147 OMPT_STORE_RETURN_ADDRESS(gtid);
2148 return __kmpc_omp_taskwait_ompt(loc_ref, gtid, OMPT_GET_FRAME_ADDRESS(0),
2149 OMPT_LOAD_RETURN_ADDRESS(gtid));
2152 return __kmpc_omp_taskwait_template<false>(loc_ref, gtid, NULL, NULL);
2156kmp_int32 __kmpc_omp_taskyield(
ident_t *loc_ref, kmp_int32 gtid,
int end_part) {
2157 kmp_taskdata_t *taskdata = NULL;
2159 int thread_finished = FALSE;
2162 KMP_SET_THREAD_STATE_BLOCK(TASKYIELD);
2164 KA_TRACE(10, (
"__kmpc_omp_taskyield(enter): T#%d loc=%p end_part = %d\n",
2165 gtid, loc_ref, end_part));
2166 __kmp_assert_valid_gtid(gtid);
2168 if (__kmp_tasking_mode != tskm_immediate_exec && __kmp_init_parallel) {
2169 thread = __kmp_threads[gtid];
2170 taskdata = thread->th.th_current_task;
2177 taskdata->td_taskwait_counter += 1;
2178 taskdata->td_taskwait_ident = loc_ref;
2179 taskdata->td_taskwait_thread = gtid + 1;
2182 void *itt_sync_obj = NULL;
2184 KMP_ITT_TASKWAIT_STARTING(itt_sync_obj);
2187 if (!taskdata->td_flags.team_serial) {
2188 kmp_task_team_t *task_team = thread->th.th_task_team;
2189 if (task_team != NULL) {
2190 if (KMP_TASKING_ENABLED(task_team)) {
2192 if (UNLIKELY(ompt_enabled.enabled))
2193 thread->th.ompt_thread_info.ompt_task_yielded = 1;
2195 __kmp_execute_tasks_32(
2196 thread, gtid, (kmp_flag_32<> *)NULL, FALSE,
2197 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj),
2198 __kmp_task_stealing_constraint);
2200 if (UNLIKELY(ompt_enabled.enabled))
2201 thread->th.ompt_thread_info.ompt_task_yielded = 0;
2207 KMP_ITT_TASKWAIT_FINISHED(itt_sync_obj);
2212 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
2215 KA_TRACE(10, (
"__kmpc_omp_taskyield(exit): T#%d task %p resuming, "
2216 "returning TASK_CURRENT_NOT_QUEUED\n",
2219 return TASK_CURRENT_NOT_QUEUED;
2240 unsigned reserved31 : 31;
2320template <
typename T>
2321void *__kmp_task_reduction_init(
int gtid,
int num, T *data) {
2322 __kmp_assert_valid_gtid(gtid);
2323 kmp_info_t *thread = __kmp_threads[gtid];
2324 kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
2325 kmp_uint32 nth = thread->th.th_team_nproc;
2329 KMP_ASSERT(tg != NULL);
2330 KMP_ASSERT(data != NULL);
2331 KMP_ASSERT(num > 0);
2332 if (nth == 1 && !__kmp_enable_hidden_helper) {
2333 KA_TRACE(10, (
"__kmpc_task_reduction_init: T#%d, tg %p, exiting nth=1\n",
2337 KA_TRACE(10, (
"__kmpc_task_reduction_init: T#%d, taskgroup %p, #items %d\n",
2341 for (
int i = 0; i < num; ++i) {
2342 size_t size = data[i].reduce_size - 1;
2344 size += CACHE_LINE - size % CACHE_LINE;
2345 KMP_ASSERT(data[i].reduce_comb != NULL);
2348 arr[i].
flags = data[i].flags;
2352 __kmp_assign_orig<T>(arr[i], data[i]);
2353 if (!arr[i].flags.lazy_priv) {
2356 arr[i].
reduce_pend = (
char *)(arr[i].reduce_priv) + nth * size;
2357 if (arr[i].reduce_init != NULL) {
2359 for (
size_t j = 0; j < nth; ++j) {
2360 __kmp_call_init<T>(arr[i], j * size);
2367 arr[i].
reduce_priv = __kmp_allocate(nth *
sizeof(
void *));
2370 tg->reduce_data = (
void *)arr;
2371 tg->reduce_num_data = num;
2390#if OMP_TASKGRAPH_EXPERIMENTAL
2391 kmp_tdg_info_t *tdg = __kmp_find_tdg(__kmp_curr_tdg_idx);
2392 if (tdg && __kmp_tdg_is_recording(tdg->tdg_status)) {
2393 kmp_tdg_info_t *this_tdg = __kmp_global_tdgs[__kmp_curr_tdg_idx];
2394 this_tdg->rec_taskred_data =
2396 this_tdg->rec_num_taskred = num;
2397 KMP_MEMCPY(this_tdg->rec_taskred_data, data,
2417#if OMP_TASKGRAPH_EXPERIMENTAL
2418 kmp_tdg_info_t *tdg = __kmp_find_tdg(__kmp_curr_tdg_idx);
2419 if (tdg && __kmp_tdg_is_recording(tdg->tdg_status)) {
2420 kmp_tdg_info_t *this_tdg = __kmp_global_tdgs[__kmp_curr_tdg_idx];
2421 this_tdg->rec_taskred_data =
2423 this_tdg->rec_num_taskred = num;
2424 KMP_MEMCPY(this_tdg->rec_taskred_data, data,
2432template <
typename T>
2433void __kmp_task_reduction_init_copy(kmp_info_t *thr,
int num, T *data,
2434 kmp_taskgroup_t *tg,
void *reduce_data) {
2436 KA_TRACE(20, (
"__kmp_task_reduction_init_copy: Th %p, init taskgroup %p,"
2438 thr, tg, reduce_data));
2443 for (
int i = 0; i < num; ++i) {
2446 tg->reduce_data = (
void *)arr;
2447 tg->reduce_num_data = num;
2460 __kmp_assert_valid_gtid(gtid);
2461 kmp_info_t *thread = __kmp_threads[gtid];
2462 kmp_int32 nth = thread->th.th_team_nproc;
2466 kmp_taskgroup_t *tg = (kmp_taskgroup_t *)tskgrp;
2468 tg = thread->th.th_current_task->td_taskgroup;
2469 KMP_ASSERT(tg != NULL);
2472 kmp_int32 tid = thread->th.th_info.ds.ds_tid;
2474#if OMP_TASKGRAPH_EXPERIMENTAL
2475 if ((thread->th.th_current_task->is_taskgraph) &&
2476 (!__kmp_tdg_is_recording(
2477 __kmp_global_tdgs[__kmp_curr_tdg_idx]->tdg_status))) {
2478 tg = thread->th.th_current_task->td_taskgroup;
2479 KMP_ASSERT(tg != NULL);
2480 KMP_ASSERT(tg->reduce_data != NULL);
2482 num = tg->reduce_num_data;
2486 KMP_ASSERT(data != NULL);
2487 while (tg != NULL) {
2489 num = tg->reduce_num_data;
2490 for (
int i = 0; i < num; ++i) {
2491 if (!arr[i].flags.lazy_priv) {
2492 if (data == arr[i].reduce_shar ||
2493 (data >= arr[i].reduce_priv && data < arr[i].reduce_pend))
2494 return (
char *)(arr[i].
reduce_priv) + tid * arr[i].reduce_size;
2497 void **p_priv = (
void **)(arr[i].reduce_priv);
2498 if (data == arr[i].reduce_shar)
2501 for (
int j = 0; j < nth; ++j)
2502 if (data == p_priv[j])
2506 if (p_priv[tid] == NULL) {
2508 p_priv[tid] = __kmp_allocate(arr[i].reduce_size);
2509 if (arr[i].reduce_init != NULL) {
2510 if (arr[i].reduce_orig != NULL) {
2511 ((void (*)(
void *,
void *))arr[i].reduce_init)(
2514 ((void (*)(
void *))arr[i].reduce_init)(p_priv[tid]);
2521 KMP_ASSERT(tg->parent);
2524 KMP_ASSERT2(0,
"Unknown task reduction item");
2530static void __kmp_task_reduction_fini(kmp_info_t *th, kmp_taskgroup_t *tg) {
2531 kmp_int32 nth = th->th.th_team_nproc;
2534 __kmp_enable_hidden_helper);
2537 kmp_int32 num = tg->reduce_num_data;
2538 for (
int i = 0; i < num; ++i) {
2540 void (*f_fini)(
void *) = (
void (*)(
void *))(arr[i].
reduce_fini);
2541 void (*f_comb)(
void *,
void *) =
2543 if (!arr[i].flags.lazy_priv) {
2546 for (
int j = 0; j < nth; ++j) {
2547 void *priv_data = (
char *)pr_data + j * size;
2548 f_comb(sh_data, priv_data);
2553 void **pr_data = (
void **)(arr[i].reduce_priv);
2554 for (
int j = 0; j < nth; ++j) {
2555 if (pr_data[j] != NULL) {
2556 f_comb(sh_data, pr_data[j]);
2559 __kmp_free(pr_data[j]);
2563 __kmp_free(arr[i].reduce_priv);
2565 __kmp_thread_free(th, arr);
2566 tg->reduce_data = NULL;
2567 tg->reduce_num_data = 0;
2573static void __kmp_task_reduction_clean(kmp_info_t *th, kmp_taskgroup_t *tg) {
2574 __kmp_thread_free(th, tg->reduce_data);
2575 tg->reduce_data = NULL;
2576 tg->reduce_num_data = 0;
2579template <
typename T>
2580void *__kmp_task_reduction_modifier_init(
ident_t *loc,
int gtid,
int is_ws,
2582 __kmp_assert_valid_gtid(gtid);
2583 kmp_info_t *thr = __kmp_threads[gtid];
2584 kmp_int32 nth = thr->th.th_team_nproc;
2585 __kmpc_taskgroup(loc, gtid);
2588 (
"__kmpc_reduction_modifier_init: T#%d, tg %p, exiting nth=1\n",
2589 gtid, thr->th.th_current_task->td_taskgroup));
2590 return (
void *)thr->th.th_current_task->td_taskgroup;
2592 kmp_team_t *team = thr->th.th_team;
2594 kmp_taskgroup_t *tg;
2595 reduce_data = KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[is_ws]);
2596 if (reduce_data == NULL &&
2597 __kmp_atomic_compare_store(&team->t.t_tg_reduce_data[is_ws], reduce_data,
2600 KMP_DEBUG_ASSERT(reduce_data == NULL);
2602 tg = (kmp_taskgroup_t *)__kmp_task_reduction_init<T>(gtid, num, data);
2606 KMP_DEBUG_ASSERT(KMP_ATOMIC_LD_RLX(&team->t.t_tg_fini_counter[0]) == 0);
2607 KMP_DEBUG_ASSERT(KMP_ATOMIC_LD_RLX(&team->t.t_tg_fini_counter[1]) == 0);
2608 KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[is_ws], reduce_data);
2611 (reduce_data = KMP_ATOMIC_LD_ACQ(&team->t.t_tg_reduce_data[is_ws])) ==
2615 KMP_DEBUG_ASSERT(reduce_data > (
void *)1);
2616 tg = thr->th.th_current_task->td_taskgroup;
2617 __kmp_task_reduction_init_copy<T>(thr, num, data, tg, reduce_data);
2639 int num,
void *data) {
2640 return __kmp_task_reduction_modifier_init(loc, gtid, is_ws, num,
2660 return __kmp_task_reduction_modifier_init(loc, gtid, is_ws, num,
2673 __kmpc_end_taskgroup(loc, gtid);
2677void __kmpc_taskgroup(
ident_t *loc,
int gtid) {
2678 __kmp_assert_valid_gtid(gtid);
2679 kmp_info_t *thread = __kmp_threads[gtid];
2680 kmp_taskdata_t *taskdata = thread->th.th_current_task;
2681 kmp_taskgroup_t *tg_new =
2682 (kmp_taskgroup_t *)__kmp_thread_malloc(thread,
sizeof(kmp_taskgroup_t));
2683 KA_TRACE(10, (
"__kmpc_taskgroup: T#%d loc=%p group=%p\n", gtid, loc, tg_new));
2684 KMP_ATOMIC_ST_RLX(&tg_new->count, 0);
2685 KMP_ATOMIC_ST_RLX(&tg_new->cancel_request, cancel_noreq);
2686 tg_new->parent = taskdata->td_taskgroup;
2687 tg_new->reduce_data = NULL;
2688 tg_new->reduce_num_data = 0;
2689 tg_new->gomp_data = NULL;
2690 taskdata->td_taskgroup = tg_new;
2692#if OMPT_SUPPORT && OMPT_OPTIONAL
2693 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region)) {
2694 void *codeptr = OMPT_LOAD_RETURN_ADDRESS(gtid);
2696 codeptr = OMPT_GET_RETURN_ADDRESS(0);
2697 kmp_team_t *team = thread->th.th_team;
2698 ompt_data_t my_task_data = taskdata->ompt_task_info.task_data;
2700 ompt_data_t my_parallel_data = team->t.ompt_team_info.parallel_data;
2702 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
2703 ompt_sync_region_taskgroup, ompt_scope_begin, &(my_parallel_data),
2704 &(my_task_data), codeptr);
2711void __kmpc_end_taskgroup(
ident_t *loc,
int gtid) {
2712 __kmp_assert_valid_gtid(gtid);
2713 kmp_info_t *thread = __kmp_threads[gtid];
2714 kmp_taskdata_t *taskdata = thread->th.th_current_task;
2715 kmp_taskgroup_t *taskgroup = taskdata->td_taskgroup;
2716 int thread_finished = FALSE;
2718#if OMPT_SUPPORT && OMPT_OPTIONAL
2720 ompt_data_t my_task_data;
2721 ompt_data_t my_parallel_data;
2722 void *codeptr =
nullptr;
2723 if (UNLIKELY(ompt_enabled.enabled)) {
2724 team = thread->th.th_team;
2725 my_task_data = taskdata->ompt_task_info.task_data;
2727 my_parallel_data = team->t.ompt_team_info.parallel_data;
2728 codeptr = OMPT_LOAD_RETURN_ADDRESS(gtid);
2730 codeptr = OMPT_GET_RETURN_ADDRESS(0);
2734 KA_TRACE(10, (
"__kmpc_end_taskgroup(enter): T#%d loc=%p\n", gtid, loc));
2735 KMP_DEBUG_ASSERT(taskgroup != NULL);
2736 KMP_SET_THREAD_STATE_BLOCK(TASKGROUP);
2738 if (__kmp_tasking_mode != tskm_immediate_exec) {
2740 taskdata->td_taskwait_counter += 1;
2741 taskdata->td_taskwait_ident = loc;
2742 taskdata->td_taskwait_thread = gtid + 1;
2746 void *itt_sync_obj = NULL;
2748 KMP_ITT_TASKWAIT_STARTING(itt_sync_obj);
2752#if OMPT_SUPPORT && OMPT_OPTIONAL
2753 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region_wait)) {
2754 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
2755 ompt_sync_region_taskgroup, ompt_scope_begin, &(my_parallel_data),
2756 &(my_task_data), codeptr);
2760#if ENABLE_LIBOMPTARGET
2763 if (UNLIKELY(kmp_target_sync_cb))
2764 (*kmp_target_sync_cb)(loc, gtid, KMP_TASKDATA_TO_TASK(taskdata), NULL);
2767 if (!taskdata->td_flags.team_serial ||
2768 (thread->th.th_task_team != NULL &&
2769 (thread->th.th_task_team->tt.tt_found_proxy_tasks ||
2770 thread->th.th_task_team->tt.tt_hidden_helper_task_encountered))) {
2771 kmp_flag_32<false, false> flag(
2772 RCAST(std::atomic<kmp_uint32> *, &(taskgroup->count)), 0U);
2773 while (KMP_ATOMIC_LD_ACQ(&taskgroup->count) != 0) {
2774 flag.execute_tasks(thread, gtid, FALSE,
2775 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj),
2776 __kmp_task_stealing_constraint);
2779 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
2781#if OMPT_SUPPORT && OMPT_OPTIONAL
2782 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region_wait)) {
2783 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
2784 ompt_sync_region_taskgroup, ompt_scope_end, &(my_parallel_data),
2785 &(my_task_data), codeptr);
2790 KMP_ITT_TASKWAIT_FINISHED(itt_sync_obj);
2791 KMP_FSYNC_ACQUIRED(taskdata);
2794 KMP_DEBUG_ASSERT(taskgroup->count == 0);
2796 if (taskgroup->reduce_data != NULL &&
2797 !taskgroup->gomp_data) {
2800 kmp_team_t *t = thread->th.th_team;
2804 if ((reduce_data = KMP_ATOMIC_LD_ACQ(&t->t.t_tg_reduce_data[0])) != NULL &&
2807 cnt = KMP_ATOMIC_INC(&t->t.t_tg_fini_counter[0]);
2808 if (cnt == thread->th.th_team_nproc - 1) {
2811 __kmp_task_reduction_fini(thread, taskgroup);
2814 __kmp_thread_free(thread, reduce_data);
2815 KMP_ATOMIC_ST_REL(&t->t.t_tg_reduce_data[0], NULL);
2816 KMP_ATOMIC_ST_REL(&t->t.t_tg_fini_counter[0], 0);
2820 __kmp_task_reduction_clean(thread, taskgroup);
2822 }
else if ((reduce_data = KMP_ATOMIC_LD_ACQ(&t->t.t_tg_reduce_data[1])) !=
2826 cnt = KMP_ATOMIC_INC(&t->t.t_tg_fini_counter[1]);
2827 if (cnt == thread->th.th_team_nproc - 1) {
2829 __kmp_task_reduction_fini(thread, taskgroup);
2832 __kmp_thread_free(thread, reduce_data);
2833 KMP_ATOMIC_ST_REL(&t->t.t_tg_reduce_data[1], NULL);
2834 KMP_ATOMIC_ST_REL(&t->t.t_tg_fini_counter[1], 0);
2838 __kmp_task_reduction_clean(thread, taskgroup);
2842 __kmp_task_reduction_fini(thread, taskgroup);
2846 taskdata->td_taskgroup = taskgroup->parent;
2847 __kmp_thread_free(thread, taskgroup);
2849 KA_TRACE(10, (
"__kmpc_end_taskgroup(exit): T#%d task %p finished waiting\n",
2852#if OMPT_SUPPORT && OMPT_OPTIONAL
2853 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region)) {
2854 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
2855 ompt_sync_region_taskgroup, ompt_scope_end, &(my_parallel_data),
2856 &(my_task_data), codeptr);
2861static kmp_task_t *__kmp_get_priority_task(kmp_int32 gtid,
2862 kmp_task_team_t *task_team,
2863 kmp_int32 is_constrained) {
2864 kmp_task_t *task = NULL;
2865 kmp_taskdata_t *taskdata;
2866 kmp_taskdata_t *current;
2867 kmp_thread_data_t *thread_data;
2868 int ntasks = task_team->tt.tt_num_task_pri;
2871 20, (
"__kmp_get_priority_task(exit #1): T#%d No tasks to get\n", gtid));
2876 if (__kmp_atomic_compare_store(&task_team->tt.tt_num_task_pri, ntasks,
2879 ntasks = task_team->tt.tt_num_task_pri;
2880 }
while (ntasks > 0);
2882 KA_TRACE(20, (
"__kmp_get_priority_task(exit #2): T#%d No tasks to get\n",
2888 kmp_task_pri_t *list = task_team->tt.tt_task_pri_list;
2890 KMP_ASSERT(list != NULL);
2891 thread_data = &list->td;
2892 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
2893 deque_ntasks = thread_data->td.td_deque_ntasks;
2894 if (deque_ntasks == 0) {
2895 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2896 KA_TRACE(20, (
"__kmp_get_priority_task: T#%d No tasks to get from %p\n",
2897 __kmp_get_gtid(), thread_data));
2900 }
while (deque_ntasks == 0);
2901 KMP_DEBUG_ASSERT(deque_ntasks);
2902 int target = thread_data->td.td_deque_head;
2903 current = __kmp_threads[gtid]->th.th_current_task;
2904 taskdata = thread_data->td.td_deque[target];
2905 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
2907 thread_data->td.td_deque_head =
2908 (target + 1) & TASK_DEQUE_MASK(thread_data->td);
2910 if (!task_team->tt.tt_untied_task_encountered) {
2912 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2913 KA_TRACE(20, (
"__kmp_get_priority_task(exit #3): T#%d could not get task "
2914 "from %p: task_team=%p ntasks=%d head=%u tail=%u\n",
2915 gtid, thread_data, task_team, deque_ntasks, target,
2916 thread_data->td.td_deque_tail));
2917 task_team->tt.tt_num_task_pri++;
2923 for (i = 1; i < deque_ntasks; ++i) {
2924 target = (target + 1) & TASK_DEQUE_MASK(thread_data->td);
2925 taskdata = thread_data->td.td_deque[target];
2926 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
2932 if (taskdata == NULL) {
2934 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2936 10, (
"__kmp_get_priority_task(exit #4): T#%d could not get task from "
2937 "%p: task_team=%p ntasks=%d head=%u tail=%u\n",
2938 gtid, thread_data, task_team, deque_ntasks,
2939 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2940 task_team->tt.tt_num_task_pri++;
2944 for (i = i + 1; i < deque_ntasks; ++i) {
2946 target = (target + 1) & TASK_DEQUE_MASK(thread_data->td);
2947 thread_data->td.td_deque[prev] = thread_data->td.td_deque[target];
2951 thread_data->td.td_deque_tail ==
2952 (kmp_uint32)((target + 1) & TASK_DEQUE_MASK(thread_data->td)));
2953 thread_data->td.td_deque_tail = target;
2955 thread_data->td.td_deque_ntasks = deque_ntasks - 1;
2956 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2957 task = KMP_TASKDATA_TO_TASK(taskdata);
2962static kmp_task_t *__kmp_remove_my_task(kmp_info_t *thread, kmp_int32 gtid,
2963 kmp_task_team_t *task_team,
2964 kmp_int32 is_constrained) {
2966 kmp_taskdata_t *taskdata;
2967 kmp_thread_data_t *thread_data;
2970 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
2971 KMP_DEBUG_ASSERT(task_team->tt.tt_threads_data !=
2974 thread_data = &task_team->tt.tt_threads_data[__kmp_tid_from_gtid(gtid)];
2976 KA_TRACE(10, (
"__kmp_remove_my_task(enter): T#%d ntasks=%d head=%u tail=%u\n",
2977 gtid, thread_data->td.td_deque_ntasks,
2978 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2980 if (TCR_4(thread_data->td.td_deque_ntasks) == 0) {
2982 (
"__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
2983 "ntasks=%d head=%u tail=%u\n",
2984 gtid, thread_data->td.td_deque_ntasks,
2985 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2989 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
2991 if (TCR_4(thread_data->td.td_deque_ntasks) == 0) {
2992 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2994 (
"__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
2995 "ntasks=%d head=%u tail=%u\n",
2996 gtid, thread_data->td.td_deque_ntasks,
2997 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
3001 tail = (thread_data->td.td_deque_tail - 1) &
3002 TASK_DEQUE_MASK(thread_data->td);
3003 taskdata = thread_data->td.td_deque[tail];
3005 if (!__kmp_task_is_allowed(gtid, is_constrained, taskdata,
3006 thread->th.th_current_task)) {
3008 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
3010 (
"__kmp_remove_my_task(exit #3): T#%d TSC blocks tail task: "
3011 "ntasks=%d head=%u tail=%u\n",
3012 gtid, thread_data->td.td_deque_ntasks,
3013 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
3017 thread_data->td.td_deque_tail = tail;
3018 TCW_4(thread_data->td.td_deque_ntasks, thread_data->td.td_deque_ntasks - 1);
3020 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
3022 KA_TRACE(10, (
"__kmp_remove_my_task(exit #4): T#%d task %p removed: "
3023 "ntasks=%d head=%u tail=%u\n",
3024 gtid, taskdata, thread_data->td.td_deque_ntasks,
3025 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
3027 task = KMP_TASKDATA_TO_TASK(taskdata);
3034static kmp_task_t *__kmp_steal_task(kmp_int32 victim_tid, kmp_int32 gtid,
3035 kmp_task_team_t *task_team,
3036 std::atomic<kmp_int32> *unfinished_threads,
3037 int *thread_finished,
3038 kmp_int32 is_constrained) {
3040 kmp_taskdata_t *taskdata;
3041 kmp_taskdata_t *current;
3042 kmp_thread_data_t *victim_td, *threads_data;
3044 kmp_info_t *victim_thr;
3046 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3048 threads_data = task_team->tt.tt_threads_data;
3049 KMP_DEBUG_ASSERT(threads_data != NULL);
3050 KMP_DEBUG_ASSERT(victim_tid >= 0);
3051 KMP_DEBUG_ASSERT(victim_tid < task_team->tt.tt_max_threads);
3053 victim_td = &threads_data[victim_tid];
3054 victim_thr = victim_td->td.td_thr;
3057 KA_TRACE(10, (
"__kmp_steal_task(enter): T#%d try to steal from T#%d: "
3058 "task_team=%p ntasks=%d head=%u tail=%u\n",
3059 gtid, __kmp_gtid_from_thread(victim_thr), task_team,
3060 victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head,
3061 victim_td->td.td_deque_tail));
3063 if (TCR_4(victim_td->td.td_deque_ntasks) == 0) {
3064 KA_TRACE(10, (
"__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
3065 "task_team=%p ntasks=%d head=%u tail=%u\n",
3066 gtid, __kmp_gtid_from_thread(victim_thr), task_team,
3067 victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head,
3068 victim_td->td.td_deque_tail));
3072 __kmp_acquire_bootstrap_lock(&victim_td->td.td_deque_lock);
3074 int ntasks = TCR_4(victim_td->td.td_deque_ntasks);
3077 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
3078 KA_TRACE(10, (
"__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "
3079 "task_team=%p ntasks=%d head=%u tail=%u\n",
3080 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,
3081 victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
3085 KMP_DEBUG_ASSERT(victim_td->td.td_deque != NULL);
3086 current = __kmp_threads[gtid]->th.th_current_task;
3087 taskdata = victim_td->td.td_deque[victim_td->td.td_deque_head];
3088 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
3090 victim_td->td.td_deque_head =
3091 (victim_td->td.td_deque_head + 1) & TASK_DEQUE_MASK(victim_td->td);
3093 if (!task_team->tt.tt_untied_task_encountered) {
3095 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
3096 KA_TRACE(10, (
"__kmp_steal_task(exit #3): T#%d could not steal from "
3097 "T#%d: task_team=%p ntasks=%d head=%u tail=%u\n",
3098 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,
3099 victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
3104 target = victim_td->td.td_deque_head;
3106 for (i = 1; i < ntasks; ++i) {
3107 target = (target + 1) & TASK_DEQUE_MASK(victim_td->td);
3108 taskdata = victim_td->td.td_deque[target];
3109 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
3115 if (taskdata == NULL) {
3117 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
3118 KA_TRACE(10, (
"__kmp_steal_task(exit #4): T#%d could not steal from "
3119 "T#%d: task_team=%p ntasks=%d head=%u tail=%u\n",
3120 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,
3121 victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
3125 for (i = i + 1; i < ntasks; ++i) {
3127 target = (target + 1) & TASK_DEQUE_MASK(victim_td->td);
3128 victim_td->td.td_deque[prev] = victim_td->td.td_deque[target];
3132 victim_td->td.td_deque_tail ==
3133 (kmp_uint32)((target + 1) & TASK_DEQUE_MASK(victim_td->td)));
3134 victim_td->td.td_deque_tail = target;
3136 if (*thread_finished) {
3143 KMP_ATOMIC_INC(unfinished_threads);
3146 (
"__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n",
3147 gtid, count + 1, task_team));
3148 *thread_finished = FALSE;
3150 TCW_4(victim_td->td.td_deque_ntasks, ntasks - 1);
3152 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
3156 (
"__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
3157 "task_team=%p ntasks=%d head=%u tail=%u\n",
3158 gtid, taskdata, __kmp_gtid_from_thread(victim_thr), task_team,
3159 ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
3161 task = KMP_TASKDATA_TO_TASK(taskdata);
3175static inline int __kmp_execute_tasks_template(
3176 kmp_info_t *thread, kmp_int32 gtid, C *flag,
int final_spin,
3177 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3178 kmp_int32 is_constrained) {
3179 kmp_task_team_t *task_team = thread->th.th_task_team;
3180 kmp_thread_data_t *threads_data;
3182 kmp_info_t *other_thread;
3183 kmp_taskdata_t *current_task = thread->th.th_current_task;
3184 std::atomic<kmp_int32> *unfinished_threads;
3185 kmp_int32 nthreads, victim_tid = -2, use_own_tasks = 1, new_victim = 0,
3186 tid = thread->th.th_info.ds.ds_tid;
3188 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3189 KMP_DEBUG_ASSERT(thread == __kmp_threads[gtid]);
3191 if (task_team == NULL || current_task == NULL)
3194 KA_TRACE(15, (
"__kmp_execute_tasks_template(enter): T#%d final_spin=%d "
3195 "*thread_finished=%d\n",
3196 gtid, final_spin, *thread_finished));
3198 thread->th.th_reap_state = KMP_NOT_SAFE_TO_REAP;
3199 threads_data = (kmp_thread_data_t *)TCR_PTR(task_team->tt.tt_threads_data);
3201 KMP_DEBUG_ASSERT(threads_data != NULL);
3203 nthreads = task_team->tt.tt_nproc;
3204 unfinished_threads = &(task_team->tt.tt_unfinished_threads);
3205 KMP_DEBUG_ASSERT(*unfinished_threads >= 0);
3210#if ENABLE_LIBOMPTARGET
3212 if (UNLIKELY(kmp_target_sync_cb))
3213 (*kmp_target_sync_cb)(NULL, gtid, KMP_TASKDATA_TO_TASK(current_task),
3218 if (task_team->tt.tt_num_task_pri) {
3219 task = __kmp_get_priority_task(gtid, task_team, is_constrained);
3221 if (task == NULL && use_own_tasks) {
3222 task = __kmp_remove_my_task(thread, gtid, task_team, is_constrained);
3224 if ((task == NULL) && (nthreads > 1)) {
3228 if (victim_tid == -2) {
3229 victim_tid = threads_data[tid].td.td_deque_last_stolen;
3232 other_thread = threads_data[victim_tid].td.td_thr;
3234 if (victim_tid != -1) {
3236 }
else if (!new_victim) {
3242 victim_tid = __kmp_get_random(thread) % (nthreads - 1);
3243 if (victim_tid >= tid) {
3247 other_thread = threads_data[victim_tid].td.td_thr;
3257 if ((__kmp_tasking_mode == tskm_task_teams) &&
3258 (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME) &&
3259 (TCR_PTR(CCAST(
void *, other_thread->th.th_sleep_loc)) !=
3262 __kmp_null_resume_wrapper(other_thread);
3276 __kmp_steal_task(victim_tid, gtid, task_team, unfinished_threads,
3277 thread_finished, is_constrained);
3280 if (threads_data[tid].td.td_deque_last_stolen != victim_tid) {
3281 threads_data[tid].td.td_deque_last_stolen = victim_tid;
3288 KMP_CHECK_UPDATE(threads_data[tid].td.td_deque_last_stolen, -1);
3297#if USE_ITT_BUILD && USE_ITT_NOTIFY
3298 if (__itt_sync_create_ptr || KMP_ITT_DEBUG) {
3299 if (itt_sync_obj == NULL) {
3301 itt_sync_obj = __kmp_itt_barrier_object(gtid, bs_forkjoin_barrier);
3303 __kmp_itt_task_starting(itt_sync_obj);
3306 __kmp_invoke_task(gtid, task, current_task);
3308 if (itt_sync_obj != NULL)
3309 __kmp_itt_task_finished(itt_sync_obj);
3316 if (flag == NULL || (!final_spin && flag->done_check())) {
3319 (
"__kmp_execute_tasks_template: T#%d spin condition satisfied\n",
3323 if (thread->th.th_task_team == NULL) {
3326 KMP_YIELD(__kmp_library == library_throughput);
3329 if (!use_own_tasks && TCR_4(threads_data[tid].td.td_deque_ntasks) != 0) {
3330 KA_TRACE(20, (
"__kmp_execute_tasks_template: T#%d stolen task spawned "
3331 "other tasks, restart\n",
3342 KMP_ATOMIC_LD_ACQ(¤t_task->td_incomplete_child_tasks) == 0) {
3346 if (!*thread_finished) {
3348 kmp_int32 count = -1 +
3350 KMP_ATOMIC_DEC(unfinished_threads);
3351 KA_TRACE(20, (
"__kmp_execute_tasks_template: T#%d dec "
3352 "unfinished_threads to %d task_team=%p\n",
3353 gtid, count, task_team));
3354 *thread_finished = TRUE;
3362 if (flag != NULL && flag->done_check()) {
3365 (
"__kmp_execute_tasks_template: T#%d spin condition satisfied\n",
3373 if (thread->th.th_task_team == NULL) {
3375 (
"__kmp_execute_tasks_template: T#%d no more tasks\n", gtid));
3384 if (flag == NULL || (!final_spin && flag->done_check())) {
3386 (
"__kmp_execute_tasks_template: T#%d spin condition satisfied\n",
3393 if (nthreads == 1 &&
3394 KMP_ATOMIC_LD_ACQ(¤t_task->td_incomplete_child_tasks))
3398 (
"__kmp_execute_tasks_template: T#%d can't find work\n", gtid));
3404template <
bool C,
bool S>
3405int __kmp_execute_tasks_32(
3406 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_32<C, S> *flag,
int final_spin,
3407 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3408 kmp_int32 is_constrained) {
3409 return __kmp_execute_tasks_template(
3410 thread, gtid, flag, final_spin,
3411 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3414template <
bool C,
bool S>
3415int __kmp_execute_tasks_64(
3416 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_64<C, S> *flag,
int final_spin,
3417 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3418 kmp_int32 is_constrained) {
3419 return __kmp_execute_tasks_template(
3420 thread, gtid, flag, final_spin,
3421 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3424template <
bool C,
bool S>
3425int __kmp_atomic_execute_tasks_64(
3426 kmp_info_t *thread, kmp_int32 gtid, kmp_atomic_flag_64<C, S> *flag,
3427 int final_spin,
int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3428 kmp_int32 is_constrained) {
3429 return __kmp_execute_tasks_template(
3430 thread, gtid, flag, final_spin,
3431 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3434int __kmp_execute_tasks_oncore(
3435 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_oncore *flag,
int final_spin,
3436 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3437 kmp_int32 is_constrained) {
3438 return __kmp_execute_tasks_template(
3439 thread, gtid, flag, final_spin,
3440 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3444__kmp_execute_tasks_32<false, false>(kmp_info_t *, kmp_int32,
3445 kmp_flag_32<false, false> *,
int,
3446 int *USE_ITT_BUILD_ARG(
void *), kmp_int32);
3448template int __kmp_execute_tasks_64<false, true>(kmp_info_t *, kmp_int32,
3449 kmp_flag_64<false, true> *,
3451 int *USE_ITT_BUILD_ARG(
void *),
3454template int __kmp_execute_tasks_64<true, false>(kmp_info_t *, kmp_int32,
3455 kmp_flag_64<true, false> *,
3457 int *USE_ITT_BUILD_ARG(
void *),
3460template int __kmp_atomic_execute_tasks_64<false, true>(
3461 kmp_info_t *, kmp_int32, kmp_atomic_flag_64<false, true> *,
int,
3462 int *USE_ITT_BUILD_ARG(
void *), kmp_int32);
3464template int __kmp_atomic_execute_tasks_64<true, false>(
3465 kmp_info_t *, kmp_int32, kmp_atomic_flag_64<true, false> *,
int,
3466 int *USE_ITT_BUILD_ARG(
void *), kmp_int32);
3471static void __kmp_enable_tasking(kmp_task_team_t *task_team,
3472 kmp_info_t *this_thr) {
3473 kmp_thread_data_t *threads_data;
3474 int nthreads, i, is_init_thread;
3476 KA_TRACE(10, (
"__kmp_enable_tasking(enter): T#%d\n",
3477 __kmp_gtid_from_thread(this_thr)));
3479 KMP_DEBUG_ASSERT(task_team != NULL);
3480 KMP_DEBUG_ASSERT(this_thr->th.th_team != NULL);
3482 nthreads = task_team->tt.tt_nproc;
3483 KMP_DEBUG_ASSERT(nthreads > 0);
3484 KMP_DEBUG_ASSERT(nthreads == this_thr->th.th_team->t.t_nproc);
3487 is_init_thread = __kmp_realloc_task_threads_data(this_thr, task_team);
3489 if (!is_init_thread) {
3493 (
"__kmp_enable_tasking(exit): T#%d: threads array already set up.\n",
3494 __kmp_gtid_from_thread(this_thr)));
3497 threads_data = (kmp_thread_data_t *)TCR_PTR(task_team->tt.tt_threads_data);
3498 KMP_DEBUG_ASSERT(threads_data != NULL);
3500 if (__kmp_tasking_mode == tskm_task_teams &&
3501 (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME)) {
3505 for (i = 0; i < nthreads; i++) {
3507 kmp_info_t *thread = threads_data[i].td.td_thr;
3509 if (i == this_thr->th.th_info.ds.ds_tid) {
3518 if ((sleep_loc = TCR_PTR(CCAST(
void *, thread->th.th_sleep_loc))) !=
3520 KF_TRACE(50, (
"__kmp_enable_tasking: T#%d waking up thread T#%d\n",
3521 __kmp_gtid_from_thread(this_thr),
3522 __kmp_gtid_from_thread(thread)));
3523 __kmp_null_resume_wrapper(thread);
3525 KF_TRACE(50, (
"__kmp_enable_tasking: T#%d don't wake up thread T#%d\n",
3526 __kmp_gtid_from_thread(this_thr),
3527 __kmp_gtid_from_thread(thread)));
3532 KA_TRACE(10, (
"__kmp_enable_tasking(exit): T#%d\n",
3533 __kmp_gtid_from_thread(this_thr)));
3566static kmp_task_team_t *__kmp_free_task_teams =
3569kmp_bootstrap_lock_t __kmp_task_team_lock =
3570 KMP_BOOTSTRAP_LOCK_INITIALIZER(__kmp_task_team_lock);
3577static void __kmp_alloc_task_deque(kmp_info_t *thread,
3578 kmp_thread_data_t *thread_data) {
3579 __kmp_init_bootstrap_lock(&thread_data->td.td_deque_lock);
3580 KMP_DEBUG_ASSERT(thread_data->td.td_deque == NULL);
3583 thread_data->td.td_deque_last_stolen = -1;
3585 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) == 0);
3586 KMP_DEBUG_ASSERT(thread_data->td.td_deque_head == 0);
3587 KMP_DEBUG_ASSERT(thread_data->td.td_deque_tail == 0);
3591 (
"__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n",
3592 __kmp_gtid_from_thread(thread), INITIAL_TASK_DEQUE_SIZE, thread_data));
3596 thread_data->td.td_deque = (kmp_taskdata_t **)__kmp_allocate(
3597 INITIAL_TASK_DEQUE_SIZE *
sizeof(kmp_taskdata_t *));
3598 thread_data->td.td_deque_size = INITIAL_TASK_DEQUE_SIZE;
3604static void __kmp_free_task_deque(kmp_thread_data_t *thread_data) {
3605 if (thread_data->td.td_deque != NULL) {
3606 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
3607 TCW_4(thread_data->td.td_deque_ntasks, 0);
3608 __kmp_free(thread_data->td.td_deque);
3609 thread_data->td.td_deque = NULL;
3610 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
3621static int __kmp_realloc_task_threads_data(kmp_info_t *thread,
3622 kmp_task_team_t *task_team) {
3623 kmp_thread_data_t **threads_data_p;
3624 kmp_int32 nthreads, maxthreads;
3625 int is_init_thread = FALSE;
3627 if (TCR_4(task_team->tt.tt_found_tasks)) {
3632 threads_data_p = &task_team->tt.tt_threads_data;
3633 nthreads = task_team->tt.tt_nproc;
3634 maxthreads = task_team->tt.tt_max_threads;
3639 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_threads_lock);
3641 if (!TCR_4(task_team->tt.tt_found_tasks)) {
3643 kmp_team_t *team = thread->th.th_team;
3646 is_init_thread = TRUE;
3647 if (maxthreads < nthreads) {
3649 if (*threads_data_p != NULL) {
3650 kmp_thread_data_t *old_data = *threads_data_p;
3651 kmp_thread_data_t *new_data = NULL;
3655 (
"__kmp_realloc_task_threads_data: T#%d reallocating "
3656 "threads data for task_team %p, new_size = %d, old_size = %d\n",
3657 __kmp_gtid_from_thread(thread), task_team, nthreads, maxthreads));
3662 new_data = (kmp_thread_data_t *)__kmp_allocate(
3663 nthreads *
sizeof(kmp_thread_data_t));
3665 KMP_MEMCPY_S((
void *)new_data, nthreads *
sizeof(kmp_thread_data_t),
3666 (
void *)old_data, maxthreads *
sizeof(kmp_thread_data_t));
3669 (*threads_data_p) = new_data;
3670 __kmp_free(old_data);
3672 KE_TRACE(10, (
"__kmp_realloc_task_threads_data: T#%d allocating "
3673 "threads data for task_team %p, size = %d\n",
3674 __kmp_gtid_from_thread(thread), task_team, nthreads));
3678 *threads_data_p = (kmp_thread_data_t *)__kmp_allocate(
3679 nthreads *
sizeof(kmp_thread_data_t));
3681 task_team->tt.tt_max_threads = nthreads;
3684 KMP_DEBUG_ASSERT(*threads_data_p != NULL);
3688 for (i = 0; i < nthreads; i++) {
3689 kmp_thread_data_t *thread_data = &(*threads_data_p)[i];
3690 thread_data->td.td_thr = team->t.t_threads[i];
3692 if (thread_data->td.td_deque_last_stolen >= nthreads) {
3696 thread_data->td.td_deque_last_stolen = -1;
3701 TCW_SYNC_4(task_team->tt.tt_found_tasks, TRUE);
3704 __kmp_release_bootstrap_lock(&task_team->tt.tt_threads_lock);
3705 return is_init_thread;
3711static void __kmp_free_task_threads_data(kmp_task_team_t *task_team) {
3712 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_threads_lock);
3713 if (task_team->tt.tt_threads_data != NULL) {
3715 for (i = 0; i < task_team->tt.tt_max_threads; i++) {
3716 __kmp_free_task_deque(&task_team->tt.tt_threads_data[i]);
3718 __kmp_free(task_team->tt.tt_threads_data);
3719 task_team->tt.tt_threads_data = NULL;
3721 __kmp_release_bootstrap_lock(&task_team->tt.tt_threads_lock);
3727static void __kmp_free_task_pri_list(kmp_task_team_t *task_team) {
3728 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
3729 if (task_team->tt.tt_task_pri_list != NULL) {
3730 kmp_task_pri_t *list = task_team->tt.tt_task_pri_list;
3731 while (list != NULL) {
3732 kmp_task_pri_t *next = list->next;
3733 __kmp_free_task_deque(&list->td);
3737 task_team->tt.tt_task_pri_list = NULL;
3739 __kmp_release_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
3742static inline void __kmp_task_team_init(kmp_task_team_t *task_team,
3744 int team_nth = team->t.t_nproc;
3746 if (!task_team->tt.tt_active || team_nth != task_team->tt.tt_nproc) {
3747 TCW_4(task_team->tt.tt_found_tasks, FALSE);
3748 TCW_4(task_team->tt.tt_found_proxy_tasks, FALSE);
3749 TCW_4(task_team->tt.tt_hidden_helper_task_encountered, FALSE);
3750 TCW_4(task_team->tt.tt_nproc, team_nth);
3751 KMP_ATOMIC_ST_REL(&task_team->tt.tt_unfinished_threads, team_nth);
3752 TCW_4(task_team->tt.tt_active, TRUE);
3760static kmp_task_team_t *__kmp_allocate_task_team(kmp_info_t *thread,
3762 kmp_task_team_t *task_team = NULL;
3764 KA_TRACE(20, (
"__kmp_allocate_task_team: T#%d entering; team = %p\n",
3765 (thread ? __kmp_gtid_from_thread(thread) : -1), team));
3767 if (TCR_PTR(__kmp_free_task_teams) != NULL) {
3769 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3770 if (__kmp_free_task_teams != NULL) {
3771 task_team = __kmp_free_task_teams;
3772 TCW_PTR(__kmp_free_task_teams, task_team->tt.tt_next);
3773 task_team->tt.tt_next = NULL;
3775 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3778 if (task_team == NULL) {
3779 KE_TRACE(10, (
"__kmp_allocate_task_team: T#%d allocating "
3780 "task team for team %p\n",
3781 __kmp_gtid_from_thread(thread), team));
3784 task_team = (kmp_task_team_t *)__kmp_allocate(
sizeof(kmp_task_team_t));
3785 __kmp_init_bootstrap_lock(&task_team->tt.tt_threads_lock);
3786 __kmp_init_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
3787#if USE_ITT_BUILD && USE_ITT_NOTIFY && KMP_DEBUG
3790 __itt_suppress_mark_range(
3791 __itt_suppress_range, __itt_suppress_threading_errors,
3792 &task_team->tt.tt_found_tasks,
sizeof(task_team->tt.tt_found_tasks));
3793 __itt_suppress_mark_range(__itt_suppress_range,
3794 __itt_suppress_threading_errors,
3795 CCAST(kmp_uint32 *, &task_team->tt.tt_active),
3796 sizeof(task_team->tt.tt_active));
3804 __kmp_task_team_init(task_team, team);
3806 KA_TRACE(20, (
"__kmp_allocate_task_team: T#%d exiting; task_team = %p "
3807 "unfinished_threads init'd to %d\n",
3808 (thread ? __kmp_gtid_from_thread(thread) : -1), task_team,
3809 KMP_ATOMIC_LD_RLX(&task_team->tt.tt_unfinished_threads)));
3816void __kmp_free_task_team(kmp_info_t *thread, kmp_task_team_t *task_team) {
3817 KA_TRACE(20, (
"__kmp_free_task_team: T#%d task_team = %p\n",
3818 thread ? __kmp_gtid_from_thread(thread) : -1, task_team));
3821 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3823 KMP_DEBUG_ASSERT(task_team->tt.tt_next == NULL);
3824 task_team->tt.tt_next = __kmp_free_task_teams;
3825 TCW_PTR(__kmp_free_task_teams, task_team);
3827 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3835void __kmp_reap_task_teams(
void) {
3836 kmp_task_team_t *task_team;
3838 if (TCR_PTR(__kmp_free_task_teams) != NULL) {
3840 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3841 while ((task_team = __kmp_free_task_teams) != NULL) {
3842 __kmp_free_task_teams = task_team->tt.tt_next;
3843 task_team->tt.tt_next = NULL;
3846 if (task_team->tt.tt_threads_data != NULL) {
3847 __kmp_free_task_threads_data(task_team);
3849 if (task_team->tt.tt_task_pri_list != NULL) {
3850 __kmp_free_task_pri_list(task_team);
3852 __kmp_free(task_team);
3854 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3862void __kmp_push_task_team_node(kmp_info_t *thread, kmp_team_t *team) {
3863 KMP_DEBUG_ASSERT(team->t.t_nproc == 1);
3864 kmp_task_team_list_t *current =
3865 (kmp_task_team_list_t *)(&team->t.t_task_team[0]);
3866 kmp_task_team_list_t *node =
3867 (kmp_task_team_list_t *)__kmp_allocate(
sizeof(kmp_task_team_list_t));
3868 node->task_team = current->task_team;
3869 node->next = current->next;
3870 thread->th.th_task_team = current->task_team = NULL;
3871 current->next = node;
3875void __kmp_pop_task_team_node(kmp_info_t *thread, kmp_team_t *team) {
3876 KMP_DEBUG_ASSERT(team->t.t_nproc == 1);
3877 kmp_task_team_list_t *current =
3878 (kmp_task_team_list_t *)(&team->t.t_task_team[0]);
3879 if (current->task_team) {
3880 __kmp_free_task_team(thread, current->task_team);
3882 kmp_task_team_list_t *next = current->next;
3884 current->task_team = next->task_team;
3885 current->next = next->next;
3886 KMP_DEBUG_ASSERT(next != current);
3888 thread->th.th_task_team = current->task_team;
3895void __kmp_wait_to_unref_task_teams(
void) {
3901 KMP_INIT_YIELD(spins);
3902 KMP_INIT_BACKOFF(time);
3910 for (thread = CCAST(kmp_info_t *, __kmp_thread_pool); thread != NULL;
3911 thread = thread->th.th_next_pool) {
3915 if (TCR_PTR(thread->th.th_task_team) == NULL) {
3916 KA_TRACE(10, (
"__kmp_wait_to_unref_task_team: T#%d task_team == NULL\n",
3917 __kmp_gtid_from_thread(thread)));
3922 if (!__kmp_is_thread_alive(thread, &exit_val)) {
3923 thread->th.th_task_team = NULL;
3930 KA_TRACE(10, (
"__kmp_wait_to_unref_task_team: Waiting for T#%d to "
3931 "unreference task_team\n",
3932 __kmp_gtid_from_thread(thread)));
3934 if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME) {
3937 if ((sleep_loc = TCR_PTR(CCAST(
void *, thread->th.th_sleep_loc))) !=
3941 (
"__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n",
3942 __kmp_gtid_from_thread(thread), __kmp_gtid_from_thread(thread)));
3943 __kmp_null_resume_wrapper(thread);
3952 KMP_YIELD_OVERSUB_ELSE_SPIN(spins, time);
3958void __kmp_task_team_setup(kmp_info_t *this_thr, kmp_team_t *team) {
3959 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3964 if (team == this_thr->th.th_serial_team ||
3965 team == this_thr->th.th_root->r.r_root_team) {
3966 KMP_DEBUG_ASSERT(team->t.t_nproc == 1);
3967 if (team->t.t_task_team[0] == NULL) {
3968 team->t.t_task_team[0] = __kmp_allocate_task_team(this_thr, team);
3970 20, (
"__kmp_task_team_setup: Primary T#%d created new task_team %p"
3971 " for serial/root team %p\n",
3972 __kmp_gtid_from_thread(this_thr), team->t.t_task_team[0], team));
3975 __kmp_task_team_init(team->t.t_task_team[0], team);
3983 if (team->t.t_task_team[this_thr->th.th_task_state] == NULL) {
3984 team->t.t_task_team[this_thr->th.th_task_state] =
3985 __kmp_allocate_task_team(this_thr, team);
3986 KA_TRACE(20, (
"__kmp_task_team_setup: Primary T#%d created new task_team %p"
3987 " for team %d at parity=%d\n",
3988 __kmp_gtid_from_thread(this_thr),
3989 team->t.t_task_team[this_thr->th.th_task_state], team->t.t_id,
3990 this_thr->th.th_task_state));
3999 int other_team = 1 - this_thr->th.th_task_state;
4000 KMP_DEBUG_ASSERT(other_team >= 0 && other_team < 2);
4001 if (team->t.t_task_team[other_team] == NULL) {
4002 team->t.t_task_team[other_team] = __kmp_allocate_task_team(this_thr, team);
4003 KA_TRACE(20, (
"__kmp_task_team_setup: Primary T#%d created second new "
4004 "task_team %p for team %d at parity=%d\n",
4005 __kmp_gtid_from_thread(this_thr),
4006 team->t.t_task_team[other_team], team->t.t_id, other_team));
4009 kmp_task_team_t *task_team = team->t.t_task_team[other_team];
4010 __kmp_task_team_init(task_team, team);
4013 KA_TRACE(20, (
"__kmp_task_team_setup: Primary T#%d reset next task_team "
4014 "%p for team %d at parity=%d\n",
4015 __kmp_gtid_from_thread(this_thr),
4016 team->t.t_task_team[other_team], team->t.t_id, other_team));
4023 if (this_thr == __kmp_hidden_helper_main_thread) {
4024 for (
int i = 0; i < 2; ++i) {
4025 kmp_task_team_t *task_team = team->t.t_task_team[i];
4026 if (KMP_TASKING_ENABLED(task_team)) {
4029 __kmp_enable_tasking(task_team, this_thr);
4030 for (
int j = 0; j < task_team->tt.tt_nproc; ++j) {
4031 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[j];
4032 if (thread_data->td.td_deque == NULL) {
4033 __kmp_alloc_task_deque(__kmp_hidden_helper_threads[j], thread_data);
4043void __kmp_task_team_sync(kmp_info_t *this_thr, kmp_team_t *team) {
4044 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
4045 KMP_DEBUG_ASSERT(team != this_thr->th.th_serial_team);
4046 KMP_DEBUG_ASSERT(team != this_thr->th.th_root->r.r_root_team);
4050 this_thr->th.th_task_state = (kmp_uint8)(1 - this_thr->th.th_task_state);
4054 TCW_PTR(this_thr->th.th_task_team,
4055 team->t.t_task_team[this_thr->th.th_task_state]);
4057 (
"__kmp_task_team_sync: Thread T#%d task team switched to task_team "
4058 "%p from Team #%d (parity=%d)\n",
4059 __kmp_gtid_from_thread(this_thr), this_thr->th.th_task_team,
4060 team->t.t_id, this_thr->th.th_task_state));
4069void __kmp_task_team_wait(
4070 kmp_info_t *this_thr,
4071 kmp_team_t *team USE_ITT_BUILD_ARG(
void *itt_sync_obj),
int wait) {
4072 kmp_task_team_t *task_team = team->t.t_task_team[this_thr->th.th_task_state];
4074 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
4075 KMP_DEBUG_ASSERT(task_team == this_thr->th.th_task_team);
4077 if ((task_team != NULL) && KMP_TASKING_ENABLED(task_team)) {
4079 KA_TRACE(20, (
"__kmp_task_team_wait: Primary T#%d waiting for all tasks "
4080 "(for unfinished_threads to reach 0) on task_team = %p\n",
4081 __kmp_gtid_from_thread(this_thr), task_team));
4085 kmp_flag_32<false, false> flag(
4086 RCAST(std::atomic<kmp_uint32> *,
4087 &task_team->tt.tt_unfinished_threads),
4089 flag.wait(this_thr, TRUE USE_ITT_BUILD_ARG(itt_sync_obj));
4095 (
"__kmp_task_team_wait: Primary T#%d deactivating task_team %p: "
4096 "setting active to false, setting local and team's pointer to NULL\n",
4097 __kmp_gtid_from_thread(this_thr), task_team));
4098 TCW_SYNC_4(task_team->tt.tt_found_proxy_tasks, FALSE);
4099 TCW_SYNC_4(task_team->tt.tt_hidden_helper_task_encountered, FALSE);
4100 KMP_CHECK_UPDATE(task_team->tt.tt_untied_task_encountered, 0);
4101 TCW_SYNC_4(task_team->tt.tt_active, FALSE);
4104 TCW_PTR(this_thr->th.th_task_team, NULL);
4113void __kmp_tasking_barrier(kmp_team_t *team, kmp_info_t *thread,
int gtid) {
4114 std::atomic<kmp_uint32> *spin = RCAST(
4115 std::atomic<kmp_uint32> *,
4116 &team->t.t_task_team[thread->th.th_task_state]->tt.tt_unfinished_threads);
4118 KMP_DEBUG_ASSERT(__kmp_tasking_mode == tskm_extra_barrier);
4121 KMP_FSYNC_SPIN_INIT(spin, NULL);
4123 kmp_flag_32<false, false> spin_flag(spin, 0U);
4124 while (!spin_flag.execute_tasks(thread, gtid, TRUE,
4125 &flag USE_ITT_BUILD_ARG(NULL), 0)) {
4128 KMP_FSYNC_SPIN_PREPARE(RCAST(
void *, spin));
4131 if (TCR_4(__kmp_global.g.g_done)) {
4132 if (__kmp_global.g.g_abort)
4133 __kmp_abort_thread();
4139 KMP_FSYNC_SPIN_ACQUIRED(RCAST(
void *, spin));
4148static bool __kmp_give_task(kmp_info_t *thread, kmp_int32 tid, kmp_task_t *task,
4150 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4151 kmp_task_team_t *task_team = taskdata->td_task_team;
4153 KA_TRACE(20, (
"__kmp_give_task: trying to give task %p to thread %d.\n",
4157 KMP_DEBUG_ASSERT(task_team != NULL);
4159 bool result =
false;
4160 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[tid];
4162 if (thread_data->td.td_deque == NULL) {
4166 (
"__kmp_give_task: thread %d has no queue while giving task %p.\n",
4171 if (TCR_4(thread_data->td.td_deque_ntasks) >=
4172 TASK_DEQUE_SIZE(thread_data->td)) {
4175 (
"__kmp_give_task: queue is full while giving task %p to thread %d.\n",
4180 if (TASK_DEQUE_SIZE(thread_data->td) / INITIAL_TASK_DEQUE_SIZE >= pass)
4183 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
4184 if (TCR_4(thread_data->td.td_deque_ntasks) >=
4185 TASK_DEQUE_SIZE(thread_data->td)) {
4187 __kmp_realloc_task_deque(thread, thread_data);
4192 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
4194 if (TCR_4(thread_data->td.td_deque_ntasks) >=
4195 TASK_DEQUE_SIZE(thread_data->td)) {
4196 KA_TRACE(30, (
"__kmp_give_task: queue is full while giving task %p to "
4202 if (TASK_DEQUE_SIZE(thread_data->td) / INITIAL_TASK_DEQUE_SIZE >= pass)
4203 goto release_and_exit;
4205 __kmp_realloc_task_deque(thread, thread_data);
4211 thread_data->td.td_deque[thread_data->td.td_deque_tail] = taskdata;
4213 thread_data->td.td_deque_tail =
4214 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td);
4215 TCW_4(thread_data->td.td_deque_ntasks,
4216 TCR_4(thread_data->td.td_deque_ntasks) + 1);
4219 KA_TRACE(30, (
"__kmp_give_task: successfully gave task %p to thread %d.\n",
4223 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
4228#define PROXY_TASK_FLAG 0x40000000
4245static void __kmp_first_top_half_finish_proxy(kmp_taskdata_t *taskdata) {
4246 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
4247 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4248 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
4249 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
4251 taskdata->td_flags.complete = 1;
4252#if OMP_TASKGRAPH_EXPERIMENTAL
4253 taskdata->td_flags.onced = 1;
4256 if (taskdata->td_taskgroup)
4257 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
4261 KMP_ATOMIC_OR(&taskdata->td_incomplete_child_tasks, PROXY_TASK_FLAG);
4264static void __kmp_second_top_half_finish_proxy(kmp_taskdata_t *taskdata) {
4266 kmp_int32 children = 0;
4270 KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks);
4271 KMP_DEBUG_ASSERT(children >= 0);
4274 KMP_ATOMIC_AND(&taskdata->td_incomplete_child_tasks, ~PROXY_TASK_FLAG);
4277static void __kmp_bottom_half_finish_proxy(kmp_int32 gtid, kmp_task_t *ptask) {
4278 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4279 kmp_info_t *thread = __kmp_threads[gtid];
4281 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4282 KMP_DEBUG_ASSERT(taskdata->td_flags.complete ==
4287 while ((KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks) &
4288 PROXY_TASK_FLAG) > 0)
4291 __kmp_release_deps(gtid, taskdata);
4292 __kmp_free_task_and_ancestors(gtid, taskdata, thread);
4304 KMP_DEBUG_ASSERT(ptask != NULL);
4305 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4307 10, (
"__kmp_proxy_task_completed(enter): T#%d proxy task %p completing\n",
4309 __kmp_assert_valid_gtid(gtid);
4310 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4312 __kmp_first_top_half_finish_proxy(taskdata);
4313 __kmp_second_top_half_finish_proxy(taskdata);
4314 __kmp_bottom_half_finish_proxy(gtid, ptask);
4317 (
"__kmp_proxy_task_completed(exit): T#%d proxy task %p completing\n",
4321void __kmpc_give_task(kmp_task_t *ptask, kmp_int32 start = 0) {
4322 KMP_DEBUG_ASSERT(ptask != NULL);
4323 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4327 kmp_team_t *team = taskdata->td_team;
4328 kmp_int32 nthreads = team->t.t_nproc;
4333 kmp_int32 start_k = start % nthreads;
4335 kmp_int32 k = start_k;
4339 thread = team->t.t_threads[k];
4340 k = (k + 1) % nthreads;
4346 }
while (!__kmp_give_task(thread, k, ptask, pass));
4348 if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME && __kmp_wpolicy_passive) {
4350 for (
int i = 0; i < nthreads; ++i) {
4351 thread = team->t.t_threads[i];
4352 if (thread->th.th_sleep_loc != NULL) {
4353 __kmp_null_resume_wrapper(thread);
4368 KMP_DEBUG_ASSERT(ptask != NULL);
4369 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4373 (
"__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n",
4376 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4378 __kmp_first_top_half_finish_proxy(taskdata);
4380 __kmpc_give_task(ptask);
4382 __kmp_second_top_half_finish_proxy(taskdata);
4386 (
"__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n",
4390kmp_event_t *__kmpc_task_allow_completion_event(
ident_t *loc_ref,
int gtid,
4392 kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(task);
4393 if (td->td_allow_completion_event.type == KMP_EVENT_UNINITIALIZED) {
4394 td->td_allow_completion_event.type = KMP_EVENT_ALLOW_COMPLETION;
4395 td->td_allow_completion_event.ed.task = task;
4396 __kmp_init_tas_lock(&td->td_allow_completion_event.lock);
4398 return &td->td_allow_completion_event;
4401void __kmp_fulfill_event(kmp_event_t *event) {
4402 if (event->type == KMP_EVENT_ALLOW_COMPLETION) {
4403 kmp_task_t *ptask = event->ed.task;
4404 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4405 bool detached =
false;
4406 int gtid = __kmp_get_gtid();
4411 __kmp_acquire_tas_lock(&event->lock, gtid);
4412 if (taskdata->td_flags.proxy == TASK_PROXY) {
4418 if (UNLIKELY(ompt_enabled.enabled))
4419 __ompt_task_finish(ptask, NULL, ompt_task_early_fulfill);
4422 event->type = KMP_EVENT_UNINITIALIZED;
4423 __kmp_release_tas_lock(&event->lock, gtid);
4429 if (UNLIKELY(ompt_enabled.enabled))
4430 __ompt_task_finish(ptask, NULL, ompt_task_late_fulfill);
4434 kmp_team_t *team = taskdata->td_team;
4435 kmp_info_t *thread = __kmp_get_thread();
4436 if (thread->th.th_team == team) {
4456kmp_task_t *__kmp_task_dup_alloc(kmp_info_t *thread, kmp_task_t *task_src
4457#
if OMP_TASKGRAPH_EXPERIMENTAL
4463 kmp_taskdata_t *taskdata;
4464 kmp_taskdata_t *taskdata_src = KMP_TASK_TO_TASKDATA(task_src);
4465 kmp_taskdata_t *parent_task = taskdata_src->td_parent;
4466 size_t shareds_offset;
4469 KA_TRACE(10, (
"__kmp_task_dup_alloc(enter): Th %p, source task %p\n", thread,
4471 KMP_DEBUG_ASSERT(taskdata_src->td_flags.proxy ==
4473 KMP_DEBUG_ASSERT(taskdata_src->td_flags.tasktype == TASK_EXPLICIT);
4474 task_size = taskdata_src->td_size_alloc;
4477 KA_TRACE(30, (
"__kmp_task_dup_alloc: Th %p, malloc size %ld\n", thread,
4480 taskdata = (kmp_taskdata_t *)__kmp_fast_allocate(thread, task_size);
4482 taskdata = (kmp_taskdata_t *)__kmp_thread_malloc(thread, task_size);
4484 KMP_MEMCPY(taskdata, taskdata_src, task_size);
4486 task = KMP_TASKDATA_TO_TASK(taskdata);
4489#if OMP_TASKGRAPH_EXPERIMENTAL
4490 if (taskdata->is_taskgraph && !taskloop_recur &&
4491 __kmp_tdg_is_recording(taskdata_src->tdg->tdg_status))
4492 taskdata->td_tdg_task_id = KMP_ATOMIC_INC(&__kmp_tdg_task_id);
4494 taskdata->td_task_id = KMP_GEN_TASK_ID();
4495 if (task->shareds != NULL) {
4496 shareds_offset = (
char *)task_src->shareds - (
char *)taskdata_src;
4497 task->shareds = &((
char *)taskdata)[shareds_offset];
4498 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task->shareds) & (
sizeof(
void *) - 1)) ==
4501 taskdata->td_alloc_thread = thread;
4502 taskdata->td_parent = parent_task;
4504 taskdata->td_taskgroup = parent_task->td_taskgroup;
4507 if (taskdata->td_flags.tiedness == TASK_TIED)
4508 taskdata->td_last_tied = taskdata;
4512 if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
4513 KMP_ATOMIC_INC(&parent_task->td_incomplete_child_tasks);
4514 if (parent_task->td_taskgroup)
4515 KMP_ATOMIC_INC(&parent_task->td_taskgroup->count);
4518 if (taskdata->td_parent->td_flags.tasktype == TASK_EXPLICIT)
4519 KMP_ATOMIC_INC(&taskdata->td_parent->td_allocated_child_tasks);
4523 (
"__kmp_task_dup_alloc(exit): Th %p, created task %p, parent=%p\n",
4524 thread, taskdata, taskdata->td_parent));
4526 if (UNLIKELY(ompt_enabled.enabled))
4527 __ompt_task_init(taskdata, thread->th.th_info.ds.ds_gtid);
4536typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32);
4538KMP_BUILD_ASSERT(
sizeof(
long) == 4 ||
sizeof(
long) == 8);
4543class kmp_taskloop_bounds_t {
4545 const kmp_taskdata_t *taskdata;
4546 size_t lower_offset;
4547 size_t upper_offset;
4550 kmp_taskloop_bounds_t(kmp_task_t *_task, kmp_uint64 *lb, kmp_uint64 *ub)
4551 : task(_task), taskdata(KMP_TASK_TO_TASKDATA(task)),
4552 lower_offset((char *)lb - (char *)task),
4553 upper_offset((char *)ub - (char *)task) {
4554 KMP_DEBUG_ASSERT((
char *)lb > (
char *)_task);
4555 KMP_DEBUG_ASSERT((
char *)ub > (
char *)_task);
4557 kmp_taskloop_bounds_t(kmp_task_t *_task,
const kmp_taskloop_bounds_t &bounds)
4558 : task(_task), taskdata(KMP_TASK_TO_TASKDATA(_task)),
4559 lower_offset(bounds.lower_offset), upper_offset(bounds.upper_offset) {}
4560 size_t get_lower_offset()
const {
return lower_offset; }
4561 size_t get_upper_offset()
const {
return upper_offset; }
4562 kmp_uint64 get_lb()
const {
4564#if defined(KMP_GOMP_COMPAT)
4566 if (!taskdata->td_flags.native) {
4567 retval = *(kmp_int64 *)((
char *)task + lower_offset);
4570 if (taskdata->td_size_loop_bounds == 4) {
4571 kmp_int32 *lb = RCAST(kmp_int32 *, task->shareds);
4572 retval = (kmp_int64)*lb;
4574 kmp_int64 *lb = RCAST(kmp_int64 *, task->shareds);
4575 retval = (kmp_int64)*lb;
4580 retval = *(kmp_int64 *)((
char *)task + lower_offset);
4584 kmp_uint64 get_ub()
const {
4586#if defined(KMP_GOMP_COMPAT)
4588 if (!taskdata->td_flags.native) {
4589 retval = *(kmp_int64 *)((
char *)task + upper_offset);
4592 if (taskdata->td_size_loop_bounds == 4) {
4593 kmp_int32 *ub = RCAST(kmp_int32 *, task->shareds) + 1;
4594 retval = (kmp_int64)*ub;
4596 kmp_int64 *ub = RCAST(kmp_int64 *, task->shareds) + 1;
4597 retval = (kmp_int64)*ub;
4601 retval = *(kmp_int64 *)((
char *)task + upper_offset);
4605 void set_lb(kmp_uint64 lb) {
4606#if defined(KMP_GOMP_COMPAT)
4608 if (!taskdata->td_flags.native) {
4609 *(kmp_uint64 *)((
char *)task + lower_offset) = lb;
4612 if (taskdata->td_size_loop_bounds == 4) {
4613 kmp_uint32 *lower = RCAST(kmp_uint32 *, task->shareds);
4614 *lower = (kmp_uint32)lb;
4616 kmp_uint64 *lower = RCAST(kmp_uint64 *, task->shareds);
4617 *lower = (kmp_uint64)lb;
4621 *(kmp_uint64 *)((
char *)task + lower_offset) = lb;
4624 void set_ub(kmp_uint64 ub) {
4625#if defined(KMP_GOMP_COMPAT)
4627 if (!taskdata->td_flags.native) {
4628 *(kmp_uint64 *)((
char *)task + upper_offset) = ub;
4631 if (taskdata->td_size_loop_bounds == 4) {
4632 kmp_uint32 *upper = RCAST(kmp_uint32 *, task->shareds) + 1;
4633 *upper = (kmp_uint32)ub;
4635 kmp_uint64 *upper = RCAST(kmp_uint64 *, task->shareds) + 1;
4636 *upper = (kmp_uint64)ub;
4640 *(kmp_uint64 *)((
char *)task + upper_offset) = ub;
4661void __kmp_taskloop_linear(
ident_t *loc,
int gtid, kmp_task_t *task,
4662 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
4663 kmp_uint64 ub_glob, kmp_uint64 num_tasks,
4664 kmp_uint64 grainsize, kmp_uint64 extras,
4665 kmp_int64 last_chunk, kmp_uint64 tc,
4671 KMP_TIME_PARTITIONED_BLOCK(OMP_taskloop_scheduling);
4672 p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
4674 kmp_taskloop_bounds_t task_bounds(task, lb, ub);
4675 kmp_uint64 lower = task_bounds.get_lb();
4676 kmp_uint64 upper = task_bounds.get_ub();
4678 kmp_info_t *thread = __kmp_threads[gtid];
4679 kmp_taskdata_t *current_task = thread->th.th_current_task;
4680 kmp_task_t *next_task;
4681 kmp_int32 lastpriv = 0;
4683 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize +
4684 (last_chunk < 0 ? last_chunk : extras));
4685 KMP_DEBUG_ASSERT(num_tasks > extras);
4686 KMP_DEBUG_ASSERT(num_tasks > 0);
4687 KA_TRACE(20, (
"__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "
4688 "extras %lld, last_chunk %lld, i=%lld,%lld(%d)%lld, dup %p\n",
4689 gtid, num_tasks, grainsize, extras, last_chunk, lower, upper,
4690 ub_glob, st, task_dup));
4693 for (i = 0; i < num_tasks; ++i) {
4694 kmp_uint64 chunk_minus_1;
4696 chunk_minus_1 = grainsize - 1;
4698 chunk_minus_1 = grainsize;
4701 upper = lower + st * chunk_minus_1;
4705 if (i == num_tasks - 1) {
4708 KMP_DEBUG_ASSERT(upper == *ub);
4709 if (upper == ub_glob)
4711 }
else if (st > 0) {
4712 KMP_DEBUG_ASSERT((kmp_uint64)st > *ub - upper);
4713 if ((kmp_uint64)st > ub_glob - upper)
4716 KMP_DEBUG_ASSERT(upper + st < *ub);
4717 if (upper - ub_glob < (kmp_uint64)(-st))
4722#if OMP_TASKGRAPH_EXPERIMENTAL
4723 next_task = __kmp_task_dup_alloc(thread, task, 0);
4725 next_task = __kmp_task_dup_alloc(thread, task);
4728 kmp_taskdata_t *next_taskdata = KMP_TASK_TO_TASKDATA(next_task);
4729 kmp_taskloop_bounds_t next_task_bounds =
4730 kmp_taskloop_bounds_t(next_task, task_bounds);
4733 next_task_bounds.set_lb(lower);
4734 if (next_taskdata->td_flags.native) {
4735 next_task_bounds.set_ub(upper + (st > 0 ? 1 : -1));
4737 next_task_bounds.set_ub(upper);
4739 if (ptask_dup != NULL)
4741 ptask_dup(next_task, task, lastpriv);
4743 (
"__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
4744 "upper %lld stride %lld, (offsets %p %p)\n",
4745 gtid, i, next_task, lower, upper, st,
4746 next_task_bounds.get_lower_offset(),
4747 next_task_bounds.get_upper_offset()));
4749 __kmp_omp_taskloop_task(NULL, gtid, next_task,
4752 if (ompt_enabled.ompt_callback_dispatch) {
4753 OMPT_GET_DISPATCH_CHUNK(next_taskdata->ompt_task_info.dispatch_chunk,
4758 __kmp_omp_task(gtid, next_task,
true);
4763 __kmp_task_start(gtid, task, current_task);
4765 __kmp_task_finish<false>(gtid, task, current_task);
4770typedef struct __taskloop_params {
4777 kmp_uint64 num_tasks;
4778 kmp_uint64 grainsize;
4780 kmp_int64 last_chunk;
4782 kmp_uint64 num_t_min;
4786} __taskloop_params_t;
4788void __kmp_taskloop_recur(
ident_t *,
int, kmp_task_t *, kmp_uint64 *,
4789 kmp_uint64 *, kmp_int64, kmp_uint64, kmp_uint64,
4790 kmp_uint64, kmp_uint64, kmp_int64, kmp_uint64,
4798int __kmp_taskloop_task(
int gtid,
void *ptask) {
4799 __taskloop_params_t *p =
4800 (__taskloop_params_t *)((kmp_task_t *)ptask)->shareds;
4801 kmp_task_t *task = p->task;
4802 kmp_uint64 *lb = p->lb;
4803 kmp_uint64 *ub = p->ub;
4804 void *task_dup = p->task_dup;
4806 kmp_int64 st = p->st;
4807 kmp_uint64 ub_glob = p->ub_glob;
4808 kmp_uint64 num_tasks = p->num_tasks;
4809 kmp_uint64 grainsize = p->grainsize;
4810 kmp_uint64 extras = p->extras;
4811 kmp_int64 last_chunk = p->last_chunk;
4812 kmp_uint64 tc = p->tc;
4813 kmp_uint64 num_t_min = p->num_t_min;
4815 void *codeptr_ra = p->codeptr_ra;
4818 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4819 KMP_DEBUG_ASSERT(task != NULL);
4821 (
"__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"
4822 " %lld, extras %lld, last_chunk %lld, i=%lld,%lld(%d), dup %p\n",
4823 gtid, taskdata, num_tasks, grainsize, extras, last_chunk, *lb, *ub,
4826 KMP_DEBUG_ASSERT(num_tasks * 2 + 1 > num_t_min);
4827 if (num_tasks > num_t_min)
4828 __kmp_taskloop_recur(NULL, gtid, task, lb, ub, st, ub_glob, num_tasks,
4829 grainsize, extras, last_chunk, tc, num_t_min,
4835 __kmp_taskloop_linear(NULL, gtid, task, lb, ub, st, ub_glob, num_tasks,
4836 grainsize, extras, last_chunk, tc,
4842 KA_TRACE(40, (
"__kmp_taskloop_task(exit): T#%d\n", gtid));
4864void __kmp_taskloop_recur(
ident_t *loc,
int gtid, kmp_task_t *task,
4865 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
4866 kmp_uint64 ub_glob, kmp_uint64 num_tasks,
4867 kmp_uint64 grainsize, kmp_uint64 extras,
4868 kmp_int64 last_chunk, kmp_uint64 tc,
4869 kmp_uint64 num_t_min,
4874 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4875 KMP_DEBUG_ASSERT(task != NULL);
4876 KMP_DEBUG_ASSERT(num_tasks > num_t_min);
4878 (
"__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"
4879 " %lld, extras %lld, last_chunk %lld, i=%lld,%lld(%d), dup %p\n",
4880 gtid, taskdata, num_tasks, grainsize, extras, last_chunk, *lb, *ub,
4882 p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
4883 kmp_uint64 lower = *lb;
4884 kmp_info_t *thread = __kmp_threads[gtid];
4886 kmp_task_t *next_task;
4887 size_t lower_offset =
4888 (
char *)lb - (
char *)task;
4889 size_t upper_offset =
4890 (
char *)ub - (
char *)task;
4892 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize +
4893 (last_chunk < 0 ? last_chunk : extras));
4894 KMP_DEBUG_ASSERT(num_tasks > extras);
4895 KMP_DEBUG_ASSERT(num_tasks > 0);
4898 kmp_uint64 lb1, ub0, tc0, tc1, ext0, ext1;
4899 kmp_int64 last_chunk0 = 0, last_chunk1 = 0;
4900 kmp_uint64 gr_size0 = grainsize;
4901 kmp_uint64 n_tsk0 = num_tasks >> 1;
4902 kmp_uint64 n_tsk1 = num_tasks - n_tsk0;
4903 if (last_chunk < 0) {
4905 last_chunk1 = last_chunk;
4906 tc0 = grainsize * n_tsk0;
4908 }
else if (n_tsk0 <= extras) {
4911 ext1 = extras - n_tsk0;
4912 tc0 = gr_size0 * n_tsk0;
4917 tc1 = grainsize * n_tsk1;
4920 ub0 = lower + st * (tc0 - 1);
4924#if OMP_TASKGRAPH_EXPERIMENTAL
4925 next_task = __kmp_task_dup_alloc(thread, task,
4928 next_task = __kmp_task_dup_alloc(thread, task);
4931 *(kmp_uint64 *)((
char *)next_task + lower_offset) = lb1;
4932 if (ptask_dup != NULL)
4933 ptask_dup(next_task, task, 0);
4938 kmp_taskdata_t *current_task = thread->th.th_current_task;
4939 thread->th.th_current_task = taskdata->td_parent;
4940 kmp_task_t *new_task =
4941 __kmpc_omp_task_alloc(loc, gtid, 1, 3 *
sizeof(
void *),
4942 sizeof(__taskloop_params_t), &__kmp_taskloop_task);
4944 thread->th.th_current_task = current_task;
4945 __taskloop_params_t *p = (__taskloop_params_t *)new_task->shareds;
4946 p->task = next_task;
4947 p->lb = (kmp_uint64 *)((
char *)next_task + lower_offset);
4948 p->ub = (kmp_uint64 *)((
char *)next_task + upper_offset);
4949 p->task_dup = task_dup;
4951 p->ub_glob = ub_glob;
4952 p->num_tasks = n_tsk1;
4953 p->grainsize = grainsize;
4955 p->last_chunk = last_chunk1;
4957 p->num_t_min = num_t_min;
4959 p->codeptr_ra = codeptr_ra;
4962#if OMP_TASKGRAPH_EXPERIMENTAL
4963 kmp_taskdata_t *new_task_data = KMP_TASK_TO_TASKDATA(new_task);
4964 new_task_data->tdg = taskdata->tdg;
4965 new_task_data->is_taskgraph = 0;
4970 __kmp_omp_taskloop_task(NULL, gtid, new_task, codeptr_ra);
4972 __kmp_omp_task(gtid, new_task,
true);
4976 if (n_tsk0 > num_t_min)
4977 __kmp_taskloop_recur(loc, gtid, task, lb, ub, st, ub_glob, n_tsk0, gr_size0,
4978 ext0, last_chunk0, tc0, num_t_min,
4984 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, n_tsk0,
4985 gr_size0, ext0, last_chunk0, tc0,
4991 KA_TRACE(40, (
"__kmp_taskloop_recur(exit): T#%d\n", gtid));
4994static void __kmp_taskloop(
ident_t *loc,
int gtid, kmp_task_t *task,
int if_val,
4995 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
4996 int nogroup,
int sched, kmp_uint64 grainsize,
4997 int modifier,
void *task_dup) {
4998 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4999 KMP_DEBUG_ASSERT(task != NULL);
5001#if OMPT_SUPPORT && OMPT_OPTIONAL
5002 OMPT_STORE_RETURN_ADDRESS(gtid);
5004 __kmpc_taskgroup(loc, gtid);
5007#if OMP_TASKGRAPH_EXPERIMENTAL
5008 KMP_ATOMIC_DEC(&__kmp_tdg_task_id);
5012 kmp_taskloop_bounds_t task_bounds(task, lb, ub);
5015 kmp_uint64 lower = task_bounds.get_lb();
5016 kmp_uint64 upper = task_bounds.get_ub();
5017 kmp_uint64 ub_glob = upper;
5018 kmp_uint64 num_tasks = 0, extras = 0;
5019 kmp_int64 last_chunk =
5021 kmp_uint64 num_tasks_min = __kmp_taskloop_min_tasks;
5022 kmp_info_t *thread = __kmp_threads[gtid];
5023 kmp_taskdata_t *current_task = thread->th.th_current_task;
5025 KA_TRACE(20, (
"__kmp_taskloop: T#%d, task %p, lb %lld, ub %lld, st %lld, "
5026 "grain %llu(%d, %d), dup %p\n",
5027 gtid, taskdata, lower, upper, st, grainsize, sched, modifier,
5032 tc = upper - lower + 1;
5033 }
else if (st < 0) {
5034 tc = (lower - upper) / (-st) + 1;
5036 tc = (upper - lower) / st + 1;
5039 KA_TRACE(20, (
"__kmp_taskloop(exit): T#%d zero-trip loop\n", gtid));
5041 __kmp_task_start(gtid, task, current_task);
5043 __kmp_task_finish<false>(gtid, task, current_task);
5047#if OMPT_SUPPORT && OMPT_OPTIONAL
5048 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
5049 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
5050 if (ompt_enabled.ompt_callback_work) {
5051 ompt_callbacks.ompt_callback(ompt_callback_work)(
5052 ompt_work_taskloop, ompt_scope_begin, &(team_info->parallel_data),
5053 &(task_info->task_data), tc, OMPT_GET_RETURN_ADDRESS(0));
5057 if (num_tasks_min == 0)
5060 KMP_MIN(thread->th.th_team_nproc * 10, INITIAL_TASK_DEQUE_SIZE);
5066 grainsize = thread->th.th_team_nproc *
static_cast<kmp_uint64
>(10);
5069 if (grainsize > tc) {
5074 num_tasks = grainsize;
5075 grainsize = tc / num_tasks;
5076 extras = tc % num_tasks;
5080 if (grainsize > tc) {
5086 num_tasks = (tc + grainsize - 1) / grainsize;
5087 last_chunk = tc - (num_tasks * grainsize);
5090 num_tasks = tc / grainsize;
5092 grainsize = tc / num_tasks;
5093 extras = tc % num_tasks;
5098 KMP_ASSERT2(0,
"unknown scheduling of taskloop");
5101 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize +
5102 (last_chunk < 0 ? last_chunk : extras));
5103 KMP_DEBUG_ASSERT(num_tasks > extras);
5104 KMP_DEBUG_ASSERT(num_tasks > 0);
5110 taskdata->td_flags.task_serial = 1;
5111 taskdata->td_flags.tiedness = TASK_TIED;
5113 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
5114 grainsize, extras, last_chunk, tc,
5116 OMPT_GET_RETURN_ADDRESS(0),
5121 }
else if (num_tasks > num_tasks_min && !taskdata->td_flags.native) {
5122 KA_TRACE(20, (
"__kmp_taskloop: T#%d, go recursive: tc %llu, #tasks %llu"
5123 "(%lld), grain %llu, extras %llu, last_chunk %lld\n",
5124 gtid, tc, num_tasks, num_tasks_min, grainsize, extras,
5126 __kmp_taskloop_recur(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
5127 grainsize, extras, last_chunk, tc, num_tasks_min,
5129 OMPT_GET_RETURN_ADDRESS(0),
5133 KA_TRACE(20, (
"__kmp_taskloop: T#%d, go linear: tc %llu, #tasks %llu"
5134 "(%lld), grain %llu, extras %llu, last_chunk %lld\n",
5135 gtid, tc, num_tasks, num_tasks_min, grainsize, extras,
5137 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
5138 grainsize, extras, last_chunk, tc,
5140 OMPT_GET_RETURN_ADDRESS(0),
5145#if OMPT_SUPPORT && OMPT_OPTIONAL
5146 if (ompt_enabled.ompt_callback_work) {
5147 ompt_callbacks.ompt_callback(ompt_callback_work)(
5148 ompt_work_taskloop, ompt_scope_end, &(team_info->parallel_data),
5149 &(task_info->task_data), tc, OMPT_GET_RETURN_ADDRESS(0));
5154#if OMPT_SUPPORT && OMPT_OPTIONAL
5155 OMPT_STORE_RETURN_ADDRESS(gtid);
5157 __kmpc_end_taskgroup(loc, gtid);
5159 KA_TRACE(20, (
"__kmp_taskloop(exit): T#%d\n", gtid));
5179 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
int nogroup,
5180 int sched, kmp_uint64 grainsize,
void *task_dup) {
5181 __kmp_assert_valid_gtid(gtid);
5182 KA_TRACE(20, (
"__kmpc_taskloop(enter): T#%d\n", gtid));
5183 __kmp_taskloop(loc, gtid, task, if_val, lb, ub, st, nogroup, sched, grainsize,
5185 KA_TRACE(20, (
"__kmpc_taskloop(exit): T#%d\n", gtid));
5206 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
5207 int nogroup,
int sched, kmp_uint64 grainsize,
5208 int modifier,
void *task_dup) {
5209 __kmp_assert_valid_gtid(gtid);
5210 KA_TRACE(20, (
"__kmpc_taskloop_5(enter): T#%d\n", gtid));
5211 __kmp_taskloop(loc, gtid, task, if_val, lb, ub, st, nogroup, sched, grainsize,
5212 modifier, task_dup);
5213 KA_TRACE(20, (
"__kmpc_taskloop_5(exit): T#%d\n", gtid));
5225 if (gtid == KMP_GTID_DNE)
5228 kmp_info_t *thread = __kmp_thread_from_gtid(gtid);
5229 kmp_taskdata_t *taskdata = thread->th.th_current_task;
5234 return &taskdata->td_target_data.async_handle;
5246 if (gtid == KMP_GTID_DNE)
5249 kmp_info_t *thread = __kmp_thread_from_gtid(gtid);
5250 kmp_taskdata_t *taskdata = thread->th.th_current_task;
5255 return taskdata->td_task_team != NULL;
5258#if OMP_TASKGRAPH_EXPERIMENTAL
5263static kmp_tdg_info_t *__kmp_find_tdg(kmp_int32 tdg_id) {
5264 kmp_tdg_info_t *res =
nullptr;
5265 if (__kmp_max_tdgs == 0)
5268 if (__kmp_global_tdgs == NULL)
5269 __kmp_global_tdgs = (kmp_tdg_info_t **)__kmp_allocate(
5270 sizeof(kmp_tdg_info_t *) * __kmp_max_tdgs);
5272 if ((__kmp_global_tdgs[tdg_id]) &&
5273 (__kmp_global_tdgs[tdg_id]->tdg_status != KMP_TDG_NONE))
5274 res = __kmp_global_tdgs[tdg_id];
5281void __kmp_print_tdg_dot(kmp_tdg_info_t *tdg, kmp_int32 gtid) {
5282 kmp_int32 tdg_id = tdg->tdg_id;
5283 KA_TRACE(10, (
"__kmp_print_tdg_dot(enter): T#%d tdg_id=%d \n", gtid, tdg_id));
5286 sprintf(file_name,
"tdg_%d.dot", tdg_id);
5289 kmp_int32 num_tasks = KMP_ATOMIC_LD_RLX(&tdg->num_tasks);
5293 " subgraph cluster {\n"
5296 for (kmp_int32 i = 0; i < num_tasks; i++) {
5297 fprintf(tdg_file,
" %d[style=bold]\n", i);
5299 fprintf(tdg_file,
" }\n");
5300 for (kmp_int32 i = 0; i < num_tasks; i++) {
5301 kmp_int32 nsuccessors = tdg->record_map[i].nsuccessors;
5302 kmp_int32 *successors = tdg->record_map[i].successors;
5303 if (nsuccessors > 0) {
5304 for (kmp_int32 j = 0; j < nsuccessors; j++)
5305 fprintf(tdg_file,
" %d -> %d \n", i, successors[j]);
5308 fprintf(tdg_file,
"}");
5309 KA_TRACE(10, (
"__kmp_print_tdg_dot(exit): T#%d tdg_id=%d \n", gtid, tdg_id));
5316void __kmp_exec_tdg(kmp_int32 gtid, kmp_tdg_info_t *tdg) {
5317 KMP_DEBUG_ASSERT(tdg->tdg_status == KMP_TDG_READY);
5318 KA_TRACE(10, (
"__kmp_exec_tdg(enter): T#%d tdg_id=%d num_roots=%d\n", gtid,
5319 tdg->tdg_id, tdg->num_roots));
5320 kmp_node_info_t *this_record_map = tdg->record_map;
5321 kmp_int32 *this_root_tasks = tdg->root_tasks;
5322 kmp_int32 this_num_roots = tdg->num_roots;
5323 kmp_int32 this_num_tasks = KMP_ATOMIC_LD_RLX(&tdg->num_tasks);
5325 kmp_info_t *thread = __kmp_threads[gtid];
5326 kmp_taskdata_t *parent_task = thread->th.th_current_task;
5328 if (tdg->rec_taskred_data) {
5332 for (kmp_int32 j = 0; j < this_num_tasks; j++) {
5333 kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(this_record_map[j].task);
5335 td->td_parent = parent_task;
5336 this_record_map[j].parent_task = parent_task;
5338 kmp_taskgroup_t *parent_taskgroup =
5339 this_record_map[j].parent_task->td_taskgroup;
5341 KMP_ATOMIC_ST_RLX(&this_record_map[j].npredecessors_counter,
5342 this_record_map[j].npredecessors);
5343 KMP_ATOMIC_INC(&this_record_map[j].parent_task->td_incomplete_child_tasks);
5345 if (parent_taskgroup) {
5346 KMP_ATOMIC_INC(&parent_taskgroup->count);
5348 td->td_taskgroup = parent_taskgroup;
5349 }
else if (td->td_taskgroup !=
nullptr) {
5351 td->td_taskgroup =
nullptr;
5353 if (this_record_map[j].parent_task->td_flags.tasktype == TASK_EXPLICIT)
5354 KMP_ATOMIC_INC(&this_record_map[j].parent_task->td_allocated_child_tasks);
5357 for (kmp_int32 j = 0; j < this_num_roots; ++j) {
5358 __kmp_omp_task(gtid, this_record_map[this_root_tasks[j]].task,
true);
5360 KA_TRACE(10, (
"__kmp_exec_tdg(exit): T#%d tdg_id=%d num_roots=%d\n", gtid,
5361 tdg->tdg_id, tdg->num_roots));
5369static inline void __kmp_start_record(kmp_int32 gtid,
5370 kmp_taskgraph_flags_t *flags,
5372 kmp_tdg_info_t *tdg =
5373 (kmp_tdg_info_t *)__kmp_allocate(
sizeof(kmp_tdg_info_t));
5374 __kmp_global_tdgs[__kmp_curr_tdg_idx] = tdg;
5376 tdg->tdg_id = tdg_id;
5377 tdg->map_size = INIT_MAPSIZE;
5378 tdg->num_roots = -1;
5379 tdg->root_tasks =
nullptr;
5380 tdg->tdg_status = KMP_TDG_RECORDING;
5381 tdg->rec_num_taskred = 0;
5382 tdg->rec_taskred_data =
nullptr;
5383 KMP_ATOMIC_ST_RLX(&tdg->num_tasks, 0);
5386 kmp_node_info_t *this_record_map =
5387 (kmp_node_info_t *)__kmp_allocate(INIT_MAPSIZE *
sizeof(kmp_node_info_t));
5388 for (kmp_int32 i = 0; i < INIT_MAPSIZE; i++) {
5389 kmp_int32 *successorsList =
5390 (kmp_int32 *)__kmp_allocate(__kmp_successors_size *
sizeof(kmp_int32));
5391 this_record_map[i].task =
nullptr;
5392 this_record_map[i].successors = successorsList;
5393 this_record_map[i].nsuccessors = 0;
5394 this_record_map[i].npredecessors = 0;
5395 this_record_map[i].successors_size = __kmp_successors_size;
5396 KMP_ATOMIC_ST_RLX(&this_record_map[i].npredecessors_counter, 0);
5399 __kmp_global_tdgs[__kmp_curr_tdg_idx]->record_map = this_record_map;
5409kmp_int32 __kmpc_start_record_task(
ident_t *loc_ref, kmp_int32 gtid,
5410 kmp_int32 input_flags, kmp_int32 tdg_id) {
5413 kmp_taskgraph_flags_t *flags = (kmp_taskgraph_flags_t *)&input_flags;
5415 (
"__kmpc_start_record_task(enter): T#%d loc=%p flags=%d tdg_id=%d\n",
5416 gtid, loc_ref, input_flags, tdg_id));
5418 if (__kmp_max_tdgs == 0) {
5421 (
"__kmpc_start_record_task(abandon): T#%d loc=%p flags=%d tdg_id = %d, "
5422 "__kmp_max_tdgs = 0\n",
5423 gtid, loc_ref, input_flags, tdg_id));
5427 __kmpc_taskgroup(loc_ref, gtid);
5428 if (kmp_tdg_info_t *tdg = __kmp_find_tdg(tdg_id)) {
5430 __kmp_exec_tdg(gtid, tdg);
5433 __kmp_curr_tdg_idx = tdg_id;
5434 KMP_DEBUG_ASSERT(__kmp_curr_tdg_idx < __kmp_max_tdgs);
5435 __kmp_start_record(gtid, flags, tdg_id);
5439 KA_TRACE(10, (
"__kmpc_start_record_task(exit): T#%d TDG %d starts to %s\n",
5440 gtid, tdg_id, res ?
"record" :
"execute"));
5447void __kmp_end_record(kmp_int32 gtid, kmp_tdg_info_t *tdg) {
5449 kmp_node_info_t *this_record_map = tdg->record_map;
5450 kmp_int32 this_num_tasks = KMP_ATOMIC_LD_RLX(&tdg->num_tasks);
5451 kmp_int32 *this_root_tasks =
5452 (kmp_int32 *)__kmp_allocate(this_num_tasks *
sizeof(kmp_int32));
5453 kmp_int32 this_map_size = tdg->map_size;
5454 kmp_int32 this_num_roots = 0;
5455 kmp_info_t *thread = __kmp_threads[gtid];
5457 for (kmp_int32 i = 0; i < this_num_tasks; i++) {
5458 if (this_record_map[i].npredecessors == 0) {
5459 this_root_tasks[this_num_roots++] = i;
5464 tdg->map_size = this_map_size;
5465 tdg->num_roots = this_num_roots;
5466 tdg->root_tasks = this_root_tasks;
5467 KMP_DEBUG_ASSERT(tdg->tdg_status == KMP_TDG_RECORDING);
5468 tdg->tdg_status = KMP_TDG_READY;
5470 if (thread->th.th_current_task->td_dephash) {
5471 __kmp_dephash_free(thread, thread->th.th_current_task->td_dephash);
5472 thread->th.th_current_task->td_dephash = NULL;
5476 for (kmp_int32 i = 0; i < this_num_tasks; i++) {
5477 KMP_ATOMIC_ST_RLX(&this_record_map[i].npredecessors_counter,
5478 this_record_map[i].npredecessors);
5480 KMP_ATOMIC_ST_RLX(&__kmp_tdg_task_id, 0);
5483 __kmp_print_tdg_dot(tdg, gtid);
5493void __kmpc_end_record_task(
ident_t *loc_ref, kmp_int32 gtid,
5494 kmp_int32 input_flags, kmp_int32 tdg_id) {
5495 kmp_tdg_info_t *tdg = __kmp_find_tdg(tdg_id);
5497 KA_TRACE(10, (
"__kmpc_end_record_task(enter): T#%d loc=%p finishes recording"
5498 " tdg=%d with flags=%d\n",
5499 gtid, loc_ref, tdg_id, input_flags));
5500 if (__kmp_max_tdgs) {
5502 __kmpc_end_taskgroup(loc_ref, gtid);
5503 if (__kmp_tdg_is_recording(tdg->tdg_status))
5504 __kmp_end_record(gtid, tdg);
5506 KA_TRACE(10, (
"__kmpc_end_record_task(exit): T#%d loc=%p finished recording"
5507 " tdg=%d, its status is now READY\n",
5508 gtid, loc_ref, tdg_id));
struct kmp_taskred_data kmp_taskred_data_t
struct kmp_task_red_input kmp_task_red_input_t
struct kmp_taskred_flags kmp_taskred_flags_t
struct kmp_taskred_input kmp_taskred_input_t
#define KMP_COUNT_BLOCK(name)
Increments specified counter (name).
void * __kmpc_task_reduction_get_th_data(int gtid, void *tskgrp, void *data)
void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int sched, kmp_uint64 grainsize, void *task_dup)
void * __kmpc_task_reduction_modifier_init(ident_t *loc, int gtid, int is_ws, int num, void *data)
void * __kmpc_taskred_modifier_init(ident_t *loc, int gtid, int is_ws, int num, void *data)
bool __kmpc_omp_has_task_team(kmp_int32 gtid)
void __kmpc_proxy_task_completed_ooo(kmp_task_t *ptask)
void __kmpc_task_reduction_modifier_fini(ident_t *loc, int gtid, int is_ws)
kmp_int32 __kmpc_omp_reg_task_with_affinity(ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *new_task, kmp_int32 naffins, kmp_task_affinity_info_t *affin_list)
void __kmpc_taskloop_5(ident_t *loc, int gtid, kmp_task_t *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int sched, kmp_uint64 grainsize, int modifier, void *task_dup)
void * __kmpc_task_reduction_init(int gtid, int num, void *data)
void __kmpc_proxy_task_completed(kmp_int32 gtid, kmp_task_t *ptask)
void * __kmpc_taskred_init(int gtid, int num, void *data)
void ** __kmpc_omp_get_target_async_handle_ptr(kmp_int32 gtid)
kmp_taskred_flags_t flags