1 // RUN: %libomp-cxx-compile-and-run
2 // RUN: %libomp-cxx-compile && env OMP_NUM_THREADS=1 %libomp-run
5 * This test aims to check whether hidden helper task can work with regular task
6 * in terms of dependences. It is equivalent to the following code:
9 * for (int i = 0; i < N; ++i) {
11 * #pragma omp task shared(data) depend(out: data)
15 * #pragma omp hidden helper task shared(data) depend(inout: data)
19 * #pragma omp hidden helper task shared(data) depend(inout: data)
23 * #pragma omp task shared(data) depend(inout: data)
27 * #pragma omp taskwait
35 struct kmp_task_t_with_privates
{
45 kmp_int32
omp_task_entry(kmp_int32 gtid
, kmp_task_t_with_privates
*task
) {
46 auto shareds
= reinterpret_cast<anon
*>(task
->task
.shareds
);
47 auto p
= shareds
->data
;
52 int main(int argc
, char *argv
[]) {
53 constexpr const int N
= 1024;
54 #pragma omp parallel for
55 for (int i
= 0; i
< N
; ++i
) {
56 int32_t gtid
= __kmpc_global_thread_num(nullptr);
60 auto task1
= __kmpc_omp_task_alloc(
61 nullptr, gtid
, 1, sizeof(kmp_task_t_with_privates
), sizeof(anon
),
62 reinterpret_cast<kmp_routine_entry_t
>(omp_task_entry
<1>));
64 auto shareds
= reinterpret_cast<anon
*>(task1
->shareds
);
65 shareds
->data
= &data
;
67 kmp_depend_info_t depinfo1
;
68 depinfo1
.base_addr
= reinterpret_cast<intptr_t>(&data
);
69 depinfo1
.flag
= 2; // OUT
72 __kmpc_omp_task_with_deps(nullptr, gtid
, task1
, 1, &depinfo1
, 0, nullptr);
75 auto task2
= __kmpc_omp_target_task_alloc(
76 nullptr, gtid
, 1, sizeof(kmp_task_t_with_privates
), sizeof(anon
),
77 reinterpret_cast<kmp_routine_entry_t
>(omp_task_entry
<2>), -1);
79 shareds
= reinterpret_cast<anon
*>(task2
->shareds
);
80 shareds
->data
= &data
;
82 kmp_depend_info_t depinfo2
;
83 depinfo2
.base_addr
= reinterpret_cast<intptr_t>(&data
);
84 depinfo2
.flag
= 3; // INOUT
87 __kmpc_omp_task_with_deps(nullptr, gtid
, task2
, 1, &depinfo2
, 0, nullptr);
90 auto task3
= __kmpc_omp_target_task_alloc(
91 nullptr, gtid
, 1, sizeof(kmp_task_t_with_privates
), sizeof(anon
),
92 reinterpret_cast<kmp_routine_entry_t
>(omp_task_entry
<4>), -1);
94 shareds
= reinterpret_cast<anon
*>(task3
->shareds
);
95 shareds
->data
= &data
;
97 kmp_depend_info_t depinfo3
;
98 depinfo3
.base_addr
= reinterpret_cast<intptr_t>(&data
);
99 depinfo3
.flag
= 3; // INOUT
102 __kmpc_omp_task_with_deps(nullptr, gtid
, task3
, 1, &depinfo3
, 0, nullptr);
105 auto task4
= __kmpc_omp_task_alloc(
106 nullptr, gtid
, 1, sizeof(kmp_task_t_with_privates
), sizeof(anon
),
107 reinterpret_cast<kmp_routine_entry_t
>(omp_task_entry
<8>));
109 shareds
= reinterpret_cast<anon
*>(task4
->shareds
);
110 shareds
->data
= &data
;
112 kmp_depend_info_t depinfo4
;
113 depinfo4
.base_addr
= reinterpret_cast<intptr_t>(&data
);
114 depinfo4
.flag
= 3; // INOUT
117 __kmpc_omp_task_with_deps(nullptr, gtid
, task4
, 1, &depinfo4
, 0, nullptr);
119 // Wait for all tasks
120 __kmpc_omp_taskwait(nullptr, gtid
);
125 std::cout
<< "PASS\n";