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);
44static bool __kmp_task_is_allowed(
int gtid,
const kmp_int32 is_constrained,
45 const kmp_taskdata_t *tasknew,
46 const kmp_taskdata_t *taskcurr) {
47 if (is_constrained && (tasknew->td_flags.tiedness == TASK_TIED)) {
51 kmp_taskdata_t *current = taskcurr->td_last_tied;
52 KMP_DEBUG_ASSERT(current != NULL);
54 if (current->td_flags.tasktype == TASK_EXPLICIT ||
55 current->td_taskwait_thread > 0) {
56 kmp_int32 level = current->td_level;
57 kmp_taskdata_t *parent = tasknew->td_parent;
58 while (parent != current && parent->td_level > level) {
60 parent = parent->td_parent;
61 KMP_DEBUG_ASSERT(parent != NULL);
63 if (parent != current)
68 kmp_depnode_t *node = tasknew->td_depnode;
69 if (UNLIKELY(node && (node->dn.mtx_num_locks > 0))) {
70 for (
int i = 0; i < node->dn.mtx_num_locks; ++i) {
71 KMP_DEBUG_ASSERT(node->dn.mtx_locks[i] != NULL);
72 if (__kmp_test_lock(node->dn.mtx_locks[i], gtid))
75 for (
int j = i - 1; j >= 0; --j)
76 __kmp_release_lock(node->dn.mtx_locks[j], gtid);
80 node->dn.mtx_num_locks = -node->dn.mtx_num_locks;
89static void __kmp_realloc_task_deque(kmp_info_t *thread,
90 kmp_thread_data_t *thread_data) {
91 kmp_int32 size = TASK_DEQUE_SIZE(thread_data->td);
92 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) == size);
93 kmp_int32 new_size = 2 * size;
95 KE_TRACE(10, (
"__kmp_realloc_task_deque: T#%d reallocating deque[from %d to "
96 "%d] for thread_data %p\n",
97 __kmp_gtid_from_thread(thread), size, new_size, thread_data));
99 kmp_taskdata_t **new_deque =
100 (kmp_taskdata_t **)__kmp_allocate(new_size *
sizeof(kmp_taskdata_t *));
103 for (i = thread_data->td.td_deque_head, j = 0; j < size;
104 i = (i + 1) & TASK_DEQUE_MASK(thread_data->td), j++)
105 new_deque[j] = thread_data->td.td_deque[i];
107 __kmp_free(thread_data->td.td_deque);
109 thread_data->td.td_deque_head = 0;
110 thread_data->td.td_deque_tail = size;
111 thread_data->td.td_deque = new_deque;
112 thread_data->td.td_deque_size = new_size;
115static kmp_task_pri_t *__kmp_alloc_task_pri_list() {
116 kmp_task_pri_t *l = (kmp_task_pri_t *)__kmp_allocate(
sizeof(kmp_task_pri_t));
117 kmp_thread_data_t *thread_data = &l->td;
118 __kmp_init_bootstrap_lock(&thread_data->td.td_deque_lock);
119 thread_data->td.td_deque_last_stolen = -1;
120 KE_TRACE(20, (
"__kmp_alloc_task_pri_list: T#%d allocating deque[%d] "
121 "for thread_data %p\n",
122 __kmp_get_gtid(), INITIAL_TASK_DEQUE_SIZE, thread_data));
123 thread_data->td.td_deque = (kmp_taskdata_t **)__kmp_allocate(
124 INITIAL_TASK_DEQUE_SIZE *
sizeof(kmp_taskdata_t *));
125 thread_data->td.td_deque_size = INITIAL_TASK_DEQUE_SIZE;
134static kmp_thread_data_t *
135__kmp_get_priority_deque_data(kmp_task_team_t *task_team, kmp_int32 pri) {
136 kmp_thread_data_t *thread_data;
137 kmp_task_pri_t *lst = task_team->tt.tt_task_pri_list;
138 if (lst->priority == pri) {
140 thread_data = &lst->td;
141 }
else if (lst->priority < pri) {
144 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
145 thread_data = &list->td;
146 list->priority = pri;
148 task_team->tt.tt_task_pri_list = list;
150 kmp_task_pri_t *next_queue = lst->next;
151 while (next_queue && next_queue->priority > pri) {
153 next_queue = lst->next;
156 if (next_queue == NULL) {
158 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
159 thread_data = &list->td;
160 list->priority = pri;
163 }
else if (next_queue->priority == pri) {
165 thread_data = &next_queue->td;
168 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
169 thread_data = &list->td;
170 list->priority = pri;
171 list->next = next_queue;
179static kmp_int32 __kmp_push_priority_task(kmp_int32 gtid, kmp_info_t *thread,
180 kmp_taskdata_t *taskdata,
181 kmp_task_team_t *task_team,
183 kmp_thread_data_t *thread_data = NULL;
185 (
"__kmp_push_priority_task: T#%d trying to push task %p, pri %d.\n",
186 gtid, taskdata, pri));
189 kmp_task_pri_t *lst = task_team->tt.tt_task_pri_list;
190 if (UNLIKELY(lst == NULL)) {
191 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
192 if (task_team->tt.tt_task_pri_list == NULL) {
194 kmp_task_pri_t *list = __kmp_alloc_task_pri_list();
195 thread_data = &list->td;
196 list->priority = pri;
198 task_team->tt.tt_task_pri_list = list;
201 thread_data = __kmp_get_priority_deque_data(task_team, pri);
203 __kmp_release_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
205 if (lst->priority == pri) {
207 thread_data = &lst->td;
209 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
210 thread_data = __kmp_get_priority_deque_data(task_team, pri);
211 __kmp_release_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
214 KMP_DEBUG_ASSERT(thread_data);
216 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
218 if (TCR_4(thread_data->td.td_deque_ntasks) >=
219 TASK_DEQUE_SIZE(thread_data->td)) {
220 if (__kmp_enable_task_throttling &&
221 __kmp_task_is_allowed(gtid, __kmp_task_stealing_constraint, taskdata,
222 thread->th.th_current_task)) {
223 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
224 KA_TRACE(20, (
"__kmp_push_priority_task: T#%d deque is full; returning "
225 "TASK_NOT_PUSHED for task %p\n",
227 return TASK_NOT_PUSHED;
230 __kmp_realloc_task_deque(thread, thread_data);
233 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) <
234 TASK_DEQUE_SIZE(thread_data->td));
236 thread_data->td.td_deque[thread_data->td.td_deque_tail] = taskdata;
238 thread_data->td.td_deque_tail =
239 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td);
240 TCW_4(thread_data->td.td_deque_ntasks,
241 TCR_4(thread_data->td.td_deque_ntasks) + 1);
242 KMP_FSYNC_RELEASING(thread->th.th_current_task);
243 KMP_FSYNC_RELEASING(taskdata);
244 KA_TRACE(20, (
"__kmp_push_priority_task: T#%d returning "
245 "TASK_SUCCESSFULLY_PUSHED: task=%p ntasks=%d head=%u tail=%u\n",
246 gtid, taskdata, thread_data->td.td_deque_ntasks,
247 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
248 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
249 task_team->tt.tt_num_task_pri++;
250 return TASK_SUCCESSFULLY_PUSHED;
254static kmp_int32 __kmp_push_task(kmp_int32 gtid, kmp_task_t *task) {
255 kmp_info_t *thread = __kmp_threads[gtid];
256 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
261 if (UNLIKELY(taskdata->td_flags.hidden_helper &&
262 !KMP_HIDDEN_HELPER_THREAD(gtid))) {
263 kmp_int32 shadow_gtid = KMP_GTID_TO_SHADOW_GTID(gtid);
264 __kmpc_give_task(task, __kmp_tid_from_gtid(shadow_gtid));
266 __kmp_hidden_helper_worker_thread_signal();
267 return TASK_SUCCESSFULLY_PUSHED;
270 kmp_task_team_t *task_team = thread->th.th_task_team;
271 kmp_int32 tid = __kmp_tid_from_gtid(gtid);
272 kmp_thread_data_t *thread_data;
275 (
"__kmp_push_task: T#%d trying to push task %p.\n", gtid, taskdata));
277 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
280 kmp_int32 counter = 1 + KMP_ATOMIC_INC(&taskdata->td_untied_count);
281 KMP_DEBUG_USE_VAR(counter);
284 (
"__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n",
285 gtid, counter, taskdata));
289 if (UNLIKELY(taskdata->td_flags.task_serial)) {
290 KA_TRACE(20, (
"__kmp_push_task: T#%d team serialized; returning "
291 "TASK_NOT_PUSHED for task %p\n",
293 return TASK_NOT_PUSHED;
298 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
299 if (UNLIKELY(!KMP_TASKING_ENABLED(task_team))) {
300 __kmp_enable_tasking(task_team, thread);
302 KMP_DEBUG_ASSERT(TCR_4(task_team->tt.tt_found_tasks) == TRUE);
303 KMP_DEBUG_ASSERT(TCR_PTR(task_team->tt.tt_threads_data) != NULL);
305 if (taskdata->td_flags.priority_specified && task->data2.priority > 0 &&
306 __kmp_max_task_priority > 0) {
307 int pri = KMP_MIN(task->data2.priority, __kmp_max_task_priority);
308 return __kmp_push_priority_task(gtid, thread, taskdata, task_team, pri);
312 thread_data = &task_team->tt.tt_threads_data[tid];
317 if (UNLIKELY(thread_data->td.td_deque == NULL)) {
318 __kmp_alloc_task_deque(thread, thread_data);
323 if (TCR_4(thread_data->td.td_deque_ntasks) >=
324 TASK_DEQUE_SIZE(thread_data->td)) {
325 if (__kmp_enable_task_throttling &&
326 __kmp_task_is_allowed(gtid, __kmp_task_stealing_constraint, taskdata,
327 thread->th.th_current_task)) {
328 KA_TRACE(20, (
"__kmp_push_task: T#%d deque is full; returning "
329 "TASK_NOT_PUSHED for task %p\n",
331 return TASK_NOT_PUSHED;
333 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
335 if (TCR_4(thread_data->td.td_deque_ntasks) >=
336 TASK_DEQUE_SIZE(thread_data->td)) {
338 __kmp_realloc_task_deque(thread, thread_data);
344 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
346 if (TCR_4(thread_data->td.td_deque_ntasks) >=
347 TASK_DEQUE_SIZE(thread_data->td)) {
348 if (__kmp_enable_task_throttling &&
349 __kmp_task_is_allowed(gtid, __kmp_task_stealing_constraint, taskdata,
350 thread->th.th_current_task)) {
351 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
352 KA_TRACE(20, (
"__kmp_push_task: T#%d deque is full on 2nd check; "
353 "returning TASK_NOT_PUSHED for task %p\n",
355 return TASK_NOT_PUSHED;
358 __kmp_realloc_task_deque(thread, thread_data);
363 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) <
364 TASK_DEQUE_SIZE(thread_data->td));
366 thread_data->td.td_deque[thread_data->td.td_deque_tail] =
369 thread_data->td.td_deque_tail =
370 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td);
371 TCW_4(thread_data->td.td_deque_ntasks,
372 TCR_4(thread_data->td.td_deque_ntasks) + 1);
373 KMP_FSYNC_RELEASING(thread->th.th_current_task);
374 KMP_FSYNC_RELEASING(taskdata);
375 KA_TRACE(20, (
"__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "
376 "task=%p ntasks=%d head=%u tail=%u\n",
377 gtid, taskdata, thread_data->td.td_deque_ntasks,
378 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
380 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
382 return TASK_SUCCESSFULLY_PUSHED;
389void __kmp_pop_current_task_from_thread(kmp_info_t *this_thr) {
390 KF_TRACE(10, (
"__kmp_pop_current_task_from_thread(enter): T#%d "
391 "this_thread=%p, curtask=%p, "
392 "curtask_parent=%p\n",
393 0, this_thr, this_thr->th.th_current_task,
394 this_thr->th.th_current_task->td_parent));
396 this_thr->th.th_current_task = this_thr->th.th_current_task->td_parent;
398 KF_TRACE(10, (
"__kmp_pop_current_task_from_thread(exit): 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));
411void __kmp_push_current_task_to_thread(kmp_info_t *this_thr, kmp_team_t *team,
415 KF_TRACE(10, (
"__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
418 tid, this_thr, this_thr->th.th_current_task,
419 team->t.t_implicit_task_taskdata[tid].td_parent));
421 KMP_DEBUG_ASSERT(this_thr != NULL);
424 if (this_thr->th.th_current_task != &team->t.t_implicit_task_taskdata[0]) {
425 team->t.t_implicit_task_taskdata[0].td_parent =
426 this_thr->th.th_current_task;
427 this_thr->th.th_current_task = &team->t.t_implicit_task_taskdata[0];
430 team->t.t_implicit_task_taskdata[tid].td_parent =
431 team->t.t_implicit_task_taskdata[0].td_parent;
432 this_thr->th.th_current_task = &team->t.t_implicit_task_taskdata[tid];
435 KF_TRACE(10, (
"__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
438 tid, this_thr, this_thr->th.th_current_task,
439 team->t.t_implicit_task_taskdata[tid].td_parent));
447static void __kmp_task_start(kmp_int32 gtid, kmp_task_t *task,
448 kmp_taskdata_t *current_task) {
449 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
450 kmp_info_t *thread = __kmp_threads[gtid];
453 (
"__kmp_task_start(enter): T#%d starting task %p: current_task=%p\n",
454 gtid, taskdata, current_task));
456 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
461 current_task->td_flags.executing = 0;
471 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
472 taskdata->td_last_tied = current_task->td_last_tied;
473 KMP_DEBUG_ASSERT(taskdata->td_last_tied);
477 thread->th.th_current_task = taskdata;
479 KMP_DEBUG_ASSERT(taskdata->td_flags.started == 0 ||
480 taskdata->td_flags.tiedness == TASK_UNTIED);
481 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 0 ||
482 taskdata->td_flags.tiedness == TASK_UNTIED);
483 taskdata->td_flags.started = 1;
484 taskdata->td_flags.executing = 1;
485 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
486 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
493 KA_TRACE(10, (
"__kmp_task_start(exit): T#%d task=%p\n", gtid, taskdata));
503static inline void __ompt_task_start(kmp_task_t *task,
504 kmp_taskdata_t *current_task,
506 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
507 ompt_task_status_t status = ompt_task_switch;
508 if (__kmp_threads[gtid]->th.ompt_thread_info.ompt_task_yielded) {
509 status = ompt_task_yield;
510 __kmp_threads[gtid]->th.ompt_thread_info.ompt_task_yielded = 0;
513 if (ompt_enabled.ompt_callback_task_schedule) {
514 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
515 &(current_task->ompt_task_info.task_data), status,
516 &(taskdata->ompt_task_info.task_data));
518 taskdata->ompt_task_info.scheduling_parent = current_task;
523static inline void __ompt_task_finish(kmp_task_t *task,
524 kmp_taskdata_t *resumed_task,
525 ompt_task_status_t status) {
526 if (ompt_enabled.ompt_callback_task_schedule) {
527 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
528 if (__kmp_omp_cancellation && taskdata->td_taskgroup &&
529 taskdata->td_taskgroup->cancel_request == cancel_taskgroup) {
530 status = ompt_task_cancel;
534 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
535 &(taskdata->ompt_task_info.task_data), status,
536 (resumed_task ? &(resumed_task->ompt_task_info.task_data) : NULL));
542static void __kmpc_omp_task_begin_if0_template(
ident_t *loc_ref, kmp_int32 gtid,
545 void *return_address) {
546 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
547 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
549 KA_TRACE(10, (
"__kmpc_omp_task_begin_if0(enter): T#%d loc=%p task=%p "
551 gtid, loc_ref, taskdata, current_task));
553 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
556 kmp_int32 counter = 1 + KMP_ATOMIC_INC(&taskdata->td_untied_count);
557 KMP_DEBUG_USE_VAR(counter);
558 KA_TRACE(20, (
"__kmpc_omp_task_begin_if0: T#%d untied_count (%d) "
559 "incremented for task %p\n",
560 gtid, counter, taskdata));
563 taskdata->td_flags.task_serial =
565 __kmp_task_start(gtid, task, current_task);
569 if (current_task->ompt_task_info.frame.enter_frame.ptr == NULL) {
570 current_task->ompt_task_info.frame.enter_frame.ptr =
571 taskdata->ompt_task_info.frame.exit_frame.ptr = frame_address;
572 current_task->ompt_task_info.frame.enter_frame_flags =
573 taskdata->ompt_task_info.frame.exit_frame_flags =
574 OMPT_FRAME_FLAGS_APP;
576 if (ompt_enabled.ompt_callback_task_create) {
577 ompt_task_info_t *parent_info = &(current_task->ompt_task_info);
578 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
579 &(parent_info->task_data), &(parent_info->frame),
580 &(taskdata->ompt_task_info.task_data),
581 TASK_TYPE_DETAILS_FORMAT(taskdata), 0, return_address);
583 __ompt_task_start(task, current_task, gtid);
587 KA_TRACE(10, (
"__kmpc_omp_task_begin_if0(exit): T#%d loc=%p task=%p,\n", gtid,
593static void __kmpc_omp_task_begin_if0_ompt(
ident_t *loc_ref, kmp_int32 gtid,
596 void *return_address) {
597 __kmpc_omp_task_begin_if0_template<true>(loc_ref, gtid, task, frame_address,
614__attribute__((target(
"backchain")))
616void __kmpc_omp_task_begin_if0(
ident_t *loc_ref, kmp_int32 gtid,
619 if (UNLIKELY(ompt_enabled.enabled)) {
620 OMPT_STORE_RETURN_ADDRESS(gtid);
621 __kmpc_omp_task_begin_if0_ompt(loc_ref, gtid, task,
622 OMPT_GET_FRAME_ADDRESS(1),
623 OMPT_LOAD_RETURN_ADDRESS(gtid));
627 __kmpc_omp_task_begin_if0_template<false>(loc_ref, gtid, task, NULL, NULL);
633void __kmpc_omp_task_begin(
ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *task) {
634 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
638 (
"__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n",
639 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task), current_task));
641 __kmp_task_start(gtid, task, current_task);
643 KA_TRACE(10, (
"__kmpc_omp_task_begin(exit): T#%d loc=%p task=%p,\n", gtid,
644 loc_ref, KMP_TASK_TO_TASKDATA(task)));
654static void __kmp_free_task(kmp_int32 gtid, kmp_taskdata_t *taskdata,
655 kmp_info_t *thread) {
656 KA_TRACE(30, (
"__kmp_free_task: T#%d freeing data from task %p\n", gtid,
660 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
661 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 0);
662 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 1);
663 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
664 KMP_DEBUG_ASSERT(taskdata->td_allocated_child_tasks == 0 ||
665 taskdata->td_flags.task_serial == 1);
666 KMP_DEBUG_ASSERT(taskdata->td_incomplete_child_tasks == 0);
667 kmp_task_t *task = KMP_TASKDATA_TO_TASK(taskdata);
669 task->data1.destructors = NULL;
670 task->data2.priority = 0;
672 taskdata->td_flags.freed = 1;
675 __kmp_fast_free(thread, taskdata);
677 __kmp_thread_free(thread, taskdata);
680 KA_TRACE(20, (
"__kmp_free_task: T#%d freed task %p\n", gtid, taskdata));
689static void __kmp_free_task_and_ancestors(kmp_int32 gtid,
690 kmp_taskdata_t *taskdata,
691 kmp_info_t *thread) {
694 kmp_int32 team_serial =
695 (taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser) &&
696 !taskdata->td_flags.proxy;
697 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
699 kmp_int32 children = KMP_ATOMIC_DEC(&taskdata->td_allocated_child_tasks) - 1;
700 KMP_DEBUG_ASSERT(children >= 0);
703 while (children == 0) {
704 kmp_taskdata_t *parent_taskdata = taskdata->td_parent;
706 KA_TRACE(20, (
"__kmp_free_task_and_ancestors(enter): T#%d task %p complete "
707 "and freeing itself\n",
711 __kmp_free_task(gtid, taskdata, thread);
713 taskdata = parent_taskdata;
719 if (taskdata->td_flags.tasktype == TASK_IMPLICIT) {
720 if (taskdata->td_dephash) {
721 int children = KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks);
722 kmp_tasking_flags_t flags_old = taskdata->td_flags;
723 if (children == 0 && flags_old.complete == 1) {
724 kmp_tasking_flags_t flags_new = flags_old;
725 flags_new.complete = 0;
726 if (KMP_COMPARE_AND_STORE_ACQ32(
727 RCAST(kmp_int32 *, &taskdata->td_flags),
728 *RCAST(kmp_int32 *, &flags_old),
729 *RCAST(kmp_int32 *, &flags_new))) {
730 KA_TRACE(100, (
"__kmp_free_task_and_ancestors: T#%d cleans "
731 "dephash of implicit task %p\n",
734 __kmp_dephash_free_entries(thread, taskdata->td_dephash);
741 children = KMP_ATOMIC_DEC(&taskdata->td_allocated_child_tasks) - 1;
742 KMP_DEBUG_ASSERT(children >= 0);
746 20, (
"__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
747 "not freeing it yet\n",
748 gtid, taskdata, children));
759static bool __kmp_track_children_task(kmp_taskdata_t *taskdata) {
760 kmp_tasking_flags_t flags = taskdata->td_flags;
761 bool ret = !(flags.team_serial || flags.tasking_ser);
762 ret = ret || flags.proxy == TASK_PROXY ||
763 flags.detachable == TASK_DETACHABLE || flags.hidden_helper;
765 KMP_ATOMIC_LD_ACQ(&taskdata->td_parent->td_incomplete_child_tasks) > 0;
779static void __kmp_task_finish(kmp_int32 gtid, kmp_task_t *task,
780 kmp_taskdata_t *resumed_task) {
781 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
782 kmp_info_t *thread = __kmp_threads[gtid];
783 kmp_task_team_t *task_team =
784 thread->th.th_task_team;
786 kmp_int32 children = 0;
788 KA_TRACE(10, (
"__kmp_task_finish(enter): T#%d finishing task %p and resuming "
790 gtid, taskdata, resumed_task));
792 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
794 if (UNLIKELY(taskdata->td_flags.tiedness == TASK_UNTIED)) {
797 kmp_int32 counter = KMP_ATOMIC_DEC(&taskdata->td_untied_count) - 1;
800 (
"__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n",
801 gtid, counter, taskdata));
805 if (resumed_task == NULL) {
806 KMP_DEBUG_ASSERT(taskdata->td_flags.task_serial);
807 resumed_task = taskdata->td_parent;
810 thread->th.th_current_task = resumed_task;
811 resumed_task->td_flags.executing = 1;
812 KA_TRACE(10, (
"__kmp_task_finish(exit): T#%d partially done task %p, "
813 "resuming task %p\n",
814 gtid, taskdata, resumed_task));
822 (taskdata->td_flags.tasking_ser || taskdata->td_flags.task_serial) ==
823 taskdata->td_flags.task_serial);
824 if (taskdata->td_flags.task_serial) {
825 if (resumed_task == NULL) {
826 resumed_task = taskdata->td_parent;
830 KMP_DEBUG_ASSERT(resumed_task !=
840 if (UNLIKELY(taskdata->td_flags.destructors_thunk)) {
841 kmp_routine_entry_t destr_thunk = task->data1.destructors;
842 KMP_ASSERT(destr_thunk);
843 destr_thunk(gtid, task);
846 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
847 KMP_DEBUG_ASSERT(taskdata->td_flags.started == 1);
848 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
850 bool completed =
true;
851 if (UNLIKELY(taskdata->td_flags.detachable == TASK_DETACHABLE)) {
852 if (taskdata->td_allow_completion_event.type ==
853 KMP_EVENT_ALLOW_COMPLETION) {
855 __kmp_acquire_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
856 if (taskdata->td_allow_completion_event.type ==
857 KMP_EVENT_ALLOW_COMPLETION) {
859 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 1);
860 taskdata->td_flags.executing = 0;
867 __ompt_task_finish(task, resumed_task, ompt_task_detach);
873 taskdata->td_flags.proxy = TASK_PROXY;
876 __kmp_release_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
881 if (taskdata->td_target_data.async_handle != NULL) {
887 __ompt_task_finish(task, resumed_task, ompt_task_switch);
890 __kmpc_give_task(task, __kmp_tid_from_gtid(gtid));
891 if (KMP_HIDDEN_HELPER_THREAD(gtid))
892 __kmp_hidden_helper_worker_thread_signal();
897 taskdata->td_flags.complete = 1;
902 __ompt_task_finish(task, resumed_task, ompt_task_complete);
906 if (__kmp_track_children_task(taskdata)) {
907 __kmp_release_deps(gtid, taskdata);
912 KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks);
913 KMP_DEBUG_ASSERT(children >= 0);
914 if (taskdata->td_taskgroup)
915 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
916 }
else if (task_team && (task_team->tt.tt_found_proxy_tasks ||
917 task_team->tt.tt_hidden_helper_task_encountered)) {
920 __kmp_release_deps(gtid, taskdata);
926 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 1);
927 taskdata->td_flags.executing = 0;
930 if (taskdata->td_flags.hidden_helper) {
932 KMP_ASSERT(KMP_HIDDEN_HELPER_THREAD(gtid));
933 KMP_ATOMIC_DEC(&__kmp_unexecuted_hidden_helper_tasks);
938 20, (
"__kmp_task_finish: T#%d finished task %p, %d incomplete children\n",
939 gtid, taskdata, children));
945 thread->th.th_current_task = resumed_task;
947 __kmp_free_task_and_ancestors(gtid, taskdata, thread);
951 resumed_task->td_flags.executing = 1;
954 10, (
"__kmp_task_finish(exit): T#%d finished task %p, resuming task %p\n",
955 gtid, taskdata, resumed_task));
961static void __kmpc_omp_task_complete_if0_template(
ident_t *loc_ref,
964 KA_TRACE(10, (
"__kmpc_omp_task_complete_if0(enter): T#%d loc=%p task=%p\n",
965 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task)));
966 KMP_DEBUG_ASSERT(gtid >= 0);
968 __kmp_task_finish<ompt>(gtid, task, NULL);
970 KA_TRACE(10, (
"__kmpc_omp_task_complete_if0(exit): T#%d loc=%p task=%p\n",
971 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task)));
975 ompt_frame_t *ompt_frame;
976 __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
977 ompt_frame->enter_frame = ompt_data_none;
978 ompt_frame->enter_frame_flags = OMPT_FRAME_FLAGS_RUNTIME;
987void __kmpc_omp_task_complete_if0_ompt(
ident_t *loc_ref, kmp_int32 gtid,
989 __kmpc_omp_task_complete_if0_template<true>(loc_ref, gtid, task);
998void __kmpc_omp_task_complete_if0(
ident_t *loc_ref, kmp_int32 gtid,
1001 if (UNLIKELY(ompt_enabled.enabled)) {
1002 __kmpc_omp_task_complete_if0_ompt(loc_ref, gtid, task);
1006 __kmpc_omp_task_complete_if0_template<false>(loc_ref, gtid, task);
1012void __kmpc_omp_task_complete(
ident_t *loc_ref, kmp_int32 gtid,
1014 KA_TRACE(10, (
"__kmpc_omp_task_complete(enter): T#%d loc=%p task=%p\n", gtid,
1015 loc_ref, KMP_TASK_TO_TASKDATA(task)));
1017 __kmp_task_finish<false>(gtid, task,
1020 KA_TRACE(10, (
"__kmpc_omp_task_complete(exit): T#%d loc=%p task=%p\n", gtid,
1021 loc_ref, KMP_TASK_TO_TASKDATA(task)));
1037void __kmp_init_implicit_task(
ident_t *loc_ref, kmp_info_t *this_thr,
1038 kmp_team_t *team,
int tid,
int set_curr_task) {
1039 kmp_taskdata_t *task = &team->t.t_implicit_task_taskdata[tid];
1043 (
"__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n",
1044 tid, team, task, set_curr_task ?
"TRUE" :
"FALSE"));
1046 task->td_task_id = KMP_GEN_TASK_ID();
1047 task->td_team = team;
1050 task->td_ident = loc_ref;
1051 task->td_taskwait_ident = NULL;
1052 task->td_taskwait_counter = 0;
1053 task->td_taskwait_thread = 0;
1055 task->td_flags.tiedness = TASK_TIED;
1056 task->td_flags.tasktype = TASK_IMPLICIT;
1057 task->td_flags.proxy = TASK_FULL;
1060 task->td_flags.task_serial = 1;
1061 task->td_flags.tasking_ser = (__kmp_tasking_mode == tskm_immediate_exec);
1062 task->td_flags.team_serial = (team->t.t_serialized) ? 1 : 0;
1064 task->td_flags.started = 1;
1065 task->td_flags.executing = 1;
1066 task->td_flags.complete = 0;
1067 task->td_flags.freed = 0;
1069 task->td_depnode = NULL;
1070 task->td_last_tied = task;
1071 task->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
1073 if (set_curr_task) {
1074 KMP_ATOMIC_ST_REL(&task->td_incomplete_child_tasks, 0);
1076 KMP_ATOMIC_ST_REL(&task->td_allocated_child_tasks, 0);
1077 task->td_taskgroup = NULL;
1078 task->td_dephash = NULL;
1079 __kmp_push_current_task_to_thread(this_thr, team, tid);
1081 KMP_DEBUG_ASSERT(task->td_incomplete_child_tasks == 0);
1082 KMP_DEBUG_ASSERT(task->td_allocated_child_tasks == 0);
1086 if (UNLIKELY(ompt_enabled.enabled))
1087 __ompt_task_init(task, tid);
1090 KF_TRACE(10, (
"__kmp_init_implicit_task(exit): T#:%d team=%p task=%p\n", tid,
1099void __kmp_finish_implicit_task(kmp_info_t *thread) {
1100 kmp_taskdata_t *task = thread->th.th_current_task;
1101#if ENABLE_LIBOMPTARGET
1104 if (UNLIKELY(kmp_target_sync_cb != NULL))
1105 (*kmp_target_sync_cb)(NULL, thread->th.th_info.ds.ds_gtid,
1106 KMP_TASKDATA_TO_TASK(task), NULL);
1108 if (task->td_dephash) {
1110 task->td_flags.complete = 1;
1111 children = KMP_ATOMIC_LD_ACQ(&task->td_incomplete_child_tasks);
1112 kmp_tasking_flags_t flags_old = task->td_flags;
1113 if (children == 0 && flags_old.complete == 1) {
1114 kmp_tasking_flags_t flags_new = flags_old;
1115 flags_new.complete = 0;
1116 if (KMP_COMPARE_AND_STORE_ACQ32(RCAST(kmp_int32 *, &task->td_flags),
1117 *RCAST(kmp_int32 *, &flags_old),
1118 *RCAST(kmp_int32 *, &flags_new))) {
1119 KA_TRACE(100, (
"__kmp_finish_implicit_task: T#%d cleans "
1120 "dephash of implicit task %p\n",
1121 thread->th.th_info.ds.ds_gtid, task));
1122 __kmp_dephash_free_entries(thread, task->td_dephash);
1132void __kmp_free_implicit_task(kmp_info_t *thread) {
1133 kmp_taskdata_t *task = thread->th.th_current_task;
1134 if (task && task->td_dephash) {
1135 __kmp_dephash_free(thread, task->td_dephash);
1136 task->td_dephash = NULL;
1142static size_t __kmp_round_up_to_val(
size_t size,
size_t val) {
1143 if (size & (val - 1)) {
1145 if (size <= KMP_SIZE_T_MAX - val) {
1164kmp_task_t *__kmp_task_alloc(
ident_t *loc_ref, kmp_int32 gtid,
1165 kmp_tasking_flags_t *flags,
1166 size_t sizeof_kmp_task_t,
size_t sizeof_shareds,
1167 kmp_routine_entry_t task_entry) {
1169 kmp_taskdata_t *taskdata;
1170 kmp_info_t *thread = __kmp_threads[gtid];
1171 kmp_team_t *team = thread->th.th_team;
1172 kmp_taskdata_t *parent_task = thread->th.th_current_task;
1173 size_t shareds_offset;
1175 if (UNLIKELY(!TCR_4(__kmp_init_middle)))
1176 __kmp_middle_initialize();
1178 if (flags->hidden_helper) {
1179 if (__kmp_enable_hidden_helper) {
1180 if (!TCR_4(__kmp_init_hidden_helper))
1181 __kmp_hidden_helper_initialize();
1184 flags->hidden_helper = FALSE;
1188 KA_TRACE(10, (
"__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "
1189 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
1190 gtid, loc_ref, *((kmp_int32 *)flags), sizeof_kmp_task_t,
1191 sizeof_shareds, task_entry));
1193 KMP_DEBUG_ASSERT(parent_task);
1194 if (parent_task->td_flags.final) {
1195 if (flags->merged_if0) {
1200 if (flags->tiedness == TASK_UNTIED && !team->t.t_serialized) {
1204 KMP_CHECK_UPDATE(thread->th.th_task_team->tt.tt_untied_task_encountered, 1);
1210 if (UNLIKELY(flags->proxy == TASK_PROXY ||
1211 flags->detachable == TASK_DETACHABLE || flags->hidden_helper)) {
1212 if (flags->proxy == TASK_PROXY) {
1213 flags->tiedness = TASK_UNTIED;
1214 flags->merged_if0 = 1;
1218 if ((thread->th.th_task_team) == NULL) {
1221 KMP_DEBUG_ASSERT(team->t.t_serialized);
1223 (
"T#%d creating task team in __kmp_task_alloc for proxy task\n",
1225 __kmp_task_team_setup(thread, team);
1226 thread->th.th_task_team = team->t.t_task_team[thread->th.th_task_state];
1228 kmp_task_team_t *task_team = thread->th.th_task_team;
1231 if (!KMP_TASKING_ENABLED(task_team)) {
1234 (
"T#%d enabling tasking in __kmp_task_alloc for proxy task\n", gtid));
1235 __kmp_enable_tasking(task_team, thread);
1236 kmp_int32 tid = thread->th.th_info.ds.ds_tid;
1237 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[tid];
1239 if (thread_data->td.td_deque == NULL) {
1240 __kmp_alloc_task_deque(thread, thread_data);
1244 if ((flags->proxy == TASK_PROXY || flags->detachable == TASK_DETACHABLE) &&
1245 task_team->tt.tt_found_proxy_tasks == FALSE)
1246 TCW_4(task_team->tt.tt_found_proxy_tasks, TRUE);
1247 if (flags->hidden_helper &&
1248 task_team->tt.tt_hidden_helper_task_encountered == FALSE)
1249 TCW_4(task_team->tt.tt_hidden_helper_task_encountered, TRUE);
1254 shareds_offset =
sizeof(kmp_taskdata_t) + sizeof_kmp_task_t;
1255 shareds_offset = __kmp_round_up_to_val(shareds_offset,
sizeof(kmp_uint64));
1258 KA_TRACE(30, (
"__kmp_task_alloc: T#%d First malloc size: %ld\n", gtid,
1260 KA_TRACE(30, (
"__kmp_task_alloc: T#%d Second malloc size: %ld\n", gtid,
1265 taskdata = (kmp_taskdata_t *)__kmp_fast_allocate(thread, shareds_offset +
1268 taskdata = (kmp_taskdata_t *)__kmp_thread_malloc(thread, shareds_offset +
1272 task = KMP_TASKDATA_TO_TASK(taskdata);
1275#if KMP_ARCH_X86 || KMP_ARCH_PPC64 || KMP_ARCH_S390X || !KMP_HAVE_QUAD
1276 KMP_DEBUG_ASSERT((((kmp_uintptr_t)taskdata) & (
sizeof(
double) - 1)) == 0);
1277 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task) & (
sizeof(
double) - 1)) == 0);
1279 KMP_DEBUG_ASSERT((((kmp_uintptr_t)taskdata) & (
sizeof(_Quad) - 1)) == 0);
1280 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task) & (
sizeof(_Quad) - 1)) == 0);
1282 if (sizeof_shareds > 0) {
1284 task->shareds = &((
char *)taskdata)[shareds_offset];
1286 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task->shareds) & (
sizeof(
void *) - 1)) ==
1289 task->shareds = NULL;
1291 task->routine = task_entry;
1294 taskdata->td_task_id = KMP_GEN_TASK_ID();
1295 taskdata->td_team = thread->th.th_team;
1296 taskdata->td_alloc_thread = thread;
1297 taskdata->td_parent = parent_task;
1298 taskdata->td_level = parent_task->td_level + 1;
1299 KMP_ATOMIC_ST_RLX(&taskdata->td_untied_count, 0);
1300 taskdata->td_ident = loc_ref;
1301 taskdata->td_taskwait_ident = NULL;
1302 taskdata->td_taskwait_counter = 0;
1303 taskdata->td_taskwait_thread = 0;
1304 KMP_DEBUG_ASSERT(taskdata->td_parent != NULL);
1306 if (flags->proxy == TASK_FULL)
1307 copy_icvs(&taskdata->td_icvs, &taskdata->td_parent->td_icvs);
1309 taskdata->td_flags = *flags;
1310 taskdata->td_task_team = thread->th.th_task_team;
1311 taskdata->td_size_alloc = shareds_offset + sizeof_shareds;
1312 taskdata->td_flags.tasktype = TASK_EXPLICIT;
1315 if (flags->hidden_helper) {
1316 kmp_info_t *shadow_thread = __kmp_threads[KMP_GTID_TO_SHADOW_GTID(gtid)];
1317 taskdata->td_team = shadow_thread->th.th_team;
1318 taskdata->td_task_team = shadow_thread->th.th_task_team;
1322 taskdata->td_flags.tasking_ser = (__kmp_tasking_mode == tskm_immediate_exec);
1325 taskdata->td_flags.team_serial = (team->t.t_serialized) ? 1 : 0;
1331 taskdata->td_flags.task_serial =
1332 (parent_task->td_flags.final || taskdata->td_flags.team_serial ||
1333 taskdata->td_flags.tasking_ser || flags->merged_if0);
1335 taskdata->td_flags.started = 0;
1336 taskdata->td_flags.executing = 0;
1337 taskdata->td_flags.complete = 0;
1338 taskdata->td_flags.freed = 0;
1339 KMP_ATOMIC_ST_RLX(&taskdata->td_incomplete_child_tasks, 0);
1341 KMP_ATOMIC_ST_RLX(&taskdata->td_allocated_child_tasks, 1);
1342 taskdata->td_taskgroup =
1343 parent_task->td_taskgroup;
1344 taskdata->td_dephash = NULL;
1345 taskdata->td_depnode = NULL;
1346 taskdata->td_target_data.async_handle = NULL;
1347 if (flags->tiedness == TASK_UNTIED)
1348 taskdata->td_last_tied = NULL;
1350 taskdata->td_last_tied = taskdata;
1351 taskdata->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
1353 if (UNLIKELY(ompt_enabled.enabled))
1354 __ompt_task_init(taskdata, gtid);
1358 if (__kmp_track_children_task(taskdata)) {
1359 KMP_ATOMIC_INC(&parent_task->td_incomplete_child_tasks);
1360 if (parent_task->td_taskgroup)
1361 KMP_ATOMIC_INC(&parent_task->td_taskgroup->count);
1364 if (taskdata->td_parent->td_flags.tasktype == TASK_EXPLICIT) {
1365 KMP_ATOMIC_INC(&taskdata->td_parent->td_allocated_child_tasks);
1367 if (flags->hidden_helper) {
1368 taskdata->td_flags.task_serial = FALSE;
1370 KMP_ATOMIC_INC(&__kmp_unexecuted_hidden_helper_tasks);
1374 KA_TRACE(20, (
"__kmp_task_alloc(exit): T#%d created task %p parent=%p\n",
1375 gtid, taskdata, taskdata->td_parent));
1380kmp_task_t *__kmpc_omp_task_alloc(
ident_t *loc_ref, kmp_int32 gtid,
1381 kmp_int32 flags,
size_t sizeof_kmp_task_t,
1382 size_t sizeof_shareds,
1383 kmp_routine_entry_t task_entry) {
1385 kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
1386 __kmp_assert_valid_gtid(gtid);
1387 input_flags->native = FALSE;
1389 KA_TRACE(10, (
"__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s %s) "
1390 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
1391 gtid, loc_ref, input_flags->tiedness ?
"tied " :
"untied",
1392 input_flags->proxy ?
"proxy" :
"",
1393 input_flags->detachable ?
"detachable" :
"", sizeof_kmp_task_t,
1394 sizeof_shareds, task_entry));
1396 retval = __kmp_task_alloc(loc_ref, gtid, input_flags, sizeof_kmp_task_t,
1397 sizeof_shareds, task_entry);
1399 KA_TRACE(20, (
"__kmpc_omp_task_alloc(exit): T#%d retval %p\n", gtid, retval));
1404kmp_task_t *__kmpc_omp_target_task_alloc(
ident_t *loc_ref, kmp_int32 gtid,
1406 size_t sizeof_kmp_task_t,
1407 size_t sizeof_shareds,
1408 kmp_routine_entry_t task_entry,
1409 kmp_int64 device_id) {
1410 auto &input_flags =
reinterpret_cast<kmp_tasking_flags_t &
>(flags);
1412 input_flags.tiedness = TASK_UNTIED;
1413 input_flags.target = 1;
1415 if (__kmp_enable_hidden_helper)
1416 input_flags.hidden_helper = TRUE;
1418 return __kmpc_omp_task_alloc(loc_ref, gtid, flags, sizeof_kmp_task_t,
1419 sizeof_shareds, task_entry);
1437 kmp_task_t *new_task, kmp_int32 naffins,
1438 kmp_task_affinity_info_t *affin_list) {
1440 KMP_DEBUG_ASSERT(affin_list != NULL);
1442 for (kmp_int32 i = 0; i < naffins; ++i) {
1443 KA_TRACE(30, (
"__kmpc_omp_reg_task_with_affinity: T#%d aff[%d] "
1444 "base_addr=0x%llx len=%zu flags={%d,%d,%d}\n",
1445 gtid, i, (
unsigned long long)affin_list[i].base_addr,
1446 affin_list[i].len, (
int)affin_list[i].flags.flag1,
1447 (
int)affin_list[i].flags.flag2,
1448 (
int)affin_list[i].flags.reserved));
1460__attribute__((target(
"backchain")))
1463__kmp_invoke_task(kmp_int32 gtid, kmp_task_t *task,
1464 kmp_taskdata_t *current_task) {
1465 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
1469 30, (
"__kmp_invoke_task(enter): T#%d invoking task %p, current_task=%p\n",
1470 gtid, taskdata, current_task));
1471 KMP_DEBUG_ASSERT(task);
1472 if (UNLIKELY(taskdata->td_flags.proxy == TASK_PROXY &&
1473 taskdata->td_flags.complete == 1)) {
1478 (
"__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n",
1481 __kmp_bottom_half_finish_proxy(gtid, task);
1483 KA_TRACE(30, (
"__kmp_invoke_task(exit): T#%d completed bottom finish for "
1484 "proxy task %p, resuming task %p\n",
1485 gtid, taskdata, current_task));
1493 ompt_thread_info_t oldInfo;
1494 if (UNLIKELY(ompt_enabled.enabled)) {
1496 thread = __kmp_threads[gtid];
1497 oldInfo = thread->th.ompt_thread_info;
1498 thread->th.ompt_thread_info.wait_id = 0;
1499 thread->th.ompt_thread_info.state = (thread->th.th_team_serialized)
1500 ? ompt_state_work_serial
1501 : ompt_state_work_parallel;
1502 taskdata->ompt_task_info.frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1509 if (taskdata->td_flags.proxy != TASK_PROXY) {
1510 __kmp_task_start(gtid, task, current_task);
1516 if (UNLIKELY(__kmp_omp_cancellation)) {
1517 thread = __kmp_threads[gtid];
1518 kmp_team_t *this_team = thread->th.th_team;
1519 kmp_taskgroup_t *taskgroup = taskdata->td_taskgroup;
1520 if ((taskgroup && taskgroup->cancel_request) ||
1521 (this_team->t.t_cancel_request == cancel_parallel)) {
1522#if OMPT_SUPPORT && OMPT_OPTIONAL
1523 ompt_data_t *task_data;
1524 if (UNLIKELY(ompt_enabled.ompt_callback_cancel)) {
1525 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL, NULL);
1526 ompt_callbacks.ompt_callback(ompt_callback_cancel)(
1528 ((taskgroup && taskgroup->cancel_request) ? ompt_cancel_taskgroup
1529 : ompt_cancel_parallel) |
1530 ompt_cancel_discarded_task,
1543#if KMP_STATS_ENABLED
1545 switch (KMP_GET_THREAD_STATE()) {
1546 case FORK_JOIN_BARRIER:
1547 KMP_PUSH_PARTITIONED_TIMER(OMP_task_join_bar);
1550 KMP_PUSH_PARTITIONED_TIMER(OMP_task_plain_bar);
1553 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskyield);
1556 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskwait);
1559 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskgroup);
1562 KMP_PUSH_PARTITIONED_TIMER(OMP_task_immediate);
1569 if (UNLIKELY(ompt_enabled.enabled))
1570 __ompt_task_start(task, current_task, gtid);
1572#if OMPT_SUPPORT && OMPT_OPTIONAL
1573 if (UNLIKELY(ompt_enabled.ompt_callback_dispatch &&
1574 taskdata->ompt_task_info.dispatch_chunk.iterations > 0)) {
1575 ompt_data_t instance = ompt_data_none;
1576 instance.ptr = &(taskdata->ompt_task_info.dispatch_chunk);
1577 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
1578 ompt_callbacks.ompt_callback(ompt_callback_dispatch)(
1579 &(team_info->parallel_data), &(taskdata->ompt_task_info.task_data),
1580 ompt_dispatch_taskloop_chunk, instance);
1581 taskdata->ompt_task_info.dispatch_chunk = {0, 0};
1586 if (ompd_state & OMPD_ENABLE_BP)
1587 ompd_bp_task_begin();
1590#if USE_ITT_BUILD && USE_ITT_NOTIFY
1591 kmp_uint64 cur_time;
1592 kmp_int32 kmp_itt_count_task =
1593 __kmp_forkjoin_frames_mode == 3 && !taskdata->td_flags.task_serial &&
1594 current_task->td_flags.tasktype == TASK_IMPLICIT;
1595 if (kmp_itt_count_task) {
1596 thread = __kmp_threads[gtid];
1598 if (thread->th.th_bar_arrive_time)
1599 cur_time = __itt_get_timestamp();
1601 kmp_itt_count_task = 0;
1603 KMP_FSYNC_ACQUIRED(taskdata);
1606#if ENABLE_LIBOMPTARGET
1607 if (taskdata->td_target_data.async_handle != NULL) {
1611 KMP_ASSERT(tgt_target_nowait_query);
1612 tgt_target_nowait_query(&taskdata->td_target_data.async_handle);
1615 if (task->routine != NULL) {
1616#ifdef KMP_GOMP_COMPAT
1617 if (taskdata->td_flags.native) {
1618 ((void (*)(
void *))(*(task->routine)))(task->shareds);
1622 (*(task->routine))(gtid, task);
1625 KMP_POP_PARTITIONED_TIMER();
1627#if USE_ITT_BUILD && USE_ITT_NOTIFY
1628 if (kmp_itt_count_task) {
1630 thread->th.th_bar_arrive_time += (__itt_get_timestamp() - cur_time);
1632 KMP_FSYNC_CANCEL(taskdata);
1633 KMP_FSYNC_RELEASING(taskdata->td_parent);
1638 if (ompd_state & OMPD_ENABLE_BP)
1643 if (taskdata->td_flags.proxy != TASK_PROXY) {
1645 if (UNLIKELY(ompt_enabled.enabled)) {
1646 thread->th.ompt_thread_info = oldInfo;
1647 if (taskdata->td_flags.tiedness == TASK_TIED) {
1648 taskdata->ompt_task_info.frame.exit_frame = ompt_data_none;
1650 __kmp_task_finish<true>(gtid, task, current_task);
1653 __kmp_task_finish<false>(gtid, task, current_task);
1656 else if (UNLIKELY(ompt_enabled.enabled && taskdata->td_flags.target)) {
1657 __ompt_task_finish(task, current_task, ompt_task_switch);
1663 (
"__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n",
1664 gtid, taskdata, current_task));
1678kmp_int32 __kmpc_omp_task_parts(
ident_t *loc_ref, kmp_int32 gtid,
1679 kmp_task_t *new_task) {
1680 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1682 KA_TRACE(10, (
"__kmpc_omp_task_parts(enter): T#%d loc=%p task=%p\n", gtid,
1683 loc_ref, new_taskdata));
1686 kmp_taskdata_t *parent;
1687 if (UNLIKELY(ompt_enabled.enabled)) {
1688 parent = new_taskdata->td_parent;
1689 if (ompt_enabled.ompt_callback_task_create) {
1690 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
1691 &(parent->ompt_task_info.task_data), &(parent->ompt_task_info.frame),
1692 &(new_taskdata->ompt_task_info.task_data),
1693 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 0,
1694 OMPT_GET_RETURN_ADDRESS(0));
1702 if (__kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED)
1704 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
1705 new_taskdata->td_flags.task_serial = 1;
1706 __kmp_invoke_task(gtid, new_task, current_task);
1711 (
"__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
1712 "loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n",
1713 gtid, loc_ref, new_taskdata));
1716 if (UNLIKELY(ompt_enabled.enabled)) {
1717 parent->ompt_task_info.frame.enter_frame = ompt_data_none;
1718 parent->ompt_task_info.frame.enter_frame_flags = OMPT_FRAME_FLAGS_RUNTIME;
1721 return TASK_CURRENT_NOT_QUEUED;
1735kmp_int32 __kmp_omp_task(kmp_int32 gtid, kmp_task_t *new_task,
1736 bool serialize_immediate) {
1737 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1741 if (new_taskdata->td_flags.proxy == TASK_PROXY ||
1742 __kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED)
1744 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
1745 if (serialize_immediate)
1746 new_taskdata->td_flags.task_serial = 1;
1747 __kmp_invoke_task(gtid, new_task, current_task);
1748 }
else if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME &&
1749 __kmp_wpolicy_passive) {
1750 kmp_info_t *this_thr = __kmp_threads[gtid];
1751 kmp_team_t *team = this_thr->th.th_team;
1752 kmp_int32 nthreads = this_thr->th.th_team_nproc;
1753 for (
int i = 0; i < nthreads; ++i) {
1754 kmp_info_t *thread = team->t.t_threads[i];
1755 if (thread == this_thr)
1757 if (thread->th.th_sleep_loc != NULL) {
1758 __kmp_null_resume_wrapper(thread);
1763 return TASK_CURRENT_NOT_QUEUED;
1778kmp_int32 __kmpc_omp_task(
ident_t *loc_ref, kmp_int32 gtid,
1779 kmp_task_t *new_task) {
1781 KMP_SET_THREAD_STATE_BLOCK(EXPLICIT_TASK);
1783#if KMP_DEBUG || OMPT_SUPPORT
1784 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1786 KA_TRACE(10, (
"__kmpc_omp_task(enter): T#%d loc=%p task=%p\n", gtid, loc_ref,
1788 __kmp_assert_valid_gtid(gtid);
1791 kmp_taskdata_t *parent = NULL;
1792 if (UNLIKELY(ompt_enabled.enabled)) {
1793 if (!new_taskdata->td_flags.started) {
1794 OMPT_STORE_RETURN_ADDRESS(gtid);
1795 parent = new_taskdata->td_parent;
1796 if (!parent->ompt_task_info.frame.enter_frame.ptr) {
1797 parent->ompt_task_info.frame.enter_frame.ptr =
1798 OMPT_GET_FRAME_ADDRESS(0);
1800 if (ompt_enabled.ompt_callback_task_create) {
1801 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
1802 &(parent->ompt_task_info.task_data),
1803 &(parent->ompt_task_info.frame),
1804 &(new_taskdata->ompt_task_info.task_data),
1805 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 0,
1806 OMPT_LOAD_RETURN_ADDRESS(gtid));
1811 __ompt_task_finish(new_task,
1812 new_taskdata->ompt_task_info.scheduling_parent,
1814 new_taskdata->ompt_task_info.frame.exit_frame = ompt_data_none;
1819 res = __kmp_omp_task(gtid, new_task,
true);
1821 KA_TRACE(10, (
"__kmpc_omp_task(exit): T#%d returning "
1822 "TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n",
1823 gtid, loc_ref, new_taskdata));
1825 if (UNLIKELY(ompt_enabled.enabled && parent != NULL)) {
1826 parent->ompt_task_info.frame.enter_frame = ompt_data_none;
1845kmp_int32 __kmp_omp_taskloop_task(
ident_t *loc_ref, kmp_int32 gtid,
1846 kmp_task_t *new_task,
void *codeptr_ra) {
1848 KMP_SET_THREAD_STATE_BLOCK(EXPLICIT_TASK);
1850#if KMP_DEBUG || OMPT_SUPPORT
1851 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
1853 KA_TRACE(10, (
"__kmpc_omp_task(enter): T#%d loc=%p task=%p\n", gtid, loc_ref,
1857 kmp_taskdata_t *parent = NULL;
1858 if (UNLIKELY(ompt_enabled.enabled && !new_taskdata->td_flags.started)) {
1859 parent = new_taskdata->td_parent;
1860 if (!parent->ompt_task_info.frame.enter_frame.ptr)
1861 parent->ompt_task_info.frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1862 if (ompt_enabled.ompt_callback_task_create) {
1863 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
1864 &(parent->ompt_task_info.task_data), &(parent->ompt_task_info.frame),
1865 &(new_taskdata->ompt_task_info.task_data),
1866 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 0, codeptr_ra);
1871 res = __kmp_omp_task(gtid, new_task,
true);
1873 KA_TRACE(10, (
"__kmpc_omp_task(exit): T#%d returning "
1874 "TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n",
1875 gtid, loc_ref, new_taskdata));
1877 if (UNLIKELY(ompt_enabled.enabled && parent != NULL)) {
1878 parent->ompt_task_info.frame.enter_frame = ompt_data_none;
1885static kmp_int32 __kmpc_omp_taskwait_template(
ident_t *loc_ref, kmp_int32 gtid,
1886 void *frame_address,
1887 void *return_address) {
1888 kmp_taskdata_t *taskdata =
nullptr;
1890 int thread_finished = FALSE;
1891 KMP_SET_THREAD_STATE_BLOCK(TASKWAIT);
1893 KA_TRACE(10, (
"__kmpc_omp_taskwait(enter): T#%d loc=%p\n", gtid, loc_ref));
1894 KMP_DEBUG_ASSERT(gtid >= 0);
1896 if (__kmp_tasking_mode != tskm_immediate_exec) {
1897 thread = __kmp_threads[gtid];
1898 taskdata = thread->th.th_current_task;
1900#if OMPT_SUPPORT && OMPT_OPTIONAL
1901 ompt_data_t *my_task_data;
1902 ompt_data_t *my_parallel_data;
1905 my_task_data = &(taskdata->ompt_task_info.task_data);
1906 my_parallel_data = OMPT_CUR_TEAM_DATA(thread);
1908 taskdata->ompt_task_info.frame.enter_frame.ptr = frame_address;
1910 if (ompt_enabled.ompt_callback_sync_region) {
1911 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
1912 ompt_sync_region_taskwait, ompt_scope_begin, my_parallel_data,
1913 my_task_data, return_address);
1916 if (ompt_enabled.ompt_callback_sync_region_wait) {
1917 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
1918 ompt_sync_region_taskwait, ompt_scope_begin, my_parallel_data,
1919 my_task_data, return_address);
1924#if ENABLE_LIBOMPTARGET
1927 if (UNLIKELY(kmp_target_sync_cb))
1928 (*kmp_target_sync_cb)(loc_ref, gtid, KMP_TASKDATA_TO_TASK(taskdata),
1937 taskdata->td_taskwait_counter += 1;
1938 taskdata->td_taskwait_ident = loc_ref;
1939 taskdata->td_taskwait_thread = gtid + 1;
1942 void *itt_sync_obj = NULL;
1944 KMP_ITT_TASKWAIT_STARTING(itt_sync_obj);
1949 !taskdata->td_flags.team_serial && !taskdata->td_flags.final;
1951 must_wait = must_wait || (thread->th.th_task_team != NULL &&
1952 thread->th.th_task_team->tt.tt_found_proxy_tasks);
1956 (__kmp_enable_hidden_helper && thread->th.th_task_team != NULL &&
1957 thread->th.th_task_team->tt.tt_hidden_helper_task_encountered);
1960 kmp_flag_32<false, false> flag(
1961 RCAST(std::atomic<kmp_uint32> *,
1962 &(taskdata->td_incomplete_child_tasks)),
1964 while (KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks) != 0) {
1965 flag.execute_tasks(thread, gtid, FALSE,
1966 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj),
1967 __kmp_task_stealing_constraint);
1971 KMP_ITT_TASKWAIT_FINISHED(itt_sync_obj);
1972 KMP_FSYNC_ACQUIRED(taskdata);
1977 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
1979#if OMPT_SUPPORT && OMPT_OPTIONAL
1981 if (ompt_enabled.ompt_callback_sync_region_wait) {
1982 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
1983 ompt_sync_region_taskwait, ompt_scope_end, my_parallel_data,
1984 my_task_data, return_address);
1986 if (ompt_enabled.ompt_callback_sync_region) {
1987 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
1988 ompt_sync_region_taskwait, ompt_scope_end, my_parallel_data,
1989 my_task_data, return_address);
1991 taskdata->ompt_task_info.frame.enter_frame = ompt_data_none;
1996 KA_TRACE(10, (
"__kmpc_omp_taskwait(exit): T#%d task %p finished waiting, "
1997 "returning TASK_CURRENT_NOT_QUEUED\n",
2000 return TASK_CURRENT_NOT_QUEUED;
2003#if OMPT_SUPPORT && OMPT_OPTIONAL
2005static kmp_int32 __kmpc_omp_taskwait_ompt(
ident_t *loc_ref, kmp_int32 gtid,
2006 void *frame_address,
2007 void *return_address) {
2008 return __kmpc_omp_taskwait_template<true>(loc_ref, gtid, frame_address,
2015kmp_int32 __kmpc_omp_taskwait(
ident_t *loc_ref, kmp_int32 gtid) {
2016#if OMPT_SUPPORT && OMPT_OPTIONAL
2017 if (UNLIKELY(ompt_enabled.enabled)) {
2018 OMPT_STORE_RETURN_ADDRESS(gtid);
2019 return __kmpc_omp_taskwait_ompt(loc_ref, gtid, OMPT_GET_FRAME_ADDRESS(0),
2020 OMPT_LOAD_RETURN_ADDRESS(gtid));
2023 return __kmpc_omp_taskwait_template<false>(loc_ref, gtid, NULL, NULL);
2027kmp_int32 __kmpc_omp_taskyield(
ident_t *loc_ref, kmp_int32 gtid,
int end_part) {
2028 kmp_taskdata_t *taskdata = NULL;
2030 int thread_finished = FALSE;
2033 KMP_SET_THREAD_STATE_BLOCK(TASKYIELD);
2035 KA_TRACE(10, (
"__kmpc_omp_taskyield(enter): T#%d loc=%p end_part = %d\n",
2036 gtid, loc_ref, end_part));
2037 __kmp_assert_valid_gtid(gtid);
2039 if (__kmp_tasking_mode != tskm_immediate_exec && __kmp_init_parallel) {
2040 thread = __kmp_threads[gtid];
2041 taskdata = thread->th.th_current_task;
2048 taskdata->td_taskwait_counter += 1;
2049 taskdata->td_taskwait_ident = loc_ref;
2050 taskdata->td_taskwait_thread = gtid + 1;
2053 void *itt_sync_obj = NULL;
2055 KMP_ITT_TASKWAIT_STARTING(itt_sync_obj);
2058 if (!taskdata->td_flags.team_serial) {
2059 kmp_task_team_t *task_team = thread->th.th_task_team;
2060 if (task_team != NULL) {
2061 if (KMP_TASKING_ENABLED(task_team)) {
2063 if (UNLIKELY(ompt_enabled.enabled))
2064 thread->th.ompt_thread_info.ompt_task_yielded = 1;
2066 __kmp_execute_tasks_32(
2067 thread, gtid, (kmp_flag_32<> *)NULL, FALSE,
2068 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj),
2069 __kmp_task_stealing_constraint);
2071 if (UNLIKELY(ompt_enabled.enabled))
2072 thread->th.ompt_thread_info.ompt_task_yielded = 0;
2078 KMP_ITT_TASKWAIT_FINISHED(itt_sync_obj);
2083 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
2086 KA_TRACE(10, (
"__kmpc_omp_taskyield(exit): T#%d task %p resuming, "
2087 "returning TASK_CURRENT_NOT_QUEUED\n",
2090 return TASK_CURRENT_NOT_QUEUED;
2111 unsigned reserved31 : 31;
2191template <
typename T>
2192void *__kmp_task_reduction_init(
int gtid,
int num, T *data) {
2193 __kmp_assert_valid_gtid(gtid);
2194 kmp_info_t *thread = __kmp_threads[gtid];
2195 kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
2196 kmp_uint32 nth = thread->th.th_team_nproc;
2200 KMP_ASSERT(tg != NULL);
2201 KMP_ASSERT(data != NULL);
2202 KMP_ASSERT(num > 0);
2203 if (nth == 1 && !__kmp_enable_hidden_helper) {
2204 KA_TRACE(10, (
"__kmpc_task_reduction_init: T#%d, tg %p, exiting nth=1\n",
2208 KA_TRACE(10, (
"__kmpc_task_reduction_init: T#%d, taskgroup %p, #items %d\n",
2212 for (
int i = 0; i < num; ++i) {
2213 size_t size = data[i].reduce_size - 1;
2215 size += CACHE_LINE - size % CACHE_LINE;
2216 KMP_ASSERT(data[i].reduce_comb != NULL);
2219 arr[i].
flags = data[i].flags;
2223 __kmp_assign_orig<T>(arr[i], data[i]);
2224 if (!arr[i].flags.lazy_priv) {
2227 arr[i].
reduce_pend = (
char *)(arr[i].reduce_priv) + nth * size;
2228 if (arr[i].reduce_init != NULL) {
2230 for (
size_t j = 0; j < nth; ++j) {
2231 __kmp_call_init<T>(arr[i], j * size);
2238 arr[i].
reduce_priv = __kmp_allocate(nth *
sizeof(
void *));
2241 tg->reduce_data = (
void *)arr;
2242 tg->reduce_num_data = num;
2281template <
typename T>
2282void __kmp_task_reduction_init_copy(kmp_info_t *thr,
int num, T *data,
2283 kmp_taskgroup_t *tg,
void *reduce_data) {
2285 KA_TRACE(20, (
"__kmp_task_reduction_init_copy: Th %p, init taskgroup %p,"
2287 thr, tg, reduce_data));
2292 for (
int i = 0; i < num; ++i) {
2295 tg->reduce_data = (
void *)arr;
2296 tg->reduce_num_data = num;
2309 __kmp_assert_valid_gtid(gtid);
2310 kmp_info_t *thread = __kmp_threads[gtid];
2311 kmp_int32 nth = thread->th.th_team_nproc;
2315 kmp_taskgroup_t *tg = (kmp_taskgroup_t *)tskgrp;
2317 tg = thread->th.th_current_task->td_taskgroup;
2318 KMP_ASSERT(tg != NULL);
2321 kmp_int32 tid = thread->th.th_info.ds.ds_tid;
2323 KMP_ASSERT(data != NULL);
2324 while (tg != NULL) {
2326 num = tg->reduce_num_data;
2327 for (
int i = 0; i < num; ++i) {
2328 if (!arr[i].flags.lazy_priv) {
2329 if (data == arr[i].reduce_shar ||
2330 (data >= arr[i].reduce_priv && data < arr[i].reduce_pend))
2331 return (
char *)(arr[i].
reduce_priv) + tid * arr[i].reduce_size;
2334 void **p_priv = (
void **)(arr[i].reduce_priv);
2335 if (data == arr[i].reduce_shar)
2338 for (
int j = 0; j < nth; ++j)
2339 if (data == p_priv[j])
2343 if (p_priv[tid] == NULL) {
2345 p_priv[tid] = __kmp_allocate(arr[i].reduce_size);
2346 if (arr[i].reduce_init != NULL) {
2347 if (arr[i].reduce_orig != NULL) {
2349 p_priv[tid], arr[i].reduce_orig);
2351 ((void (*)(
void *))arr[i].
reduce_init)(p_priv[tid]);
2358 KMP_ASSERT(tg->parent);
2361 KMP_ASSERT2(0,
"Unknown task reduction item");
2367static void __kmp_task_reduction_fini(kmp_info_t *th, kmp_taskgroup_t *tg) {
2368 kmp_int32 nth = th->th.th_team_nproc;
2371 __kmp_enable_hidden_helper);
2374 kmp_int32 num = tg->reduce_num_data;
2375 for (
int i = 0; i < num; ++i) {
2377 void (*f_fini)(
void *) = (
void (*)(
void *))(arr[i].
reduce_fini);
2378 void (*f_comb)(
void *,
void *) =
2380 if (!arr[i].flags.lazy_priv) {
2383 for (
int j = 0; j < nth; ++j) {
2384 void *priv_data = (
char *)pr_data + j * size;
2385 f_comb(sh_data, priv_data);
2390 void **pr_data = (
void **)(arr[i].reduce_priv);
2391 for (
int j = 0; j < nth; ++j) {
2392 if (pr_data[j] != NULL) {
2393 f_comb(sh_data, pr_data[j]);
2396 __kmp_free(pr_data[j]);
2400 __kmp_free(arr[i].reduce_priv);
2402 __kmp_thread_free(th, arr);
2403 tg->reduce_data = NULL;
2404 tg->reduce_num_data = 0;
2410static void __kmp_task_reduction_clean(kmp_info_t *th, kmp_taskgroup_t *tg) {
2411 __kmp_thread_free(th, tg->reduce_data);
2412 tg->reduce_data = NULL;
2413 tg->reduce_num_data = 0;
2416template <
typename T>
2417void *__kmp_task_reduction_modifier_init(
ident_t *loc,
int gtid,
int is_ws,
2419 __kmp_assert_valid_gtid(gtid);
2420 kmp_info_t *thr = __kmp_threads[gtid];
2421 kmp_int32 nth = thr->th.th_team_nproc;
2422 __kmpc_taskgroup(loc, gtid);
2425 (
"__kmpc_reduction_modifier_init: T#%d, tg %p, exiting nth=1\n",
2426 gtid, thr->th.th_current_task->td_taskgroup));
2427 return (
void *)thr->th.th_current_task->td_taskgroup;
2429 kmp_team_t *team = thr->th.th_team;
2431 kmp_taskgroup_t *tg;
2432 reduce_data = KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[is_ws]);
2433 if (reduce_data == NULL &&
2434 __kmp_atomic_compare_store(&team->t.t_tg_reduce_data[is_ws], reduce_data,
2437 KMP_DEBUG_ASSERT(reduce_data == NULL);
2439 tg = (kmp_taskgroup_t *)__kmp_task_reduction_init<T>(gtid, num, data);
2443 KMP_DEBUG_ASSERT(KMP_ATOMIC_LD_RLX(&team->t.t_tg_fini_counter[0]) == 0);
2444 KMP_DEBUG_ASSERT(KMP_ATOMIC_LD_RLX(&team->t.t_tg_fini_counter[1]) == 0);
2445 KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[is_ws], reduce_data);
2448 (reduce_data = KMP_ATOMIC_LD_ACQ(&team->t.t_tg_reduce_data[is_ws])) ==
2452 KMP_DEBUG_ASSERT(reduce_data > (
void *)1);
2453 tg = thr->th.th_current_task->td_taskgroup;
2454 __kmp_task_reduction_init_copy<T>(thr, num, data, tg, reduce_data);
2476 int num,
void *data) {
2477 return __kmp_task_reduction_modifier_init(loc, gtid, is_ws, num,
2497 return __kmp_task_reduction_modifier_init(loc, gtid, is_ws, num,
2510 __kmpc_end_taskgroup(loc, gtid);
2514void __kmpc_taskgroup(
ident_t *loc,
int gtid) {
2515 __kmp_assert_valid_gtid(gtid);
2516 kmp_info_t *thread = __kmp_threads[gtid];
2517 kmp_taskdata_t *taskdata = thread->th.th_current_task;
2518 kmp_taskgroup_t *tg_new =
2519 (kmp_taskgroup_t *)__kmp_thread_malloc(thread,
sizeof(kmp_taskgroup_t));
2520 KA_TRACE(10, (
"__kmpc_taskgroup: T#%d loc=%p group=%p\n", gtid, loc, tg_new));
2521 KMP_ATOMIC_ST_RLX(&tg_new->count, 0);
2522 KMP_ATOMIC_ST_RLX(&tg_new->cancel_request, cancel_noreq);
2523 tg_new->parent = taskdata->td_taskgroup;
2524 tg_new->reduce_data = NULL;
2525 tg_new->reduce_num_data = 0;
2526 tg_new->gomp_data = NULL;
2527 taskdata->td_taskgroup = tg_new;
2529#if OMPT_SUPPORT && OMPT_OPTIONAL
2530 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region)) {
2531 void *codeptr = OMPT_LOAD_RETURN_ADDRESS(gtid);
2533 codeptr = OMPT_GET_RETURN_ADDRESS(0);
2534 kmp_team_t *team = thread->th.th_team;
2535 ompt_data_t my_task_data = taskdata->ompt_task_info.task_data;
2537 ompt_data_t my_parallel_data = team->t.ompt_team_info.parallel_data;
2539 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
2540 ompt_sync_region_taskgroup, ompt_scope_begin, &(my_parallel_data),
2541 &(my_task_data), codeptr);
2548void __kmpc_end_taskgroup(
ident_t *loc,
int gtid) {
2549 __kmp_assert_valid_gtid(gtid);
2550 kmp_info_t *thread = __kmp_threads[gtid];
2551 kmp_taskdata_t *taskdata = thread->th.th_current_task;
2552 kmp_taskgroup_t *taskgroup = taskdata->td_taskgroup;
2553 int thread_finished = FALSE;
2555#if OMPT_SUPPORT && OMPT_OPTIONAL
2557 ompt_data_t my_task_data;
2558 ompt_data_t my_parallel_data;
2559 void *codeptr =
nullptr;
2560 if (UNLIKELY(ompt_enabled.enabled)) {
2561 team = thread->th.th_team;
2562 my_task_data = taskdata->ompt_task_info.task_data;
2564 my_parallel_data = team->t.ompt_team_info.parallel_data;
2565 codeptr = OMPT_LOAD_RETURN_ADDRESS(gtid);
2567 codeptr = OMPT_GET_RETURN_ADDRESS(0);
2571 KA_TRACE(10, (
"__kmpc_end_taskgroup(enter): T#%d loc=%p\n", gtid, loc));
2572 KMP_DEBUG_ASSERT(taskgroup != NULL);
2573 KMP_SET_THREAD_STATE_BLOCK(TASKGROUP);
2575 if (__kmp_tasking_mode != tskm_immediate_exec) {
2577 taskdata->td_taskwait_counter += 1;
2578 taskdata->td_taskwait_ident = loc;
2579 taskdata->td_taskwait_thread = gtid + 1;
2583 void *itt_sync_obj = NULL;
2585 KMP_ITT_TASKWAIT_STARTING(itt_sync_obj);
2589#if OMPT_SUPPORT && OMPT_OPTIONAL
2590 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region_wait)) {
2591 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
2592 ompt_sync_region_taskgroup, ompt_scope_begin, &(my_parallel_data),
2593 &(my_task_data), codeptr);
2597#if ENABLE_LIBOMPTARGET
2600 if (UNLIKELY(kmp_target_sync_cb))
2601 (*kmp_target_sync_cb)(loc, gtid, KMP_TASKDATA_TO_TASK(taskdata), NULL);
2604 if (!taskdata->td_flags.team_serial ||
2605 (thread->th.th_task_team != NULL &&
2606 (thread->th.th_task_team->tt.tt_found_proxy_tasks ||
2607 thread->th.th_task_team->tt.tt_hidden_helper_task_encountered))) {
2608 kmp_flag_32<false, false> flag(
2609 RCAST(std::atomic<kmp_uint32> *, &(taskgroup->count)), 0U);
2610 while (KMP_ATOMIC_LD_ACQ(&taskgroup->count) != 0) {
2611 flag.execute_tasks(thread, gtid, FALSE,
2612 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj),
2613 __kmp_task_stealing_constraint);
2616 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
2618#if OMPT_SUPPORT && OMPT_OPTIONAL
2619 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region_wait)) {
2620 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)(
2621 ompt_sync_region_taskgroup, ompt_scope_end, &(my_parallel_data),
2622 &(my_task_data), codeptr);
2627 KMP_ITT_TASKWAIT_FINISHED(itt_sync_obj);
2628 KMP_FSYNC_ACQUIRED(taskdata);
2631 KMP_DEBUG_ASSERT(taskgroup->count == 0);
2633 if (taskgroup->reduce_data != NULL &&
2634 !taskgroup->gomp_data) {
2637 kmp_team_t *t = thread->th.th_team;
2641 if ((reduce_data = KMP_ATOMIC_LD_ACQ(&t->t.t_tg_reduce_data[0])) != NULL &&
2644 cnt = KMP_ATOMIC_INC(&t->t.t_tg_fini_counter[0]);
2645 if (cnt == thread->th.th_team_nproc - 1) {
2648 __kmp_task_reduction_fini(thread, taskgroup);
2651 __kmp_thread_free(thread, reduce_data);
2652 KMP_ATOMIC_ST_REL(&t->t.t_tg_reduce_data[0], NULL);
2653 KMP_ATOMIC_ST_REL(&t->t.t_tg_fini_counter[0], 0);
2657 __kmp_task_reduction_clean(thread, taskgroup);
2659 }
else if ((reduce_data = KMP_ATOMIC_LD_ACQ(&t->t.t_tg_reduce_data[1])) !=
2663 cnt = KMP_ATOMIC_INC(&t->t.t_tg_fini_counter[1]);
2664 if (cnt == thread->th.th_team_nproc - 1) {
2666 __kmp_task_reduction_fini(thread, taskgroup);
2669 __kmp_thread_free(thread, reduce_data);
2670 KMP_ATOMIC_ST_REL(&t->t.t_tg_reduce_data[1], NULL);
2671 KMP_ATOMIC_ST_REL(&t->t.t_tg_fini_counter[1], 0);
2675 __kmp_task_reduction_clean(thread, taskgroup);
2679 __kmp_task_reduction_fini(thread, taskgroup);
2683 taskdata->td_taskgroup = taskgroup->parent;
2684 __kmp_thread_free(thread, taskgroup);
2686 KA_TRACE(10, (
"__kmpc_end_taskgroup(exit): T#%d task %p finished waiting\n",
2689#if OMPT_SUPPORT && OMPT_OPTIONAL
2690 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region)) {
2691 ompt_callbacks.ompt_callback(ompt_callback_sync_region)(
2692 ompt_sync_region_taskgroup, ompt_scope_end, &(my_parallel_data),
2693 &(my_task_data), codeptr);
2698static kmp_task_t *__kmp_get_priority_task(kmp_int32 gtid,
2699 kmp_task_team_t *task_team,
2700 kmp_int32 is_constrained) {
2701 kmp_task_t *task = NULL;
2702 kmp_taskdata_t *taskdata;
2703 kmp_taskdata_t *current;
2704 kmp_thread_data_t *thread_data;
2705 int ntasks = task_team->tt.tt_num_task_pri;
2708 20, (
"__kmp_get_priority_task(exit #1): T#%d No tasks to get\n", gtid));
2713 if (__kmp_atomic_compare_store(&task_team->tt.tt_num_task_pri, ntasks,
2716 ntasks = task_team->tt.tt_num_task_pri;
2717 }
while (ntasks > 0);
2719 KA_TRACE(20, (
"__kmp_get_priority_task(exit #2): T#%d No tasks to get\n",
2725 kmp_task_pri_t *list = task_team->tt.tt_task_pri_list;
2727 KMP_ASSERT(list != NULL);
2728 thread_data = &list->td;
2729 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
2730 deque_ntasks = thread_data->td.td_deque_ntasks;
2731 if (deque_ntasks == 0) {
2732 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2733 KA_TRACE(20, (
"__kmp_get_priority_task: T#%d No tasks to get from %p\n",
2734 __kmp_get_gtid(), thread_data));
2737 }
while (deque_ntasks == 0);
2738 KMP_DEBUG_ASSERT(deque_ntasks);
2739 int target = thread_data->td.td_deque_head;
2740 current = __kmp_threads[gtid]->th.th_current_task;
2741 taskdata = thread_data->td.td_deque[target];
2742 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
2744 thread_data->td.td_deque_head =
2745 (target + 1) & TASK_DEQUE_MASK(thread_data->td);
2747 if (!task_team->tt.tt_untied_task_encountered) {
2749 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2750 KA_TRACE(20, (
"__kmp_get_priority_task(exit #3): T#%d could not get task "
2751 "from %p: task_team=%p ntasks=%d head=%u tail=%u\n",
2752 gtid, thread_data, task_team, deque_ntasks, target,
2753 thread_data->td.td_deque_tail));
2754 task_team->tt.tt_num_task_pri++;
2760 for (i = 1; i < deque_ntasks; ++i) {
2761 target = (target + 1) & TASK_DEQUE_MASK(thread_data->td);
2762 taskdata = thread_data->td.td_deque[target];
2763 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
2769 if (taskdata == NULL) {
2771 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2773 10, (
"__kmp_get_priority_task(exit #4): T#%d could not get task from "
2774 "%p: task_team=%p ntasks=%d head=%u tail=%u\n",
2775 gtid, thread_data, task_team, deque_ntasks,
2776 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2777 task_team->tt.tt_num_task_pri++;
2781 for (i = i + 1; i < deque_ntasks; ++i) {
2783 target = (target + 1) & TASK_DEQUE_MASK(thread_data->td);
2784 thread_data->td.td_deque[prev] = thread_data->td.td_deque[target];
2788 thread_data->td.td_deque_tail ==
2789 (kmp_uint32)((target + 1) & TASK_DEQUE_MASK(thread_data->td)));
2790 thread_data->td.td_deque_tail = target;
2792 thread_data->td.td_deque_ntasks = deque_ntasks - 1;
2793 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2794 task = KMP_TASKDATA_TO_TASK(taskdata);
2799static kmp_task_t *__kmp_remove_my_task(kmp_info_t *thread, kmp_int32 gtid,
2800 kmp_task_team_t *task_team,
2801 kmp_int32 is_constrained) {
2803 kmp_taskdata_t *taskdata;
2804 kmp_thread_data_t *thread_data;
2807 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
2808 KMP_DEBUG_ASSERT(task_team->tt.tt_threads_data !=
2811 thread_data = &task_team->tt.tt_threads_data[__kmp_tid_from_gtid(gtid)];
2813 KA_TRACE(10, (
"__kmp_remove_my_task(enter): T#%d ntasks=%d head=%u tail=%u\n",
2814 gtid, thread_data->td.td_deque_ntasks,
2815 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2817 if (TCR_4(thread_data->td.td_deque_ntasks) == 0) {
2819 (
"__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
2820 "ntasks=%d head=%u tail=%u\n",
2821 gtid, thread_data->td.td_deque_ntasks,
2822 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2826 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
2828 if (TCR_4(thread_data->td.td_deque_ntasks) == 0) {
2829 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2831 (
"__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
2832 "ntasks=%d head=%u tail=%u\n",
2833 gtid, thread_data->td.td_deque_ntasks,
2834 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2838 tail = (thread_data->td.td_deque_tail - 1) &
2839 TASK_DEQUE_MASK(thread_data->td);
2840 taskdata = thread_data->td.td_deque[tail];
2842 if (!__kmp_task_is_allowed(gtid, is_constrained, taskdata,
2843 thread->th.th_current_task)) {
2845 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2847 (
"__kmp_remove_my_task(exit #3): T#%d TSC blocks tail task: "
2848 "ntasks=%d head=%u tail=%u\n",
2849 gtid, thread_data->td.td_deque_ntasks,
2850 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2854 thread_data->td.td_deque_tail = tail;
2855 TCW_4(thread_data->td.td_deque_ntasks, thread_data->td.td_deque_ntasks - 1);
2857 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2859 KA_TRACE(10, (
"__kmp_remove_my_task(exit #4): T#%d task %p removed: "
2860 "ntasks=%d head=%u tail=%u\n",
2861 gtid, taskdata, thread_data->td.td_deque_ntasks,
2862 thread_data->td.td_deque_head, thread_data->td.td_deque_tail));
2864 task = KMP_TASKDATA_TO_TASK(taskdata);
2871static kmp_task_t *__kmp_steal_task(kmp_int32 victim_tid, kmp_int32 gtid,
2872 kmp_task_team_t *task_team,
2873 std::atomic<kmp_int32> *unfinished_threads,
2874 int *thread_finished,
2875 kmp_int32 is_constrained) {
2877 kmp_taskdata_t *taskdata;
2878 kmp_taskdata_t *current;
2879 kmp_thread_data_t *victim_td, *threads_data;
2881 kmp_info_t *victim_thr;
2883 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
2885 threads_data = task_team->tt.tt_threads_data;
2886 KMP_DEBUG_ASSERT(threads_data != NULL);
2887 KMP_DEBUG_ASSERT(victim_tid >= 0);
2888 KMP_DEBUG_ASSERT(victim_tid < task_team->tt.tt_max_threads);
2890 victim_td = &threads_data[victim_tid];
2891 victim_thr = victim_td->td.td_thr;
2894 KA_TRACE(10, (
"__kmp_steal_task(enter): T#%d try to steal from T#%d: "
2895 "task_team=%p ntasks=%d head=%u tail=%u\n",
2896 gtid, __kmp_gtid_from_thread(victim_thr), task_team,
2897 victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head,
2898 victim_td->td.td_deque_tail));
2900 if (TCR_4(victim_td->td.td_deque_ntasks) == 0) {
2901 KA_TRACE(10, (
"__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
2902 "task_team=%p ntasks=%d head=%u tail=%u\n",
2903 gtid, __kmp_gtid_from_thread(victim_thr), task_team,
2904 victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head,
2905 victim_td->td.td_deque_tail));
2909 __kmp_acquire_bootstrap_lock(&victim_td->td.td_deque_lock);
2911 int ntasks = TCR_4(victim_td->td.td_deque_ntasks);
2914 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2915 KA_TRACE(10, (
"__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "
2916 "task_team=%p ntasks=%d head=%u tail=%u\n",
2917 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,
2918 victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
2922 KMP_DEBUG_ASSERT(victim_td->td.td_deque != NULL);
2923 current = __kmp_threads[gtid]->th.th_current_task;
2924 taskdata = victim_td->td.td_deque[victim_td->td.td_deque_head];
2925 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
2927 victim_td->td.td_deque_head =
2928 (victim_td->td.td_deque_head + 1) & TASK_DEQUE_MASK(victim_td->td);
2930 if (!task_team->tt.tt_untied_task_encountered) {
2932 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2933 KA_TRACE(10, (
"__kmp_steal_task(exit #3): T#%d could not steal from "
2934 "T#%d: task_team=%p ntasks=%d head=%u tail=%u\n",
2935 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,
2936 victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
2941 target = victim_td->td.td_deque_head;
2943 for (i = 1; i < ntasks; ++i) {
2944 target = (target + 1) & TASK_DEQUE_MASK(victim_td->td);
2945 taskdata = victim_td->td.td_deque[target];
2946 if (__kmp_task_is_allowed(gtid, is_constrained, taskdata, current)) {
2952 if (taskdata == NULL) {
2954 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2955 KA_TRACE(10, (
"__kmp_steal_task(exit #4): T#%d could not steal from "
2956 "T#%d: task_team=%p ntasks=%d head=%u tail=%u\n",
2957 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,
2958 victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
2962 for (i = i + 1; i < ntasks; ++i) {
2964 target = (target + 1) & TASK_DEQUE_MASK(victim_td->td);
2965 victim_td->td.td_deque[prev] = victim_td->td.td_deque[target];
2969 victim_td->td.td_deque_tail ==
2970 (kmp_uint32)((target + 1) & TASK_DEQUE_MASK(victim_td->td)));
2971 victim_td->td.td_deque_tail = target;
2973 if (*thread_finished) {
2980 KMP_ATOMIC_INC(unfinished_threads);
2983 (
"__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n",
2984 gtid, count + 1, task_team));
2985 *thread_finished = FALSE;
2987 TCW_4(victim_td->td.td_deque_ntasks, ntasks - 1);
2989 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2993 (
"__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
2994 "task_team=%p ntasks=%d head=%u tail=%u\n",
2995 gtid, taskdata, __kmp_gtid_from_thread(victim_thr), task_team,
2996 ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail));
2998 task = KMP_TASKDATA_TO_TASK(taskdata);
3012static inline int __kmp_execute_tasks_template(
3013 kmp_info_t *thread, kmp_int32 gtid, C *flag,
int final_spin,
3014 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3015 kmp_int32 is_constrained) {
3016 kmp_task_team_t *task_team = thread->th.th_task_team;
3017 kmp_thread_data_t *threads_data;
3019 kmp_info_t *other_thread;
3020 kmp_taskdata_t *current_task = thread->th.th_current_task;
3021 std::atomic<kmp_int32> *unfinished_threads;
3022 kmp_int32 nthreads, victim_tid = -2, use_own_tasks = 1, new_victim = 0,
3023 tid = thread->th.th_info.ds.ds_tid;
3025 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3026 KMP_DEBUG_ASSERT(thread == __kmp_threads[gtid]);
3028 if (task_team == NULL || current_task == NULL)
3031 KA_TRACE(15, (
"__kmp_execute_tasks_template(enter): T#%d final_spin=%d "
3032 "*thread_finished=%d\n",
3033 gtid, final_spin, *thread_finished));
3035 thread->th.th_reap_state = KMP_NOT_SAFE_TO_REAP;
3036 threads_data = (kmp_thread_data_t *)TCR_PTR(task_team->tt.tt_threads_data);
3038 KMP_DEBUG_ASSERT(threads_data != NULL);
3040 nthreads = task_team->tt.tt_nproc;
3041 unfinished_threads = &(task_team->tt.tt_unfinished_threads);
3042 KMP_DEBUG_ASSERT(*unfinished_threads >= 0);
3047#if ENABLE_LIBOMPTARGET
3049 if (UNLIKELY(kmp_target_sync_cb))
3050 (*kmp_target_sync_cb)(NULL, gtid, KMP_TASKDATA_TO_TASK(current_task),
3055 if (task_team->tt.tt_num_task_pri) {
3056 task = __kmp_get_priority_task(gtid, task_team, is_constrained);
3058 if (task == NULL && use_own_tasks) {
3059 task = __kmp_remove_my_task(thread, gtid, task_team, is_constrained);
3061 if ((task == NULL) && (nthreads > 1)) {
3065 if (victim_tid == -2) {
3066 victim_tid = threads_data[tid].td.td_deque_last_stolen;
3069 other_thread = threads_data[victim_tid].td.td_thr;
3071 if (victim_tid != -1) {
3073 }
else if (!new_victim) {
3079 victim_tid = __kmp_get_random(thread) % (nthreads - 1);
3080 if (victim_tid >= tid) {
3084 other_thread = threads_data[victim_tid].td.td_thr;
3094 if ((__kmp_tasking_mode == tskm_task_teams) &&
3095 (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME) &&
3096 (TCR_PTR(CCAST(
void *, other_thread->th.th_sleep_loc)) !=
3099 __kmp_null_resume_wrapper(other_thread);
3113 __kmp_steal_task(victim_tid, gtid, task_team, unfinished_threads,
3114 thread_finished, is_constrained);
3117 if (threads_data[tid].td.td_deque_last_stolen != victim_tid) {
3118 threads_data[tid].td.td_deque_last_stolen = victim_tid;
3125 KMP_CHECK_UPDATE(threads_data[tid].td.td_deque_last_stolen, -1);
3134#if USE_ITT_BUILD && USE_ITT_NOTIFY
3135 if (__itt_sync_create_ptr || KMP_ITT_DEBUG) {
3136 if (itt_sync_obj == NULL) {
3138 itt_sync_obj = __kmp_itt_barrier_object(gtid, bs_forkjoin_barrier);
3140 __kmp_itt_task_starting(itt_sync_obj);
3143 __kmp_invoke_task(gtid, task, current_task);
3145 if (itt_sync_obj != NULL)
3146 __kmp_itt_task_finished(itt_sync_obj);
3153 if (flag == NULL || (!final_spin && flag->done_check())) {
3156 (
"__kmp_execute_tasks_template: T#%d spin condition satisfied\n",
3160 if (thread->th.th_task_team == NULL) {
3163 KMP_YIELD(__kmp_library == library_throughput);
3166 if (!use_own_tasks && TCR_4(threads_data[tid].td.td_deque_ntasks) != 0) {
3167 KA_TRACE(20, (
"__kmp_execute_tasks_template: T#%d stolen task spawned "
3168 "other tasks, restart\n",
3179 KMP_ATOMIC_LD_ACQ(¤t_task->td_incomplete_child_tasks) == 0) {
3183 if (!*thread_finished) {
3185 kmp_int32 count = -1 +
3187 KMP_ATOMIC_DEC(unfinished_threads);
3188 KA_TRACE(20, (
"__kmp_execute_tasks_template: T#%d dec "
3189 "unfinished_threads to %d task_team=%p\n",
3190 gtid, count, task_team));
3191 *thread_finished = TRUE;
3199 if (flag != NULL && flag->done_check()) {
3202 (
"__kmp_execute_tasks_template: T#%d spin condition satisfied\n",
3210 if (thread->th.th_task_team == NULL) {
3212 (
"__kmp_execute_tasks_template: T#%d no more tasks\n", gtid));
3221 if (flag == NULL || (!final_spin && flag->done_check())) {
3223 (
"__kmp_execute_tasks_template: T#%d spin condition satisfied\n",
3230 if (nthreads == 1 &&
3231 KMP_ATOMIC_LD_ACQ(¤t_task->td_incomplete_child_tasks))
3235 (
"__kmp_execute_tasks_template: T#%d can't find work\n", gtid));
3241template <
bool C,
bool S>
3242int __kmp_execute_tasks_32(
3243 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_32<C, S> *flag,
int final_spin,
3244 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3245 kmp_int32 is_constrained) {
3246 return __kmp_execute_tasks_template(
3247 thread, gtid, flag, final_spin,
3248 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3251template <
bool C,
bool S>
3252int __kmp_execute_tasks_64(
3253 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_64<C, S> *flag,
int final_spin,
3254 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3255 kmp_int32 is_constrained) {
3256 return __kmp_execute_tasks_template(
3257 thread, gtid, flag, final_spin,
3258 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3261template <
bool C,
bool S>
3262int __kmp_atomic_execute_tasks_64(
3263 kmp_info_t *thread, kmp_int32 gtid, kmp_atomic_flag_64<C, S> *flag,
3264 int final_spin,
int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3265 kmp_int32 is_constrained) {
3266 return __kmp_execute_tasks_template(
3267 thread, gtid, flag, final_spin,
3268 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3271int __kmp_execute_tasks_oncore(
3272 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_oncore *flag,
int final_spin,
3273 int *thread_finished USE_ITT_BUILD_ARG(
void *itt_sync_obj),
3274 kmp_int32 is_constrained) {
3275 return __kmp_execute_tasks_template(
3276 thread, gtid, flag, final_spin,
3277 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained);
3281__kmp_execute_tasks_32<false, false>(kmp_info_t *, kmp_int32,
3282 kmp_flag_32<false, false> *,
int,
3283 int *USE_ITT_BUILD_ARG(
void *), kmp_int32);
3285template int __kmp_execute_tasks_64<false, true>(kmp_info_t *, kmp_int32,
3286 kmp_flag_64<false, true> *,
3288 int *USE_ITT_BUILD_ARG(
void *),
3291template int __kmp_execute_tasks_64<true, false>(kmp_info_t *, kmp_int32,
3292 kmp_flag_64<true, false> *,
3294 int *USE_ITT_BUILD_ARG(
void *),
3297template int __kmp_atomic_execute_tasks_64<false, true>(
3298 kmp_info_t *, kmp_int32, kmp_atomic_flag_64<false, true> *,
int,
3299 int *USE_ITT_BUILD_ARG(
void *), kmp_int32);
3301template int __kmp_atomic_execute_tasks_64<true, false>(
3302 kmp_info_t *, kmp_int32, kmp_atomic_flag_64<true, false> *,
int,
3303 int *USE_ITT_BUILD_ARG(
void *), kmp_int32);
3308static void __kmp_enable_tasking(kmp_task_team_t *task_team,
3309 kmp_info_t *this_thr) {
3310 kmp_thread_data_t *threads_data;
3311 int nthreads, i, is_init_thread;
3313 KA_TRACE(10, (
"__kmp_enable_tasking(enter): T#%d\n",
3314 __kmp_gtid_from_thread(this_thr)));
3316 KMP_DEBUG_ASSERT(task_team != NULL);
3317 KMP_DEBUG_ASSERT(this_thr->th.th_team != NULL);
3319 nthreads = task_team->tt.tt_nproc;
3320 KMP_DEBUG_ASSERT(nthreads > 0);
3321 KMP_DEBUG_ASSERT(nthreads == this_thr->th.th_team->t.t_nproc);
3324 is_init_thread = __kmp_realloc_task_threads_data(this_thr, task_team);
3326 if (!is_init_thread) {
3330 (
"__kmp_enable_tasking(exit): T#%d: threads array already set up.\n",
3331 __kmp_gtid_from_thread(this_thr)));
3334 threads_data = (kmp_thread_data_t *)TCR_PTR(task_team->tt.tt_threads_data);
3335 KMP_DEBUG_ASSERT(threads_data != NULL);
3337 if (__kmp_tasking_mode == tskm_task_teams &&
3338 (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME)) {
3342 for (i = 0; i < nthreads; i++) {
3344 kmp_info_t *thread = threads_data[i].td.td_thr;
3346 if (i == this_thr->th.th_info.ds.ds_tid) {
3355 if ((sleep_loc = TCR_PTR(CCAST(
void *, thread->th.th_sleep_loc))) !=
3357 KF_TRACE(50, (
"__kmp_enable_tasking: T#%d waking up thread T#%d\n",
3358 __kmp_gtid_from_thread(this_thr),
3359 __kmp_gtid_from_thread(thread)));
3360 __kmp_null_resume_wrapper(thread);
3362 KF_TRACE(50, (
"__kmp_enable_tasking: T#%d don't wake up thread T#%d\n",
3363 __kmp_gtid_from_thread(this_thr),
3364 __kmp_gtid_from_thread(thread)));
3369 KA_TRACE(10, (
"__kmp_enable_tasking(exit): T#%d\n",
3370 __kmp_gtid_from_thread(this_thr)));
3403static kmp_task_team_t *__kmp_free_task_teams =
3406kmp_bootstrap_lock_t __kmp_task_team_lock =
3407 KMP_BOOTSTRAP_LOCK_INITIALIZER(__kmp_task_team_lock);
3414static void __kmp_alloc_task_deque(kmp_info_t *thread,
3415 kmp_thread_data_t *thread_data) {
3416 __kmp_init_bootstrap_lock(&thread_data->td.td_deque_lock);
3417 KMP_DEBUG_ASSERT(thread_data->td.td_deque == NULL);
3420 thread_data->td.td_deque_last_stolen = -1;
3422 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) == 0);
3423 KMP_DEBUG_ASSERT(thread_data->td.td_deque_head == 0);
3424 KMP_DEBUG_ASSERT(thread_data->td.td_deque_tail == 0);
3428 (
"__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n",
3429 __kmp_gtid_from_thread(thread), INITIAL_TASK_DEQUE_SIZE, thread_data));
3433 thread_data->td.td_deque = (kmp_taskdata_t **)__kmp_allocate(
3434 INITIAL_TASK_DEQUE_SIZE *
sizeof(kmp_taskdata_t *));
3435 thread_data->td.td_deque_size = INITIAL_TASK_DEQUE_SIZE;
3441static void __kmp_free_task_deque(kmp_thread_data_t *thread_data) {
3442 if (thread_data->td.td_deque != NULL) {
3443 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
3444 TCW_4(thread_data->td.td_deque_ntasks, 0);
3445 __kmp_free(thread_data->td.td_deque);
3446 thread_data->td.td_deque = NULL;
3447 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
3458static int __kmp_realloc_task_threads_data(kmp_info_t *thread,
3459 kmp_task_team_t *task_team) {
3460 kmp_thread_data_t **threads_data_p;
3461 kmp_int32 nthreads, maxthreads;
3462 int is_init_thread = FALSE;
3464 if (TCR_4(task_team->tt.tt_found_tasks)) {
3469 threads_data_p = &task_team->tt.tt_threads_data;
3470 nthreads = task_team->tt.tt_nproc;
3471 maxthreads = task_team->tt.tt_max_threads;
3476 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_threads_lock);
3478 if (!TCR_4(task_team->tt.tt_found_tasks)) {
3480 kmp_team_t *team = thread->th.th_team;
3483 is_init_thread = TRUE;
3484 if (maxthreads < nthreads) {
3486 if (*threads_data_p != NULL) {
3487 kmp_thread_data_t *old_data = *threads_data_p;
3488 kmp_thread_data_t *new_data = NULL;
3492 (
"__kmp_realloc_task_threads_data: T#%d reallocating "
3493 "threads data for task_team %p, new_size = %d, old_size = %d\n",
3494 __kmp_gtid_from_thread(thread), task_team, nthreads, maxthreads));
3499 new_data = (kmp_thread_data_t *)__kmp_allocate(
3500 nthreads *
sizeof(kmp_thread_data_t));
3502 KMP_MEMCPY_S((
void *)new_data, nthreads *
sizeof(kmp_thread_data_t),
3503 (
void *)old_data, maxthreads *
sizeof(kmp_thread_data_t));
3506 (*threads_data_p) = new_data;
3507 __kmp_free(old_data);
3509 KE_TRACE(10, (
"__kmp_realloc_task_threads_data: T#%d allocating "
3510 "threads data for task_team %p, size = %d\n",
3511 __kmp_gtid_from_thread(thread), task_team, nthreads));
3515 *threads_data_p = (kmp_thread_data_t *)__kmp_allocate(
3516 nthreads *
sizeof(kmp_thread_data_t));
3518 task_team->tt.tt_max_threads = nthreads;
3521 KMP_DEBUG_ASSERT(*threads_data_p != NULL);
3525 for (i = 0; i < nthreads; i++) {
3526 kmp_thread_data_t *thread_data = &(*threads_data_p)[i];
3527 thread_data->td.td_thr = team->t.t_threads[i];
3529 if (thread_data->td.td_deque_last_stolen >= nthreads) {
3533 thread_data->td.td_deque_last_stolen = -1;
3538 TCW_SYNC_4(task_team->tt.tt_found_tasks, TRUE);
3541 __kmp_release_bootstrap_lock(&task_team->tt.tt_threads_lock);
3542 return is_init_thread;
3548static void __kmp_free_task_threads_data(kmp_task_team_t *task_team) {
3549 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_threads_lock);
3550 if (task_team->tt.tt_threads_data != NULL) {
3552 for (i = 0; i < task_team->tt.tt_max_threads; i++) {
3553 __kmp_free_task_deque(&task_team->tt.tt_threads_data[i]);
3555 __kmp_free(task_team->tt.tt_threads_data);
3556 task_team->tt.tt_threads_data = NULL;
3558 __kmp_release_bootstrap_lock(&task_team->tt.tt_threads_lock);
3564static void __kmp_free_task_pri_list(kmp_task_team_t *task_team) {
3565 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
3566 if (task_team->tt.tt_task_pri_list != NULL) {
3567 kmp_task_pri_t *list = task_team->tt.tt_task_pri_list;
3568 while (list != NULL) {
3569 kmp_task_pri_t *next = list->next;
3570 __kmp_free_task_deque(&list->td);
3574 task_team->tt.tt_task_pri_list = NULL;
3576 __kmp_release_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
3579static inline void __kmp_task_team_init(kmp_task_team_t *task_team,
3581 int team_nth = team->t.t_nproc;
3583 if (!task_team->tt.tt_active || team_nth != task_team->tt.tt_nproc) {
3584 TCW_4(task_team->tt.tt_found_tasks, FALSE);
3585 TCW_4(task_team->tt.tt_found_proxy_tasks, FALSE);
3586 TCW_4(task_team->tt.tt_hidden_helper_task_encountered, FALSE);
3587 TCW_4(task_team->tt.tt_nproc, team_nth);
3588 KMP_ATOMIC_ST_REL(&task_team->tt.tt_unfinished_threads, team_nth);
3589 TCW_4(task_team->tt.tt_active, TRUE);
3597static kmp_task_team_t *__kmp_allocate_task_team(kmp_info_t *thread,
3599 kmp_task_team_t *task_team = NULL;
3601 KA_TRACE(20, (
"__kmp_allocate_task_team: T#%d entering; team = %p\n",
3602 (thread ? __kmp_gtid_from_thread(thread) : -1), team));
3604 if (TCR_PTR(__kmp_free_task_teams) != NULL) {
3606 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3607 if (__kmp_free_task_teams != NULL) {
3608 task_team = __kmp_free_task_teams;
3609 TCW_PTR(__kmp_free_task_teams, task_team->tt.tt_next);
3610 task_team->tt.tt_next = NULL;
3612 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3615 if (task_team == NULL) {
3616 KE_TRACE(10, (
"__kmp_allocate_task_team: T#%d allocating "
3617 "task team for team %p\n",
3618 __kmp_gtid_from_thread(thread), team));
3621 task_team = (kmp_task_team_t *)__kmp_allocate(
sizeof(kmp_task_team_t));
3622 __kmp_init_bootstrap_lock(&task_team->tt.tt_threads_lock);
3623 __kmp_init_bootstrap_lock(&task_team->tt.tt_task_pri_lock);
3624#if USE_ITT_BUILD && USE_ITT_NOTIFY && KMP_DEBUG
3627 __itt_suppress_mark_range(
3628 __itt_suppress_range, __itt_suppress_threading_errors,
3629 &task_team->tt.tt_found_tasks,
sizeof(task_team->tt.tt_found_tasks));
3630 __itt_suppress_mark_range(__itt_suppress_range,
3631 __itt_suppress_threading_errors,
3632 CCAST(kmp_uint32 *, &task_team->tt.tt_active),
3633 sizeof(task_team->tt.tt_active));
3641 __kmp_task_team_init(task_team, team);
3643 KA_TRACE(20, (
"__kmp_allocate_task_team: T#%d exiting; task_team = %p "
3644 "unfinished_threads init'd to %d\n",
3645 (thread ? __kmp_gtid_from_thread(thread) : -1), task_team,
3646 KMP_ATOMIC_LD_RLX(&task_team->tt.tt_unfinished_threads)));
3653void __kmp_free_task_team(kmp_info_t *thread, kmp_task_team_t *task_team) {
3654 KA_TRACE(20, (
"__kmp_free_task_team: T#%d task_team = %p\n",
3655 thread ? __kmp_gtid_from_thread(thread) : -1, task_team));
3658 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3660 KMP_DEBUG_ASSERT(task_team->tt.tt_next == NULL);
3661 task_team->tt.tt_next = __kmp_free_task_teams;
3662 TCW_PTR(__kmp_free_task_teams, task_team);
3664 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3672void __kmp_reap_task_teams(
void) {
3673 kmp_task_team_t *task_team;
3675 if (TCR_PTR(__kmp_free_task_teams) != NULL) {
3677 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3678 while ((task_team = __kmp_free_task_teams) != NULL) {
3679 __kmp_free_task_teams = task_team->tt.tt_next;
3680 task_team->tt.tt_next = NULL;
3683 if (task_team->tt.tt_threads_data != NULL) {
3684 __kmp_free_task_threads_data(task_team);
3686 if (task_team->tt.tt_task_pri_list != NULL) {
3687 __kmp_free_task_pri_list(task_team);
3689 __kmp_free(task_team);
3691 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3699void __kmp_push_task_team_node(kmp_info_t *thread, kmp_team_t *team) {
3700 KMP_DEBUG_ASSERT(team->t.t_nproc == 1);
3701 kmp_task_team_list_t *current =
3702 (kmp_task_team_list_t *)(&team->t.t_task_team[0]);
3703 kmp_task_team_list_t *node =
3704 (kmp_task_team_list_t *)__kmp_allocate(
sizeof(kmp_task_team_list_t));
3705 node->task_team = current->task_team;
3706 node->next = current->next;
3707 thread->th.th_task_team = current->task_team = NULL;
3708 current->next = node;
3712void __kmp_pop_task_team_node(kmp_info_t *thread, kmp_team_t *team) {
3713 KMP_DEBUG_ASSERT(team->t.t_nproc == 1);
3714 kmp_task_team_list_t *current =
3715 (kmp_task_team_list_t *)(&team->t.t_task_team[0]);
3716 if (current->task_team) {
3717 __kmp_free_task_team(thread, current->task_team);
3719 kmp_task_team_list_t *next = current->next;
3721 current->task_team = next->task_team;
3722 current->next = next->next;
3723 KMP_DEBUG_ASSERT(next != current);
3725 thread->th.th_task_team = current->task_team;
3732void __kmp_wait_to_unref_task_teams(
void) {
3738 KMP_INIT_YIELD(spins);
3739 KMP_INIT_BACKOFF(time);
3747 for (thread = CCAST(kmp_info_t *, __kmp_thread_pool); thread != NULL;
3748 thread = thread->th.th_next_pool) {
3752 if (TCR_PTR(thread->th.th_task_team) == NULL) {
3753 KA_TRACE(10, (
"__kmp_wait_to_unref_task_team: T#%d task_team == NULL\n",
3754 __kmp_gtid_from_thread(thread)));
3759 if (!__kmp_is_thread_alive(thread, &exit_val)) {
3760 thread->th.th_task_team = NULL;
3767 KA_TRACE(10, (
"__kmp_wait_to_unref_task_team: Waiting for T#%d to "
3768 "unreference task_team\n",
3769 __kmp_gtid_from_thread(thread)));
3771 if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME) {
3774 if ((sleep_loc = TCR_PTR(CCAST(
void *, thread->th.th_sleep_loc))) !=
3778 (
"__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n",
3779 __kmp_gtid_from_thread(thread), __kmp_gtid_from_thread(thread)));
3780 __kmp_null_resume_wrapper(thread);
3789 KMP_YIELD_OVERSUB_ELSE_SPIN(spins, time);
3795void __kmp_task_team_setup(kmp_info_t *this_thr, kmp_team_t *team) {
3796 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3801 if (team == this_thr->th.th_serial_team ||
3802 team == this_thr->th.th_root->r.r_root_team) {
3803 KMP_DEBUG_ASSERT(team->t.t_nproc == 1);
3804 if (team->t.t_task_team[0] == NULL) {
3805 team->t.t_task_team[0] = __kmp_allocate_task_team(this_thr, team);
3807 20, (
"__kmp_task_team_setup: Primary T#%d created new task_team %p"
3808 " for serial/root team %p\n",
3809 __kmp_gtid_from_thread(this_thr), team->t.t_task_team[0], team));
3812 __kmp_task_team_init(team->t.t_task_team[0], team);
3820 if (team->t.t_task_team[this_thr->th.th_task_state] == NULL) {
3821 team->t.t_task_team[this_thr->th.th_task_state] =
3822 __kmp_allocate_task_team(this_thr, team);
3823 KA_TRACE(20, (
"__kmp_task_team_setup: Primary T#%d created new task_team %p"
3824 " for team %d at parity=%d\n",
3825 __kmp_gtid_from_thread(this_thr),
3826 team->t.t_task_team[this_thr->th.th_task_state], team->t.t_id,
3827 this_thr->th.th_task_state));
3836 int other_team = 1 - this_thr->th.th_task_state;
3837 KMP_DEBUG_ASSERT(other_team >= 0 && other_team < 2);
3838 if (team->t.t_task_team[other_team] == NULL) {
3839 team->t.t_task_team[other_team] = __kmp_allocate_task_team(this_thr, team);
3840 KA_TRACE(20, (
"__kmp_task_team_setup: Primary T#%d created second new "
3841 "task_team %p for team %d at parity=%d\n",
3842 __kmp_gtid_from_thread(this_thr),
3843 team->t.t_task_team[other_team], team->t.t_id, other_team));
3846 kmp_task_team_t *task_team = team->t.t_task_team[other_team];
3847 __kmp_task_team_init(task_team, team);
3850 KA_TRACE(20, (
"__kmp_task_team_setup: Primary T#%d reset next task_team "
3851 "%p for team %d at parity=%d\n",
3852 __kmp_gtid_from_thread(this_thr),
3853 team->t.t_task_team[other_team], team->t.t_id, other_team));
3860 if (this_thr == __kmp_hidden_helper_main_thread) {
3861 for (
int i = 0; i < 2; ++i) {
3862 kmp_task_team_t *task_team = team->t.t_task_team[i];
3863 if (KMP_TASKING_ENABLED(task_team)) {
3866 __kmp_enable_tasking(task_team, this_thr);
3867 for (
int j = 0; j < task_team->tt.tt_nproc; ++j) {
3868 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[j];
3869 if (thread_data->td.td_deque == NULL) {
3870 __kmp_alloc_task_deque(__kmp_hidden_helper_threads[j], thread_data);
3880void __kmp_task_team_sync(kmp_info_t *this_thr, kmp_team_t *team) {
3881 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3882 KMP_DEBUG_ASSERT(team != this_thr->th.th_serial_team);
3883 KMP_DEBUG_ASSERT(team != this_thr->th.th_root->r.r_root_team);
3887 this_thr->th.th_task_state = (kmp_uint8)(1 - this_thr->th.th_task_state);
3891 TCW_PTR(this_thr->th.th_task_team,
3892 team->t.t_task_team[this_thr->th.th_task_state]);
3894 (
"__kmp_task_team_sync: Thread T#%d task team switched to task_team "
3895 "%p from Team #%d (parity=%d)\n",
3896 __kmp_gtid_from_thread(this_thr), this_thr->th.th_task_team,
3897 team->t.t_id, this_thr->th.th_task_state));
3906void __kmp_task_team_wait(
3907 kmp_info_t *this_thr,
3908 kmp_team_t *team USE_ITT_BUILD_ARG(
void *itt_sync_obj),
int wait) {
3909 kmp_task_team_t *task_team = team->t.t_task_team[this_thr->th.th_task_state];
3911 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec);
3912 KMP_DEBUG_ASSERT(task_team == this_thr->th.th_task_team);
3914 if ((task_team != NULL) && KMP_TASKING_ENABLED(task_team)) {
3916 KA_TRACE(20, (
"__kmp_task_team_wait: Primary T#%d waiting for all tasks "
3917 "(for unfinished_threads to reach 0) on task_team = %p\n",
3918 __kmp_gtid_from_thread(this_thr), task_team));
3922 kmp_flag_32<false, false> flag(
3923 RCAST(std::atomic<kmp_uint32> *,
3924 &task_team->tt.tt_unfinished_threads),
3926 flag.wait(this_thr, TRUE USE_ITT_BUILD_ARG(itt_sync_obj));
3932 (
"__kmp_task_team_wait: Primary T#%d deactivating task_team %p: "
3933 "setting active to false, setting local and team's pointer to NULL\n",
3934 __kmp_gtid_from_thread(this_thr), task_team));
3935 TCW_SYNC_4(task_team->tt.tt_found_proxy_tasks, FALSE);
3936 TCW_SYNC_4(task_team->tt.tt_hidden_helper_task_encountered, FALSE);
3937 KMP_CHECK_UPDATE(task_team->tt.tt_untied_task_encountered, 0);
3938 TCW_SYNC_4(task_team->tt.tt_active, FALSE);
3941 TCW_PTR(this_thr->th.th_task_team, NULL);
3950void __kmp_tasking_barrier(kmp_team_t *team, kmp_info_t *thread,
int gtid) {
3951 std::atomic<kmp_uint32> *spin = RCAST(
3952 std::atomic<kmp_uint32> *,
3953 &team->t.t_task_team[thread->th.th_task_state]->tt.tt_unfinished_threads);
3955 KMP_DEBUG_ASSERT(__kmp_tasking_mode == tskm_extra_barrier);
3958 KMP_FSYNC_SPIN_INIT(spin, NULL);
3960 kmp_flag_32<false, false> spin_flag(spin, 0U);
3961 while (!spin_flag.execute_tasks(thread, gtid, TRUE,
3962 &flag USE_ITT_BUILD_ARG(NULL), 0)) {
3965 KMP_FSYNC_SPIN_PREPARE(RCAST(
void *, spin));
3968 if (TCR_4(__kmp_global.g.g_done)) {
3969 if (__kmp_global.g.g_abort)
3970 __kmp_abort_thread();
3976 KMP_FSYNC_SPIN_ACQUIRED(RCAST(
void *, spin));
3985static bool __kmp_give_task(kmp_info_t *thread, kmp_int32 tid, kmp_task_t *task,
3987 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
3988 kmp_task_team_t *task_team = taskdata->td_task_team;
3990 KA_TRACE(20, (
"__kmp_give_task: trying to give task %p to thread %d.\n",
3994 KMP_DEBUG_ASSERT(task_team != NULL);
3996 bool result =
false;
3997 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[tid];
3999 if (thread_data->td.td_deque == NULL) {
4003 (
"__kmp_give_task: thread %d has no queue while giving task %p.\n",
4008 if (TCR_4(thread_data->td.td_deque_ntasks) >=
4009 TASK_DEQUE_SIZE(thread_data->td)) {
4012 (
"__kmp_give_task: queue is full while giving task %p to thread %d.\n",
4017 if (TASK_DEQUE_SIZE(thread_data->td) / INITIAL_TASK_DEQUE_SIZE >= pass)
4020 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
4021 if (TCR_4(thread_data->td.td_deque_ntasks) >=
4022 TASK_DEQUE_SIZE(thread_data->td)) {
4024 __kmp_realloc_task_deque(thread, thread_data);
4029 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
4031 if (TCR_4(thread_data->td.td_deque_ntasks) >=
4032 TASK_DEQUE_SIZE(thread_data->td)) {
4033 KA_TRACE(30, (
"__kmp_give_task: queue is full while giving task %p to "
4039 if (TASK_DEQUE_SIZE(thread_data->td) / INITIAL_TASK_DEQUE_SIZE >= pass)
4040 goto release_and_exit;
4042 __kmp_realloc_task_deque(thread, thread_data);
4048 thread_data->td.td_deque[thread_data->td.td_deque_tail] = taskdata;
4050 thread_data->td.td_deque_tail =
4051 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td);
4052 TCW_4(thread_data->td.td_deque_ntasks,
4053 TCR_4(thread_data->td.td_deque_ntasks) + 1);
4056 KA_TRACE(30, (
"__kmp_give_task: successfully gave task %p to thread %d.\n",
4060 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
4065#define PROXY_TASK_FLAG 0x40000000
4082static void __kmp_first_top_half_finish_proxy(kmp_taskdata_t *taskdata) {
4083 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT);
4084 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4085 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
4086 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
4088 taskdata->td_flags.complete = 1;
4090 if (taskdata->td_taskgroup)
4091 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
4095 KMP_ATOMIC_OR(&taskdata->td_incomplete_child_tasks, PROXY_TASK_FLAG);
4098static void __kmp_second_top_half_finish_proxy(kmp_taskdata_t *taskdata) {
4100 kmp_int32 children = 0;
4104 KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks);
4105 KMP_DEBUG_ASSERT(children >= 0);
4108 KMP_ATOMIC_AND(&taskdata->td_incomplete_child_tasks, ~PROXY_TASK_FLAG);
4111static void __kmp_bottom_half_finish_proxy(kmp_int32 gtid, kmp_task_t *ptask) {
4112 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4113 kmp_info_t *thread = __kmp_threads[gtid];
4115 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4116 KMP_DEBUG_ASSERT(taskdata->td_flags.complete ==
4121 while ((KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks) &
4122 PROXY_TASK_FLAG) > 0)
4125 __kmp_release_deps(gtid, taskdata);
4126 __kmp_free_task_and_ancestors(gtid, taskdata, thread);
4138 KMP_DEBUG_ASSERT(ptask != NULL);
4139 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4141 10, (
"__kmp_proxy_task_completed(enter): T#%d proxy task %p completing\n",
4143 __kmp_assert_valid_gtid(gtid);
4144 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4146 __kmp_first_top_half_finish_proxy(taskdata);
4147 __kmp_second_top_half_finish_proxy(taskdata);
4148 __kmp_bottom_half_finish_proxy(gtid, ptask);
4151 (
"__kmp_proxy_task_completed(exit): T#%d proxy task %p completing\n",
4155void __kmpc_give_task(kmp_task_t *ptask, kmp_int32 start = 0) {
4156 KMP_DEBUG_ASSERT(ptask != NULL);
4157 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4161 kmp_team_t *team = taskdata->td_team;
4162 kmp_int32 nthreads = team->t.t_nproc;
4167 kmp_int32 start_k = start % nthreads;
4169 kmp_int32 k = start_k;
4173 thread = team->t.t_threads[k];
4174 k = (k + 1) % nthreads;
4180 }
while (!__kmp_give_task(thread, k, ptask, pass));
4182 if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME && __kmp_wpolicy_passive) {
4184 for (
int i = 0; i < nthreads; ++i) {
4185 thread = team->t.t_threads[i];
4186 if (thread->th.th_sleep_loc != NULL) {
4187 __kmp_null_resume_wrapper(thread);
4202 KMP_DEBUG_ASSERT(ptask != NULL);
4203 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4207 (
"__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n",
4210 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY);
4212 __kmp_first_top_half_finish_proxy(taskdata);
4214 __kmpc_give_task(ptask);
4216 __kmp_second_top_half_finish_proxy(taskdata);
4220 (
"__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n",
4224kmp_event_t *__kmpc_task_allow_completion_event(
ident_t *loc_ref,
int gtid,
4226 kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(task);
4227 if (td->td_allow_completion_event.type == KMP_EVENT_UNINITIALIZED) {
4228 td->td_allow_completion_event.type = KMP_EVENT_ALLOW_COMPLETION;
4229 td->td_allow_completion_event.ed.task = task;
4230 __kmp_init_tas_lock(&td->td_allow_completion_event.lock);
4232 return &td->td_allow_completion_event;
4235void __kmp_fulfill_event(kmp_event_t *event) {
4236 if (event->type == KMP_EVENT_ALLOW_COMPLETION) {
4237 kmp_task_t *ptask = event->ed.task;
4238 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
4239 bool detached =
false;
4240 int gtid = __kmp_get_gtid();
4245 __kmp_acquire_tas_lock(&event->lock, gtid);
4246 if (taskdata->td_flags.proxy == TASK_PROXY) {
4252 if (UNLIKELY(ompt_enabled.enabled))
4253 __ompt_task_finish(ptask, NULL, ompt_task_early_fulfill);
4256 event->type = KMP_EVENT_UNINITIALIZED;
4257 __kmp_release_tas_lock(&event->lock, gtid);
4263 if (UNLIKELY(ompt_enabled.enabled))
4264 __ompt_task_finish(ptask, NULL, ompt_task_late_fulfill);
4268 kmp_team_t *team = taskdata->td_team;
4269 kmp_info_t *thread = __kmp_get_thread();
4270 if (thread->th.th_team == team) {
4290kmp_task_t *__kmp_task_dup_alloc(kmp_info_t *thread, kmp_task_t *task_src) {
4292 kmp_taskdata_t *taskdata;
4293 kmp_taskdata_t *taskdata_src = KMP_TASK_TO_TASKDATA(task_src);
4294 kmp_taskdata_t *parent_task = taskdata_src->td_parent;
4295 size_t shareds_offset;
4298 KA_TRACE(10, (
"__kmp_task_dup_alloc(enter): Th %p, source task %p\n", thread,
4300 KMP_DEBUG_ASSERT(taskdata_src->td_flags.proxy ==
4302 KMP_DEBUG_ASSERT(taskdata_src->td_flags.tasktype == TASK_EXPLICIT);
4303 task_size = taskdata_src->td_size_alloc;
4306 KA_TRACE(30, (
"__kmp_task_dup_alloc: Th %p, malloc size %ld\n", thread,
4309 taskdata = (kmp_taskdata_t *)__kmp_fast_allocate(thread, task_size);
4311 taskdata = (kmp_taskdata_t *)__kmp_thread_malloc(thread, task_size);
4313 KMP_MEMCPY(taskdata, taskdata_src, task_size);
4315 task = KMP_TASKDATA_TO_TASK(taskdata);
4318 taskdata->td_task_id = KMP_GEN_TASK_ID();
4319 if (task->shareds != NULL) {
4320 shareds_offset = (
char *)task_src->shareds - (
char *)taskdata_src;
4321 task->shareds = &((
char *)taskdata)[shareds_offset];
4322 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task->shareds) & (
sizeof(
void *) - 1)) ==
4325 taskdata->td_alloc_thread = thread;
4326 taskdata->td_parent = parent_task;
4328 taskdata->td_taskgroup = parent_task->td_taskgroup;
4331 if (taskdata->td_flags.tiedness == TASK_TIED)
4332 taskdata->td_last_tied = taskdata;
4336 if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
4337 KMP_ATOMIC_INC(&parent_task->td_incomplete_child_tasks);
4338 if (parent_task->td_taskgroup)
4339 KMP_ATOMIC_INC(&parent_task->td_taskgroup->count);
4342 if (taskdata->td_parent->td_flags.tasktype == TASK_EXPLICIT)
4343 KMP_ATOMIC_INC(&taskdata->td_parent->td_allocated_child_tasks);
4347 (
"__kmp_task_dup_alloc(exit): Th %p, created task %p, parent=%p\n",
4348 thread, taskdata, taskdata->td_parent));
4350 if (UNLIKELY(ompt_enabled.enabled))
4351 __ompt_task_init(taskdata, thread->th.th_info.ds.ds_gtid);
4360typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32);
4362KMP_BUILD_ASSERT(
sizeof(
long) == 4 ||
sizeof(
long) == 8);
4367class kmp_taskloop_bounds_t {
4369 const kmp_taskdata_t *taskdata;
4370 size_t lower_offset;
4371 size_t upper_offset;
4374 kmp_taskloop_bounds_t(kmp_task_t *_task, kmp_uint64 *lb, kmp_uint64 *ub)
4375 : task(_task), taskdata(KMP_TASK_TO_TASKDATA(task)),
4376 lower_offset((char *)lb - (char *)task),
4377 upper_offset((char *)ub - (char *)task) {
4378 KMP_DEBUG_ASSERT((
char *)lb > (
char *)_task);
4379 KMP_DEBUG_ASSERT((
char *)ub > (
char *)_task);
4381 kmp_taskloop_bounds_t(kmp_task_t *_task,
const kmp_taskloop_bounds_t &bounds)
4382 : task(_task), taskdata(KMP_TASK_TO_TASKDATA(_task)),
4383 lower_offset(bounds.lower_offset), upper_offset(bounds.upper_offset) {}
4384 size_t get_lower_offset()
const {
return lower_offset; }
4385 size_t get_upper_offset()
const {
return upper_offset; }
4386 kmp_uint64 get_lb()
const {
4388#if defined(KMP_GOMP_COMPAT)
4390 if (!taskdata->td_flags.native) {
4391 retval = *(kmp_int64 *)((
char *)task + lower_offset);
4394 if (taskdata->td_size_loop_bounds == 4) {
4395 kmp_int32 *lb = RCAST(kmp_int32 *, task->shareds);
4396 retval = (kmp_int64)*lb;
4398 kmp_int64 *lb = RCAST(kmp_int64 *, task->shareds);
4399 retval = (kmp_int64)*lb;
4404 retval = *(kmp_int64 *)((
char *)task + lower_offset);
4408 kmp_uint64 get_ub()
const {
4410#if defined(KMP_GOMP_COMPAT)
4412 if (!taskdata->td_flags.native) {
4413 retval = *(kmp_int64 *)((
char *)task + upper_offset);
4416 if (taskdata->td_size_loop_bounds == 4) {
4417 kmp_int32 *ub = RCAST(kmp_int32 *, task->shareds) + 1;
4418 retval = (kmp_int64)*ub;
4420 kmp_int64 *ub = RCAST(kmp_int64 *, task->shareds) + 1;
4421 retval = (kmp_int64)*ub;
4425 retval = *(kmp_int64 *)((
char *)task + upper_offset);
4429 void set_lb(kmp_uint64 lb) {
4430#if defined(KMP_GOMP_COMPAT)
4432 if (!taskdata->td_flags.native) {
4433 *(kmp_uint64 *)((
char *)task + lower_offset) = lb;
4436 if (taskdata->td_size_loop_bounds == 4) {
4437 kmp_uint32 *lower = RCAST(kmp_uint32 *, task->shareds);
4438 *lower = (kmp_uint32)lb;
4440 kmp_uint64 *lower = RCAST(kmp_uint64 *, task->shareds);
4441 *lower = (kmp_uint64)lb;
4445 *(kmp_uint64 *)((
char *)task + lower_offset) = lb;
4448 void set_ub(kmp_uint64 ub) {
4449#if defined(KMP_GOMP_COMPAT)
4451 if (!taskdata->td_flags.native) {
4452 *(kmp_uint64 *)((
char *)task + upper_offset) = ub;
4455 if (taskdata->td_size_loop_bounds == 4) {
4456 kmp_uint32 *upper = RCAST(kmp_uint32 *, task->shareds) + 1;
4457 *upper = (kmp_uint32)ub;
4459 kmp_uint64 *upper = RCAST(kmp_uint64 *, task->shareds) + 1;
4460 *upper = (kmp_uint64)ub;
4464 *(kmp_uint64 *)((
char *)task + upper_offset) = ub;
4485void __kmp_taskloop_linear(
ident_t *loc,
int gtid, kmp_task_t *task,
4486 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
4487 kmp_uint64 ub_glob, kmp_uint64 num_tasks,
4488 kmp_uint64 grainsize, kmp_uint64 extras,
4489 kmp_int64 last_chunk, kmp_uint64 tc,
4495 KMP_TIME_PARTITIONED_BLOCK(OMP_taskloop_scheduling);
4496 p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
4498 kmp_taskloop_bounds_t task_bounds(task, lb, ub);
4499 kmp_uint64 lower = task_bounds.get_lb();
4500 kmp_uint64 upper = task_bounds.get_ub();
4502 kmp_info_t *thread = __kmp_threads[gtid];
4503 kmp_taskdata_t *current_task = thread->th.th_current_task;
4504 kmp_task_t *next_task;
4505 kmp_int32 lastpriv = 0;
4507 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize +
4508 (last_chunk < 0 ? last_chunk : extras));
4509 KMP_DEBUG_ASSERT(num_tasks > extras);
4510 KMP_DEBUG_ASSERT(num_tasks > 0);
4511 KA_TRACE(20, (
"__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "
4512 "extras %lld, last_chunk %lld, i=%lld,%lld(%d)%lld, dup %p\n",
4513 gtid, num_tasks, grainsize, extras, last_chunk, lower, upper,
4514 ub_glob, st, task_dup));
4517 for (i = 0; i < num_tasks; ++i) {
4518 kmp_uint64 chunk_minus_1;
4520 chunk_minus_1 = grainsize - 1;
4522 chunk_minus_1 = grainsize;
4525 upper = lower + st * chunk_minus_1;
4529 if (i == num_tasks - 1) {
4532 KMP_DEBUG_ASSERT(upper == *ub);
4533 if (upper == ub_glob)
4535 }
else if (st > 0) {
4536 KMP_DEBUG_ASSERT((kmp_uint64)st > *ub - upper);
4537 if ((kmp_uint64)st > ub_glob - upper)
4540 KMP_DEBUG_ASSERT(upper + st < *ub);
4541 if (upper - ub_glob < (kmp_uint64)(-st))
4546 next_task = __kmp_task_dup_alloc(thread, task);
4548 kmp_taskdata_t *next_taskdata = KMP_TASK_TO_TASKDATA(next_task);
4549 kmp_taskloop_bounds_t next_task_bounds =
4550 kmp_taskloop_bounds_t(next_task, task_bounds);
4553 next_task_bounds.set_lb(lower);
4554 if (next_taskdata->td_flags.native) {
4555 next_task_bounds.set_ub(upper + (st > 0 ? 1 : -1));
4557 next_task_bounds.set_ub(upper);
4559 if (ptask_dup != NULL)
4561 ptask_dup(next_task, task, lastpriv);
4563 (
"__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
4564 "upper %lld stride %lld, (offsets %p %p)\n",
4565 gtid, i, next_task, lower, upper, st,
4566 next_task_bounds.get_lower_offset(),
4567 next_task_bounds.get_upper_offset()));
4569 __kmp_omp_taskloop_task(NULL, gtid, next_task,
4572 if (ompt_enabled.ompt_callback_dispatch) {
4573 OMPT_GET_DISPATCH_CHUNK(next_taskdata->ompt_task_info.dispatch_chunk,
4578 __kmp_omp_task(gtid, next_task,
true);
4583 __kmp_task_start(gtid, task, current_task);
4585 __kmp_task_finish<false>(gtid, task, current_task);
4590typedef struct __taskloop_params {
4597 kmp_uint64 num_tasks;
4598 kmp_uint64 grainsize;
4600 kmp_int64 last_chunk;
4602 kmp_uint64 num_t_min;
4606} __taskloop_params_t;
4608void __kmp_taskloop_recur(
ident_t *,
int, kmp_task_t *, kmp_uint64 *,
4609 kmp_uint64 *, kmp_int64, kmp_uint64, kmp_uint64,
4610 kmp_uint64, kmp_uint64, kmp_int64, kmp_uint64,
4618int __kmp_taskloop_task(
int gtid,
void *ptask) {
4619 __taskloop_params_t *p =
4620 (__taskloop_params_t *)((kmp_task_t *)ptask)->shareds;
4621 kmp_task_t *task = p->task;
4622 kmp_uint64 *lb = p->lb;
4623 kmp_uint64 *ub = p->ub;
4624 void *task_dup = p->task_dup;
4626 kmp_int64 st = p->st;
4627 kmp_uint64 ub_glob = p->ub_glob;
4628 kmp_uint64 num_tasks = p->num_tasks;
4629 kmp_uint64 grainsize = p->grainsize;
4630 kmp_uint64 extras = p->extras;
4631 kmp_int64 last_chunk = p->last_chunk;
4632 kmp_uint64 tc = p->tc;
4633 kmp_uint64 num_t_min = p->num_t_min;
4635 void *codeptr_ra = p->codeptr_ra;
4638 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4639 KMP_DEBUG_ASSERT(task != NULL);
4641 (
"__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"
4642 " %lld, extras %lld, last_chunk %lld, i=%lld,%lld(%d), dup %p\n",
4643 gtid, taskdata, num_tasks, grainsize, extras, last_chunk, *lb, *ub,
4646 KMP_DEBUG_ASSERT(num_tasks * 2 + 1 > num_t_min);
4647 if (num_tasks > num_t_min)
4648 __kmp_taskloop_recur(NULL, gtid, task, lb, ub, st, ub_glob, num_tasks,
4649 grainsize, extras, last_chunk, tc, num_t_min,
4655 __kmp_taskloop_linear(NULL, gtid, task, lb, ub, st, ub_glob, num_tasks,
4656 grainsize, extras, last_chunk, tc,
4662 KA_TRACE(40, (
"__kmp_taskloop_task(exit): T#%d\n", gtid));
4684void __kmp_taskloop_recur(
ident_t *loc,
int gtid, kmp_task_t *task,
4685 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
4686 kmp_uint64 ub_glob, kmp_uint64 num_tasks,
4687 kmp_uint64 grainsize, kmp_uint64 extras,
4688 kmp_int64 last_chunk, kmp_uint64 tc,
4689 kmp_uint64 num_t_min,
4694 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4695 KMP_DEBUG_ASSERT(task != NULL);
4696 KMP_DEBUG_ASSERT(num_tasks > num_t_min);
4698 (
"__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"
4699 " %lld, extras %lld, last_chunk %lld, i=%lld,%lld(%d), dup %p\n",
4700 gtid, taskdata, num_tasks, grainsize, extras, last_chunk, *lb, *ub,
4702 p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
4703 kmp_uint64 lower = *lb;
4704 kmp_info_t *thread = __kmp_threads[gtid];
4706 kmp_task_t *next_task;
4707 size_t lower_offset =
4708 (
char *)lb - (
char *)task;
4709 size_t upper_offset =
4710 (
char *)ub - (
char *)task;
4712 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize +
4713 (last_chunk < 0 ? last_chunk : extras));
4714 KMP_DEBUG_ASSERT(num_tasks > extras);
4715 KMP_DEBUG_ASSERT(num_tasks > 0);
4718 kmp_uint64 lb1, ub0, tc0, tc1, ext0, ext1;
4719 kmp_int64 last_chunk0 = 0, last_chunk1 = 0;
4720 kmp_uint64 gr_size0 = grainsize;
4721 kmp_uint64 n_tsk0 = num_tasks >> 1;
4722 kmp_uint64 n_tsk1 = num_tasks - n_tsk0;
4723 if (last_chunk < 0) {
4725 last_chunk1 = last_chunk;
4726 tc0 = grainsize * n_tsk0;
4728 }
else if (n_tsk0 <= extras) {
4731 ext1 = extras - n_tsk0;
4732 tc0 = gr_size0 * n_tsk0;
4737 tc1 = grainsize * n_tsk1;
4740 ub0 = lower + st * (tc0 - 1);
4744 next_task = __kmp_task_dup_alloc(thread, task);
4746 *(kmp_uint64 *)((
char *)next_task + lower_offset) = lb1;
4747 if (ptask_dup != NULL)
4748 ptask_dup(next_task, task, 0);
4753 kmp_taskdata_t *current_task = thread->th.th_current_task;
4754 thread->th.th_current_task = taskdata->td_parent;
4755 kmp_task_t *new_task =
4756 __kmpc_omp_task_alloc(loc, gtid, 1, 3 *
sizeof(
void *),
4757 sizeof(__taskloop_params_t), &__kmp_taskloop_task);
4759 thread->th.th_current_task = current_task;
4760 __taskloop_params_t *p = (__taskloop_params_t *)new_task->shareds;
4761 p->task = next_task;
4762 p->lb = (kmp_uint64 *)((
char *)next_task + lower_offset);
4763 p->ub = (kmp_uint64 *)((
char *)next_task + upper_offset);
4764 p->task_dup = task_dup;
4766 p->ub_glob = ub_glob;
4767 p->num_tasks = n_tsk1;
4768 p->grainsize = grainsize;
4770 p->last_chunk = last_chunk1;
4772 p->num_t_min = num_t_min;
4774 p->codeptr_ra = codeptr_ra;
4779 __kmp_omp_taskloop_task(NULL, gtid, new_task, codeptr_ra);
4781 __kmp_omp_task(gtid, new_task,
true);
4785 if (n_tsk0 > num_t_min)
4786 __kmp_taskloop_recur(loc, gtid, task, lb, ub, st, ub_glob, n_tsk0, gr_size0,
4787 ext0, last_chunk0, tc0, num_t_min,
4793 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, n_tsk0,
4794 gr_size0, ext0, last_chunk0, tc0,
4800 KA_TRACE(40, (
"__kmp_taskloop_recur(exit): T#%d\n", gtid));
4803static void __kmp_taskloop(
ident_t *loc,
int gtid, kmp_task_t *task,
int if_val,
4804 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
4805 int nogroup,
int sched, kmp_uint64 grainsize,
4806 int modifier,
void *task_dup) {
4807 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
4808 KMP_DEBUG_ASSERT(task != NULL);
4810#if OMPT_SUPPORT && OMPT_OPTIONAL
4811 OMPT_STORE_RETURN_ADDRESS(gtid);
4813 __kmpc_taskgroup(loc, gtid);
4817 kmp_taskloop_bounds_t task_bounds(task, lb, ub);
4820 kmp_uint64 lower = task_bounds.get_lb();
4821 kmp_uint64 upper = task_bounds.get_ub();
4822 kmp_uint64 ub_glob = upper;
4823 kmp_uint64 num_tasks = 0, extras = 0;
4824 kmp_int64 last_chunk =
4826 kmp_uint64 num_tasks_min = __kmp_taskloop_min_tasks;
4827 kmp_info_t *thread = __kmp_threads[gtid];
4828 kmp_taskdata_t *current_task = thread->th.th_current_task;
4830 KA_TRACE(20, (
"__kmp_taskloop: T#%d, task %p, lb %lld, ub %lld, st %lld, "
4831 "grain %llu(%d, %d), dup %p\n",
4832 gtid, taskdata, lower, upper, st, grainsize, sched, modifier,
4837 tc = upper - lower + 1;
4838 }
else if (st < 0) {
4839 tc = (lower - upper) / (-st) + 1;
4841 tc = (upper - lower) / st + 1;
4844 KA_TRACE(20, (
"__kmp_taskloop(exit): T#%d zero-trip loop\n", gtid));
4846 __kmp_task_start(gtid, task, current_task);
4848 __kmp_task_finish<false>(gtid, task, current_task);
4852#if OMPT_SUPPORT && OMPT_OPTIONAL
4853 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
4854 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
4855 if (ompt_enabled.ompt_callback_work) {
4856 ompt_callbacks.ompt_callback(ompt_callback_work)(
4857 ompt_work_taskloop, ompt_scope_begin, &(team_info->parallel_data),
4858 &(task_info->task_data), tc, OMPT_GET_RETURN_ADDRESS(0));
4862 if (num_tasks_min == 0)
4865 KMP_MIN(thread->th.th_team_nproc * 10, INITIAL_TASK_DEQUE_SIZE);
4871 grainsize = thread->th.th_team_nproc *
static_cast<kmp_uint64
>(10);
4874 if (grainsize > tc) {
4879 num_tasks = grainsize;
4880 grainsize = tc / num_tasks;
4881 extras = tc % num_tasks;
4885 if (grainsize > tc) {
4891 num_tasks = (tc + grainsize - 1) / grainsize;
4892 last_chunk = tc - (num_tasks * grainsize);
4895 num_tasks = tc / grainsize;
4897 grainsize = tc / num_tasks;
4898 extras = tc % num_tasks;
4903 KMP_ASSERT2(0,
"unknown scheduling of taskloop");
4906 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize +
4907 (last_chunk < 0 ? last_chunk : extras));
4908 KMP_DEBUG_ASSERT(num_tasks > extras);
4909 KMP_DEBUG_ASSERT(num_tasks > 0);
4915 taskdata->td_flags.task_serial = 1;
4916 taskdata->td_flags.tiedness = TASK_TIED;
4918 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
4919 grainsize, extras, last_chunk, tc,
4921 OMPT_GET_RETURN_ADDRESS(0),
4926 }
else if (num_tasks > num_tasks_min && !taskdata->td_flags.native) {
4927 KA_TRACE(20, (
"__kmp_taskloop: T#%d, go recursive: tc %llu, #tasks %llu"
4928 "(%lld), grain %llu, extras %llu, last_chunk %lld\n",
4929 gtid, tc, num_tasks, num_tasks_min, grainsize, extras,
4931 __kmp_taskloop_recur(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
4932 grainsize, extras, last_chunk, tc, num_tasks_min,
4934 OMPT_GET_RETURN_ADDRESS(0),
4938 KA_TRACE(20, (
"__kmp_taskloop: T#%d, go linear: tc %llu, #tasks %llu"
4939 "(%lld), grain %llu, extras %llu, last_chunk %lld\n",
4940 gtid, tc, num_tasks, num_tasks_min, grainsize, extras,
4942 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
4943 grainsize, extras, last_chunk, tc,
4945 OMPT_GET_RETURN_ADDRESS(0),
4950#if OMPT_SUPPORT && OMPT_OPTIONAL
4951 if (ompt_enabled.ompt_callback_work) {
4952 ompt_callbacks.ompt_callback(ompt_callback_work)(
4953 ompt_work_taskloop, ompt_scope_end, &(team_info->parallel_data),
4954 &(task_info->task_data), tc, OMPT_GET_RETURN_ADDRESS(0));
4959#if OMPT_SUPPORT && OMPT_OPTIONAL
4960 OMPT_STORE_RETURN_ADDRESS(gtid);
4962 __kmpc_end_taskgroup(loc, gtid);
4964 KA_TRACE(20, (
"__kmp_taskloop(exit): T#%d\n", gtid));
4984 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
int nogroup,
4985 int sched, kmp_uint64 grainsize,
void *task_dup) {
4986 __kmp_assert_valid_gtid(gtid);
4987 KA_TRACE(20, (
"__kmpc_taskloop(enter): T#%d\n", gtid));
4988 __kmp_taskloop(loc, gtid, task, if_val, lb, ub, st, nogroup, sched, grainsize,
4990 KA_TRACE(20, (
"__kmpc_taskloop(exit): T#%d\n", gtid));
5011 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
5012 int nogroup,
int sched, kmp_uint64 grainsize,
5013 int modifier,
void *task_dup) {
5014 __kmp_assert_valid_gtid(gtid);
5015 KA_TRACE(20, (
"__kmpc_taskloop_5(enter): T#%d\n", gtid));
5016 __kmp_taskloop(loc, gtid, task, if_val, lb, ub, st, nogroup, sched, grainsize,
5017 modifier, task_dup);
5018 KA_TRACE(20, (
"__kmpc_taskloop_5(exit): T#%d\n", gtid));
5030 if (gtid == KMP_GTID_DNE)
5033 kmp_info_t *thread = __kmp_thread_from_gtid(gtid);
5034 kmp_taskdata_t *taskdata = thread->th.th_current_task;
5039 return &taskdata->td_target_data.async_handle;
5051 if (gtid == KMP_GTID_DNE)
5054 kmp_info_t *thread = __kmp_thread_from_gtid(gtid);
5055 kmp_taskdata_t *taskdata = thread->th.th_current_task;
5060 return taskdata->td_task_team != NULL;
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