384 lines · c
1// clang-format off2// RUN: %libomp-compile-and-run | FileCheck %s3// REQUIRES: ompt4 5// The runtime currently does not get dependency information from GCC.6// UNSUPPORTED: gcc7 8// Tests OMP 5.x task dependence "omp_all_memory",9// emulates compiler codegen versions for new dep kind10//11// Task tree created:12// task0 - task1 (in: i1, i2)13// \14// task2 (inoutset: i2), (in: i1)15// /16// task3 (omp_all_memory) via flag=0x8017// /18// task4 - task5 (in: i1, i2)19// /20// task6 (omp_all_memory) via addr=-121// /22// task7 (omp_all_memory) via flag=0x8023// /24// task8 (in: i3)25//26 27// CHECK: ompt_event_dependences:28// CHECK-SAME: ompt_dependence_type_in29// CHECK-SAME: ompt_dependence_type_in30// CHECK-SAME: ndeps=231 32// CHECK: ompt_event_dependences:33// CHECK-SAME: ompt_dependence_type_in34// CHECK-SAME: ompt_dependence_type_in35// CHECK-SAME: ndeps=236 37// CHECK: ompt_event_dependences:38// CHECK-SAME: ompt_dependence_type_in39// CHECK-SAME: ompt_dependence_type_inoutset40// CHECK-SAME: ndeps=241 42// CHECK: ompt_event_dependences:43// CHECK-SAME: ompt_dependence_type_in44// CHECK-SAME: ompt_dependence_type_out_all_memory45// CHECK-SAME: ndeps=246 47// CHECK: ompt_event_dependences:48// CHECK-SAME: ompt_dependence_type_in49// CHECK-SAME: ompt_dependence_type_in50// CHECK-SAME: ndeps=251 52// CHECK: ompt_event_dependences:53// CHECK-SAME: ompt_dependence_type_in54// CHECK-SAME: ompt_dependence_type_in55// CHECK-SAME: ndeps=256 57// CHECK: ompt_event_dependences:58// CHECK-SAME: ompt_dependence_type_out_all_memory59// CHECK-SAME: ndeps=160 61// CHECK: ompt_event_dependences:62// CHECK-SAME: ompt_dependence_type_out_all_memory63// CHECK-SAME: ompt_dependence_type_mutexinoutset64// CHECK-SAME: ndeps=265 66// CHECK: ompt_event_dependences:67// CHECK-SAME: ompt_dependence_type_in68// CHECK-SAME: ndeps=169// clang-format on70 71#include "callback.h"72#include <stdio.h>73#include <omp.h>74 75#ifdef _WIN3276#include <windows.h>77#define mysleep(n) Sleep(n)78#else79#include <unistd.h>80#define mysleep(n) usleep((n)*1000)81#endif82 83// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)84static int checker = 0;85static int err = 0;86#ifndef DELAY87#define DELAY 10088#endif89 90// ---------------------------------------------------------------------------91// internal data to emulate compiler codegen92typedef struct DEP {93 size_t addr;94 size_t len;95 unsigned char flags;96} dep;97#define DEP_ALL_MEM 0x8098typedef struct task {99 void **shareds;100 void *entry;101 int part_id;102 void *destr_thunk;103 int priority;104 long long device_id;105 int f_priv;106} task_t;107#define TIED 1108typedef int (*entry_t)(int, task_t *);109typedef struct ID {110 int reserved_1;111 int flags;112 int reserved_2;113 int reserved_3;114 char *psource;115} id;116// thunk routine for tasks with ALL dependency117int thunk_m(int gtid, task_t *ptask) {118 int lcheck, th;119#pragma omp atomic capture120 lcheck = ++checker;121 th = omp_get_thread_num();122 printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);123 if (lcheck != 1) { // no more than 1 task at a time124 err++;125 printf("Error m1, checker %d != 1\n", lcheck);126 }127 mysleep(DELAY);128#pragma omp atomic read129 lcheck = checker; // must still be equal to 1130 if (lcheck != 1) {131 err++;132 printf("Error m2, checker %d != 1\n", lcheck);133 }134#pragma omp atomic135 --checker;136 return 0;137}138// thunk routine for tasks with inoutset dependency139int thunk_s(int gtid, task_t *ptask) {140 int lcheck, th;141#pragma omp atomic capture142 lcheck = ++checker; // 1143 th = omp_get_thread_num();144 printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);145 if (lcheck != 1) { // no more than 1 task at a time146 err++;147 printf("Error s1, checker %d != 1\n", lcheck);148 }149 mysleep(DELAY);150#pragma omp atomic read151 lcheck = checker; // must still be equal to 1152 if (lcheck != 1) {153 err++;154 printf("Error s2, checker %d != 1\n", lcheck);155 }156#pragma omp atomic157 --checker;158 return 0;159}160 161#ifdef __cplusplus162extern "C" {163#endif164int __kmpc_global_thread_num(id *);165task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,166 size_t shar, entry_t rtn);167int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,168 dep *dep_lst, int nd_noalias, dep *noalias_lst);169static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};170#ifdef __cplusplus171} // extern "C"172#endif173// End of internal data174// ---------------------------------------------------------------------------175 176int main() {177 char *ompx_all_memory = (void *)0xffffffffffffffff;178 int i1, i2, i3;179 omp_set_num_threads(8);180 omp_set_dynamic(0);181#pragma omp parallel182 {183#pragma omp single nowait184 {185 dep sdep[2];186 task_t *ptr;187 int gtid = __kmpc_global_thread_num(&loc);188 int t = omp_get_thread_num();189#pragma omp task depend(in : i1, i2)190 { // task 0191 int lcheck, th;192#pragma omp atomic capture193 lcheck = ++checker; // 1 or 2194 th = omp_get_thread_num();195 printf("task 0_%d, th %d, checker %d\n", t, th, lcheck);196 if (lcheck > 2 || lcheck < 1) {197 err++; // no more than 2 tasks concurrently198 printf("Error1, checker %d, not 1 or 2\n", lcheck);199 }200 mysleep(DELAY);201#pragma omp atomic read202 lcheck = checker; // 1 or 2203 if (lcheck > 2 || lcheck < 1) {204#pragma omp atomic205 err++;206 printf("Error2, checker %d, not 1 or 2\n", lcheck);207 }208#pragma omp atomic209 --checker;210 }211#pragma omp task depend(in : i1, i2)212 { // task 1213 int lcheck, th;214#pragma omp atomic capture215 lcheck = ++checker; // 1 or 2216 th = omp_get_thread_num();217 printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);218 if (lcheck > 2 || lcheck < 1) {219 err++; // no more than 2 tasks concurrently220 printf("Error3, checker %d, not 1 or 2\n", lcheck);221 }222 mysleep(DELAY);223#pragma omp atomic read224 lcheck = checker; // 1 or 2225 if (lcheck > 2 || lcheck < 1) {226 err++;227 printf("Error4, checker %d, not 1 or 2\n", lcheck);228 }229#pragma omp atomic230 --checker;231 }232 // compiler codegen start233 // task2234 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);235 sdep[0].addr = (size_t)&i1;236 sdep[0].len = 0; // not used237 sdep[0].flags = 1; // IN238 sdep[1].addr = (size_t)&i2;239 sdep[1].len = 0; // not used240 sdep[1].flags = 8; // INOUTSET241 ptr->f_priv = t + 10; // init single first-private variable242 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);243 244// task3245#pragma omp task depend(in : i1) depend(inout : ompx_all_memory[0])246 {247 int lcheck, th;248#pragma omp atomic capture249 lcheck = ++checker;250 th = omp_get_thread_num();251 printf("task m_%d, th %d, checker %d\n", t, th, lcheck);252 if (lcheck != 1) { // no more than 1 task at a time253 err++;254 printf("Error m1, checker %d != 1\n", lcheck);255 }256 mysleep(DELAY);257#pragma omp atomic read258 lcheck = checker; // must still be equal to 1259 if (lcheck != 1) {260 err++;261 printf("Error m2, checker %d != 1\n", lcheck);262 }263#pragma omp atomic264 --checker;265 }266 // compiler codegen end267#pragma omp task depend(in : i1, i2)268 { // task 4269 int lcheck, th;270#pragma omp atomic capture271 lcheck = ++checker; // 1 or 2272 th = omp_get_thread_num();273 printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);274 if (lcheck > 2 || lcheck < 1) {275 err++; // no more than 2 tasks concurrently276 printf("Error5, checker %d, not 1 or 2\n", lcheck);277 }278 mysleep(DELAY);279#pragma omp atomic read280 lcheck = checker; // 1 or 2281 if (lcheck > 2 || lcheck < 1) {282 err++;283 printf("Error6, checker %d, not 1 or 2\n", lcheck);284 }285#pragma omp atomic286 --checker;287 }288#pragma omp task depend(in : i1, i2)289 { // task 5290 int lcheck, th;291#pragma omp atomic capture292 lcheck = ++checker; // 1 or 2293 th = omp_get_thread_num();294 printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);295 if (lcheck > 2 || lcheck < 1) {296 err++; // no more than 2 tasks concurrently297 printf("Error7, checker %d, not 1 or 2\n", lcheck);298 }299 mysleep(DELAY);300#pragma omp atomic read301 lcheck = checker; // 1 or 2302 if (lcheck > 2 || lcheck < 1) {303 err++;304 printf("Error8, checker %d, not 1 or 2\n", lcheck);305 }306#pragma omp atomic307 --checker;308 }309// task6310#pragma omp task depend(inout : ompx_all_memory[0])311 {312 int lcheck, th;313#pragma omp atomic capture314 lcheck = ++checker;315 th = omp_get_thread_num();316 printf("task m_%d, th %d, checker %d\n", t, th, lcheck);317 if (lcheck != 1) { // no more than 1 task at a time318 err++;319 printf("Error m1, checker %d != 1\n", lcheck);320 }321 mysleep(DELAY);322#pragma omp atomic read323 lcheck = checker; // must still be equal to 1324 if (lcheck != 1) {325 err++;326 printf("Error m2, checker %d != 1\n", lcheck);327 }328#pragma omp atomic329 --checker;330 }331// task7332#pragma omp task depend(inout : ompx_all_memory[0]) depend(mutexinoutset : i3)333 {334 int lcheck, th;335#pragma omp atomic capture336 lcheck = ++checker;337 th = omp_get_thread_num();338 printf("task m_%d, th %d, checker %d\n", t, th, lcheck);339 if (lcheck != 1) { // no more than 1 task at a time340 err++;341 printf("Error m1, checker %d != 1\n", lcheck);342 }343 mysleep(DELAY);344#pragma omp atomic read345 lcheck = checker; // must still be equal to 1346 if (lcheck != 1) {347 err++;348 printf("Error m2, checker %d != 1\n", lcheck);349 }350#pragma omp atomic351 --checker;352 }353#pragma omp task depend(in : i3)354 { // task 8355 int lcheck, th;356#pragma omp atomic capture357 lcheck = ++checker; // 1358 th = omp_get_thread_num();359 printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);360 if (lcheck != 1) {361 err++;362 printf("Error9, checker %d, != 1\n", lcheck);363 }364 mysleep(DELAY);365#pragma omp atomic read366 lcheck = checker;367 if (lcheck != 1) {368 err++;369 printf("Error10, checker %d, != 1\n", lcheck);370 }371#pragma omp atomic372 --checker;373 }374 } // single375 } // parallel376 if (err == 0 && checker == 0) {377 printf("passed\n");378 return 0;379 } else {380 printf("failed, err = %d, checker = %d\n", err, checker);381 return 1;382 }383}384