130 lines · cpp
1// RUN: %libomp-cxx-compile-and-run2// RUN: %libomp-cxx-compile && env OMP_NUM_THREADS=1 %libomp-run3 4/*5 * This test aims to check whether hidden helper task can work with regular task6 * in terms of dependences. It is equivalent to the following code:7 *8 * #pragma omp parallel9 * 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 taskwait28 * assert(data == 15);29 * }30 */31 32#include "common.h"33 34extern "C" {35struct kmp_task_t_with_privates {36 kmp_task_t task;37};38 39struct anon {40 int32_t *data;41};42}43 44template <int I>45kmp_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 52int main(int argc, char *argv[]) {53 constexpr const int N = 1024;54#pragma omp parallel for55 for (int i = 0; i < N; ++i) {56 int32_t gtid = __kmpc_global_thread_num(nullptr);57 int32_t data = 0;58 59 // Task 160 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; // OUT70 depinfo1.len = 4;71 72 __kmpc_omp_task_with_deps(nullptr, gtid, task1, 1, &depinfo1, 0, nullptr);73 74 // Task 275 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; // INOUT85 depinfo2.len = 4;86 87 __kmpc_omp_task_with_deps(nullptr, gtid, task2, 1, &depinfo2, 0, nullptr);88 89 // Task 390 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; // INOUT100 depinfo3.len = 4;101 102 __kmpc_omp_task_with_deps(nullptr, gtid, task3, 1, &depinfo3, 0, nullptr);103 104 // Task 4105 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; // INOUT115 depinfo4.len = 4;116 117 __kmpc_omp_task_with_deps(nullptr, gtid, task4, 1, &depinfo4, 0, nullptr);118 119 // Wait for all tasks120 __kmpc_omp_taskwait(nullptr, gtid);121 122 assert(data == 15);123 }124 125 std::cout << "PASS\n";126 return 0;127}128 129// CHECK: PASS130