brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · a7787ff Raw
259 lines · c
1// RUN: %libomp-compile-and-run2// RUN: %libomp-cxx-compile-and-run3// UNSUPPORTED: gcc4 5// Tests OMP 5.0 task dependences "mutexinoutset" and 5.1 "inoutset",6// emulates compiler codegen for new dep kinds7// Mutually exclusive tasks get same input dependency info array8//9// Task tree created:10//      task0 - task1 (in)11//             \12//        task2 - task3 (inoutset)13//             /14//      task3 - task4 (in)15//           /16//  task6 <-->task7  (mutexinoutset)17//       \    /18//       task8 (in)19//20#include <stdio.h>21#include <omp.h>22 23#ifdef _WIN3224#include <windows.h>25#define mysleep(n) Sleep(n)26#else27#include <unistd.h>28#define mysleep(n) usleep((n)*1000)29#endif30 31// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)32static int volatile checker = 0;33static int err = 0;34#ifndef DELAY35#define DELAY 10036#endif37 38// ---------------------------------------------------------------------------39// internal data to emulate compiler codegen40typedef struct DEP {41  size_t addr;42  size_t len;43  unsigned char flags;44} dep;45typedef struct task {46  void** shareds;47  void* entry;48  int part_id;49  void* destr_thunk;50  int priority;51  long long device_id;52  int f_priv;53} task_t;54#define TIED 155typedef int(*entry_t)(int, task_t*);56typedef struct ID {57  int reserved_1;58  int flags;59  int reserved_2;60  int reserved_3;61  char *psource;62} id;63// thunk routine for tasks with MTX dependency64int thunk_m(int gtid, task_t* ptask) {65  int th = omp_get_thread_num();66  #pragma omp atomic67    ++checker;68  printf("task _%d, th %d\n", ptask->f_priv, th);69  if (checker != 1) { // no more than 1 task at a time70    err++;71    printf("Error1, checker %d != 1\n", checker);72  }73  mysleep(DELAY);74  if (checker != 1) { // no more than 1 task at a time75    err++;76    printf("Error2, checker %d != 1\n", checker);77  }78  #pragma omp atomic79    --checker;80  return 0;81}82// thunk routine for tasks with inoutset dependency83int thunk_s(int gtid, task_t* ptask) {84  int th = omp_get_thread_num();85  #pragma omp atomic86    ++checker;87  printf("task _%d, th %d\n", ptask->f_priv, th);88  if (checker > 2) { // no more than 2 tasks concurrently89    err++;90    printf("Error1, checker %d > 2\n", checker);91  }92  mysleep(DELAY);93  if (checker > 2) { // no more than 2 tasks concurrently94    err++;95    printf("Error2, checker %d > 2\n", checker);96  }97  #pragma omp atomic98    --checker;99  return 0;100}101 102#ifdef __cplusplus103extern "C" {104#endif105int __kmpc_global_thread_num(id*);106extern task_t* __kmpc_omp_task_alloc(id *loc, int gtid, int flags,107                                     size_t sz, size_t shar, entry_t rtn);108int109__kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int nd, dep *dep_lst,110                          int nd_noalias, dep *noalias_dep_lst);111static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};112#ifdef __cplusplus113} // extern "C"114#endif115// End of internal data116// ---------------------------------------------------------------------------117 118int main()119{120  int i1,i2,i3;121  omp_set_num_threads(4);122  omp_set_dynamic(0);123  #pragma omp parallel124  {125    #pragma omp single nowait126    {127      dep sdep[2];128      task_t *ptr;129      int gtid = __kmpc_global_thread_num(&loc);130      int t = omp_get_thread_num();131      #pragma omp task depend(in: i1, i2)132      { int th = omp_get_thread_num();133        printf("task 0_%d, th %d\n", t, th);134        #pragma omp atomic135          ++checker;136        if (checker > 2) { // no more than 2 tasks concurrently137          err++;138          printf("Error1, checker %d > 2\n", checker);139        }140        mysleep(DELAY);141        if (checker > 2) { // no more than 2 tasks concurrently142          err++;143          printf("Error1, checker %d > 2\n", checker);144        }145        #pragma omp atomic146          --checker;147      }148      #pragma omp task depend(in: i1, i2)149      { int th = omp_get_thread_num();150        printf("task 1_%d, th %d\n", t, th);151        #pragma omp atomic152          ++checker;153        if (checker > 2) { // no more than 2 tasks concurrently154          err++;155          printf("Error1, checker %d > 2\n", checker);156        }157        mysleep(DELAY);158        if (checker > 2) { // no more than 2 tasks concurrently159          err++;160          printf("Error1, checker %d > 2\n", checker);161        }162        #pragma omp atomic163          --checker;164      }165// compiler codegen start166      // task2167      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);168      sdep[0].addr = (size_t)&i1;169      sdep[0].len = 0;   // not used170      sdep[0].flags = 1; // IN171      sdep[1].addr = (size_t)&i2;172      sdep[1].len = 0;   // not used173      sdep[1].flags = 8; // INOUTSET174      ptr->f_priv = t + 10; // init single first-private variable175      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);176 177      // task3178      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);179      ptr->f_priv = t + 20; // init single first-private variable180      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);181// compiler codegen end182      t = omp_get_thread_num();183      #pragma omp task depend(in: i1, i2)184      { int th = omp_get_thread_num();185        printf("task 4_%d, th %d\n", t, th);186        #pragma omp atomic187          ++checker;188        if (checker > 2) { // no more than 2 tasks concurrently189          err++;190          printf("Error1, checker %d > 2\n", checker);191        }192        mysleep(DELAY);193        if (checker > 2) { // no more than 2 tasks concurrently194          err++;195          printf("Error1, checker %d > 2\n", checker);196        }197        #pragma omp atomic198          --checker;199      }200      #pragma omp task depend(in: i1, i2)201      { int th = omp_get_thread_num();202        printf("task 5_%d, th %d\n", t, th);203        #pragma omp atomic204          ++checker;205        if (checker > 2) { // no more than 2 tasks concurrently206          err++;207          printf("Error1, checker %d > 2\n", checker);208        }209        mysleep(DELAY);210        if (checker > 2) { // no more than 2 tasks concurrently211          err++;212          printf("Error1, checker %d > 2\n", checker);213        }214        #pragma omp atomic215          --checker;216      }217// compiler codegen start218      // task6219      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);220      sdep[0].addr = (size_t)&i1;221      sdep[0].len = 0;   // not used222      sdep[0].flags = 4; // MUTEXINOUTSET223      sdep[1].addr = (size_t)&i3;224      sdep[1].len = 0;   // not used225      sdep[1].flags = 4; // MUTEXINOUTSET226      ptr->f_priv = t + 30; // init single first-private variable227      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);228 229      // task7230      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);231      ptr->f_priv = t + 40; // init single first-private variable232      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);233// compiler codegen end234      #pragma omp task depend(in: i3)235      { int th = omp_get_thread_num();236        printf("task 8_%d, th %d\n", t, th);237        #pragma omp atomic238          ++checker;239        if (checker != 1) { // last task should run exclusively240          err++;241          printf("Error1, checker %d != 1\n", checker); }242        mysleep(DELAY);243        if (checker != 1) { // last task should run exclusively244          err++;245          printf("Error1, checker %d != 1\n", checker); }246        #pragma omp atomic247          --checker;248      }249    } // single250  } // parallel251  if (err == 0) {252    printf("passed\n");253    return 0;254  } else {255    printf("failed\n");256    return 1;257  }258}259