brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 9a29996 Raw
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