xref: /llvm-project/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp (revision 8442967fe32453ada32913d1e0fdd97b19520df2)
1 // RUN: %libomp-cxx-compile-and-run
2 // RUN: %libomp-cxx-compile && env OMP_NUM_THREADS=1 %libomp-run
3 
4 /*
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:
7  *
8  * #pragma omp parallel
9  * for (int i = 0; i < N; ++i) {
10  *   int data = -1;
11  * #pragma omp task shared(data) depend(out: data)
12  *   {
13  *     data = 1;
14  *   }
15  * #pragma omp hidden helper task shared(data) depend(inout: data)
16  *   {
17  *     data += 2;
18  *   }
19  * #pragma omp hidden helper task shared(data) depend(inout: data)
20  *   {
21  *     data += 4;
22  *   }
23  * #pragma omp task shared(data) depend(inout: data)
24  *   {
25  *     data += 8;
26  *   }
27  * #pragma omp taskwait
28  *   assert(data == 15);
29  * }
30  */
31 
32 #include "common.h"
33 
34 extern "C" {
35 struct kmp_task_t_with_privates {
36   kmp_task_t task;
37 };
38 
39 struct anon {
40   int32_t *data;
41 };
42 }
43 
44 template <int I>
omp_task_entry(kmp_int32 gtid,kmp_task_t_with_privates * task)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;
48   *p += I;
49   return 0;
50 }
51 
main(int argc,char * argv[])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);
57     int32_t data = 0;
58 
59     // Task 1
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>));
63 
64     auto shareds = reinterpret_cast<anon *>(task1->shareds);
65     shareds->data = &data;
66 
67     kmp_depend_info_t depinfo1;
68     depinfo1.base_addr = reinterpret_cast<intptr_t>(&data);
69     depinfo1.flag = 2; // OUT
70     depinfo1.len = 4;
71 
72     __kmpc_omp_task_with_deps(nullptr, gtid, task1, 1, &depinfo1, 0, nullptr);
73 
74     // Task 2
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);
78 
79     shareds = reinterpret_cast<anon *>(task2->shareds);
80     shareds->data = &data;
81 
82     kmp_depend_info_t depinfo2;
83     depinfo2.base_addr = reinterpret_cast<intptr_t>(&data);
84     depinfo2.flag = 3; // INOUT
85     depinfo2.len = 4;
86 
87     __kmpc_omp_task_with_deps(nullptr, gtid, task2, 1, &depinfo2, 0, nullptr);
88 
89     // Task 3
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);
93 
94     shareds = reinterpret_cast<anon *>(task3->shareds);
95     shareds->data = &data;
96 
97     kmp_depend_info_t depinfo3;
98     depinfo3.base_addr = reinterpret_cast<intptr_t>(&data);
99     depinfo3.flag = 3; // INOUT
100     depinfo3.len = 4;
101 
102     __kmpc_omp_task_with_deps(nullptr, gtid, task3, 1, &depinfo3, 0, nullptr);
103 
104     // Task 4
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>));
108 
109     shareds = reinterpret_cast<anon *>(task4->shareds);
110     shareds->data = &data;
111 
112     kmp_depend_info_t depinfo4;
113     depinfo4.base_addr = reinterpret_cast<intptr_t>(&data);
114     depinfo4.flag = 3; // INOUT
115     depinfo4.len = 4;
116 
117     __kmpc_omp_task_with_deps(nullptr, gtid, task4, 1, &depinfo4, 0, nullptr);
118 
119     // Wait for all tasks
120     __kmpc_omp_taskwait(nullptr, gtid);
121 
122     assert(data == 15);
123   }
124 
125   std::cout << "PASS\n";
126   return 0;
127 }
128 
129 // CHECK: PASS
130