299 lines · c
1// RUN: %libomp-compile-and-run2// The runtime currently does not get dependency information from GCC.3// UNSUPPORTED: gcc4 5// Tests OMP 5.x task dependence "omp_all_memory",6// emulates compiler codegen versions for new dep kind7//8// Task tree created:9// task0 - task1 (in: i1, i2)10// \11// task2 (inoutset: i2), (in: i1)12// /13// task3 (omp_all_memory) via flag=0x8014// /15// task4 - task5 (in: i1, i2)16// /17// task6 (omp_all_memory) via addr=-118// /19// task7 (omp_all_memory) via flag=0x8020// /21// task8 (in: i3)22//23#include <stdio.h>24#include <omp.h>25 26#ifdef _WIN3227#include <windows.h>28#define mysleep(n) Sleep(n)29#else30#include <unistd.h>31#define mysleep(n) usleep((n)*1000)32#endif33 34// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)35static int checker = 0;36static int err = 0;37#ifndef DELAY38#define DELAY 10039#endif40 41// ---------------------------------------------------------------------------42// internal data to emulate compiler codegen43typedef struct DEP {44 size_t addr;45 size_t len;46 unsigned char flags;47} dep;48#define DEP_ALL_MEM 0x8049typedef struct task {50 void** shareds;51 void* entry;52 int part_id;53 void* destr_thunk;54 int priority;55 long long device_id;56 int f_priv;57} task_t;58#define TIED 159typedef int(*entry_t)(int, task_t*);60typedef struct ID {61 int reserved_1;62 int flags;63 int reserved_2;64 int reserved_3;65 char *psource;66} id;67// thunk routine for tasks with ALL dependency68int thunk_m(int gtid, task_t* ptask) {69 int lcheck, th;70 #pragma omp atomic capture71 lcheck = ++checker;72 th = omp_get_thread_num();73 printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);74 if (lcheck != 1) { // no more than 1 task at a time75 err++;76 printf("Error m1, checker %d != 1\n", lcheck);77 }78 mysleep(DELAY);79 #pragma omp atomic read80 lcheck = checker; // must still be equal to 181 if (lcheck != 1) {82 err++;83 printf("Error m2, checker %d != 1\n", lcheck);84 }85 #pragma omp atomic86 --checker;87 return 0;88}89// thunk routine for tasks with inoutset dependency90int thunk_s(int gtid, task_t* ptask) {91 int lcheck, th;92 #pragma omp atomic capture93 lcheck = ++checker; // 194 th = omp_get_thread_num();95 printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);96 if (lcheck != 1) { // no more than 1 task at a time97 err++;98 printf("Error s1, checker %d != 1\n", lcheck);99 }100 mysleep(DELAY);101 #pragma omp atomic read102 lcheck = checker; // must still be equal to 1103 if (lcheck != 1) {104 err++;105 printf("Error s2, checker %d != 1\n", lcheck);106 }107 #pragma omp atomic108 --checker;109 return 0;110}111 112#ifdef __cplusplus113extern "C" {114#endif115int __kmpc_global_thread_num(id*);116task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags,117 size_t sz, size_t shar, entry_t rtn);118int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,119 dep *dep_lst, int nd_noalias, dep *noalias_lst);120static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};121#ifdef __cplusplus122} // extern "C"123#endif124// End of internal data125// ---------------------------------------------------------------------------126 127int main()128{129 int i1,i2,i3;130 omp_set_num_threads(8);131 omp_set_dynamic(0);132 #pragma omp parallel133 {134 #pragma omp single nowait135 {136 dep sdep[2];137 task_t *ptr;138 int gtid = __kmpc_global_thread_num(&loc);139 int t = omp_get_thread_num();140 #pragma omp task depend(in: i1, i2)141 { // task 0142 int lcheck, th;143 #pragma omp atomic capture144 lcheck = ++checker; // 1 or 2145 th = omp_get_thread_num();146 printf("task 0_%d, th %d, checker %d\n", t, th, lcheck);147 if (lcheck > 2 || lcheck < 1) {148 err++; // no more than 2 tasks concurrently149 printf("Error1, checker %d, not 1 or 2\n", lcheck);150 }151 mysleep(DELAY);152 #pragma omp atomic read153 lcheck = checker; // 1 or 2154 if (lcheck > 2 || lcheck < 1) {155 #pragma omp atomic156 err++;157 printf("Error2, checker %d, not 1 or 2\n", lcheck);158 }159 #pragma omp atomic160 --checker;161 }162 #pragma omp task depend(in: i1, i2)163 { // task 1164 int lcheck, th;165 #pragma omp atomic capture166 lcheck = ++checker; // 1 or 2167 th = omp_get_thread_num();168 printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);169 if (lcheck > 2 || lcheck < 1) {170 err++; // no more than 2 tasks concurrently171 printf("Error3, checker %d, not 1 or 2\n", lcheck);172 }173 mysleep(DELAY);174 #pragma omp atomic read175 lcheck = checker; // 1 or 2176 if (lcheck > 2 || lcheck < 1) {177 err++;178 printf("Error4, checker %d, not 1 or 2\n", lcheck);179 }180 #pragma omp atomic181 --checker;182 }183// compiler codegen start184 // task2185 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);186 sdep[0].addr = (size_t)&i1;187 sdep[0].len = 0; // not used188 sdep[0].flags = 1; // IN189 sdep[1].addr = (size_t)&i2;190 sdep[1].len = 0; // not used191 sdep[1].flags = 8; // INOUTSET192 ptr->f_priv = t + 10; // init single first-private variable193 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);194 195 // task3196 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);197 sdep[0].addr = (size_t)&i1; // to be ignored198 sdep[0].len = 0; // not used199 sdep[0].flags = 1; // IN200 sdep[1].addr = 0;201 sdep[1].len = 0; // not used202 sdep[1].flags = DEP_ALL_MEM; // omp_all_memory203 ptr->f_priv = t + 20; // init single first-private variable204 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);205// compiler codegen end206 #pragma omp task depend(in: i1, i2)207 { // task 4208 int lcheck, th;209 #pragma omp atomic capture210 lcheck = ++checker; // 1 or 2211 th = omp_get_thread_num();212 printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);213 if (lcheck > 2 || lcheck < 1) {214 err++; // no more than 2 tasks concurrently215 printf("Error5, checker %d, not 1 or 2\n", lcheck);216 }217 mysleep(DELAY);218 #pragma omp atomic read219 lcheck = checker; // 1 or 2220 if (lcheck > 2 || lcheck < 1) {221 err++;222 printf("Error6, checker %d, not 1 or 2\n", lcheck);223 }224 #pragma omp atomic225 --checker;226 }227 #pragma omp task depend(in: i1, i2)228 { // task 5229 int lcheck, th;230 #pragma omp atomic capture231 lcheck = ++checker; // 1 or 2232 th = omp_get_thread_num();233 printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);234 if (lcheck > 2 || lcheck < 1) {235 err++; // no more than 2 tasks concurrently236 printf("Error7, checker %d, not 1 or 2\n", lcheck);237 }238 mysleep(DELAY);239 #pragma omp atomic read240 lcheck = checker; // 1 or 2241 if (lcheck > 2 || lcheck < 1) {242 err++;243 printf("Error8, checker %d, not 1 or 2\n", lcheck);244 }245 #pragma omp atomic246 --checker;247 }248// compiler codegen start249 // task6250 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);251 sdep[0].addr = (size_t)(-1); // omp_all_memory252 sdep[0].len = 0; // not used253 sdep[0].flags = 2; // OUT254 ptr->f_priv = t + 30; // init single first-private variable255 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 1, sdep, 0, 0);256 257 // task7258 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);259 sdep[0].addr = 0;260 sdep[0].len = 0; // not used261 sdep[0].flags = DEP_ALL_MEM; // omp_all_memory262 sdep[1].addr = (size_t)&i3; // to be ignored263 sdep[1].len = 0; // not used264 sdep[1].flags = 4; // MUTEXINOUTSET265 ptr->f_priv = t + 40; // init single first-private variable266 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);267// compiler codegen end268 #pragma omp task depend(in: i3)269 { // task 8270 int lcheck, th;271 #pragma omp atomic capture272 lcheck = ++checker; // 1273 th = omp_get_thread_num();274 printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);275 if (lcheck != 1) {276 err++;277 printf("Error9, checker %d, != 1\n", lcheck);278 }279 mysleep(DELAY);280 #pragma omp atomic read281 lcheck = checker;282 if (lcheck != 1) {283 err++;284 printf("Error10, checker %d, != 1\n", lcheck);285 }286 #pragma omp atomic287 --checker;288 }289 } // single290 } // parallel291 if (err == 0 && checker == 0) {292 printf("passed\n");293 return 0;294 } else {295 printf("failed, err = %d, checker = %d\n", err, checker);296 return 1;297 }298}299