brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · 98ce1f8 Raw
335 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//       task9 - no dependences24//           /25//       taskwait (omp_all_memory) (should not wait for task9, see prints)26//27#include <stdio.h>28#include <omp.h>29 30#ifdef _WIN3231#include <windows.h>32#define mysleep(n) Sleep(n)33#else34#include <unistd.h>35#define mysleep(n) usleep((n)*1000)36#endif37 38// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)39static int checker = 0;40static int err = 0;41static int taskwait_flag = 0;42#ifndef DELAY43// set delay interval in ms for dependent tasks44#define DELAY 10045#endif46 47// ---------------------------------------------------------------------------48// internal data to emulate compiler codegen49typedef struct DEP {50  size_t addr;51  size_t len;52  unsigned char flags;53} dep;54#define DEP_ALL_MEM 0x8055typedef struct task {56  void** shareds;57  void* entry;58  int part_id;59  void* destr_thunk;60  int priority;61  long long device_id;62  int f_priv;63} task_t;64#define TIED 165typedef int(*entry_t)(int, task_t*);66typedef struct ID {67  int reserved_1;68  int flags;69  int reserved_2;70  int reserved_3;71  char *psource;72} id;73// thunk routine for tasks with ALL dependency74int thunk_m(int gtid, task_t* ptask) {75  int lcheck, th;76  #pragma omp atomic capture77    lcheck = ++checker;78  th = omp_get_thread_num();79  printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);80  if (lcheck != 1) { // no more than 1 task at a time81    err++;82    printf("Error m1, checker %d != 1\n", lcheck);83  }84  mysleep(DELAY);85  #pragma omp atomic read86    lcheck = checker; // must still be equal to 187  if (lcheck != 1) {88    err++;89    printf("Error m2, checker %d != 1\n", lcheck);90  }91  #pragma omp atomic92    --checker;93  return 0;94}95// thunk routine for tasks with inoutset dependency96int thunk_s(int gtid, task_t* ptask) {97  int lcheck, th;98  #pragma omp atomic capture99    lcheck = ++checker; // 1100  th = omp_get_thread_num();101  printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);102  if (lcheck != 1) { // no more than 1 task at a time103    err++;104    printf("Error s1, checker %d != 1\n", lcheck);105  }106  mysleep(DELAY);107  #pragma omp atomic read108    lcheck = checker; // must still be equal to 1109  if (lcheck != 1) {110    err++;111    printf("Error s2, checker %d != 1\n", lcheck);112  }113  #pragma omp atomic114    --checker;115  return 0;116}117 118#ifdef __cplusplus119extern "C" {120#endif121int __kmpc_global_thread_num(id*);122task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags,123                              size_t sz, size_t shar, entry_t rtn);124int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,125                              dep *dep_lst, int nd_noalias, dep *noalias_lst);126void __kmpc_omp_wait_deps(id *loc, int gtid, int ndeps, dep *dep_lst,127                          int ndeps_noalias, dep *noalias_dep_lst);128static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};129#ifdef __cplusplus130} // extern "C"131#endif132// End of internal data133// ---------------------------------------------------------------------------134 135int main()136{137  int i1,i2,i3;138  omp_set_num_threads(8);139  omp_set_dynamic(0);140  #pragma omp parallel141  {142    #pragma omp single nowait143    {144      dep sdep[2];145      task_t *ptr;146      int gtid = __kmpc_global_thread_num(&loc);147      int t = omp_get_thread_num();148      // Create longest task first to ensure it is stolen.149      // The test may hang if the task created last and150      // executed by a thread which executes taskwait.151      #pragma omp task152      { // task 9 - long running task153        int flag;154        int th = omp_get_thread_num();155        printf("signalled independent task 9_%d, th %d started....\n", t, th);156        // Wait for taskwait depend() to finish157        // If the taskwait depend() improperly depends on this task158        // to finish, then the test will hang and a timeout should trigger159        while (1) {160          #pragma omp atomic read161          flag = taskwait_flag;162          if (flag == 1)163            break;164        }165        printf("signalled independent task 9_%d, th %d finished....\n", t, th);166      }167      #pragma omp task depend(in: i1, i2)168      { // task 0169        int lcheck, th;170        #pragma omp atomic capture171          lcheck = ++checker; // 1 or 2172        th = omp_get_thread_num();173        printf("task 0_%d, th %d, checker %d\n", t, th, lcheck);174        if (lcheck > 2 || lcheck < 1) {175          err++; // no more than 2 tasks concurrently176          printf("Error1, checker %d, not 1 or 2\n", lcheck);177        }178        mysleep(DELAY);179        #pragma omp atomic read180          lcheck = checker; // 1 or 2181        if (lcheck > 2 || lcheck < 1) {182          #pragma omp atomic183            err++;184          printf("Error2, checker %d, not 1 or 2\n", lcheck);185        }186        #pragma omp atomic187          --checker;188      }189      #pragma omp task depend(in: i1, i2)190      { // task 1191        int lcheck, th;192        #pragma omp atomic capture193          lcheck = ++checker; // 1 or 2194        th = omp_get_thread_num();195        printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);196        if (lcheck > 2 || lcheck < 1) {197          err++; // no more than 2 tasks concurrently198          printf("Error3, 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          err++;205          printf("Error4, checker %d, not 1 or 2\n", lcheck);206        }207        #pragma omp atomic208          --checker;209      }210// compiler codegen start211      // task2212      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);213      sdep[0].addr = (size_t)&i1;214      sdep[0].len = 0;   // not used215      sdep[0].flags = 1; // IN216      sdep[1].addr = (size_t)&i2;217      sdep[1].len = 0;   // not used218      sdep[1].flags = 8; // INOUTSET219      ptr->f_priv = t + 10; // init single first-private variable220      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);221 222      // task3223      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);224      sdep[0].addr = (size_t)&i1; // to be ignored225      sdep[0].len = 0;   // not used226      sdep[0].flags = 1; // IN227      sdep[1].addr = 0;228      sdep[1].len = 0;   // not used229      sdep[1].flags = DEP_ALL_MEM; // omp_all_memory230      ptr->f_priv = t + 20; // init single first-private variable231      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);232// compiler codegen end233      #pragma omp task depend(in: i1, i2)234      { // task 4235        int lcheck, th;236        #pragma omp atomic capture237          lcheck = ++checker; // 1 or 2238        th = omp_get_thread_num();239        printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);240        if (lcheck > 2 || lcheck < 1) {241          err++; // no more than 2 tasks concurrently242          printf("Error5, checker %d, not 1 or 2\n", lcheck);243        }244        mysleep(DELAY);245        #pragma omp atomic read246          lcheck = checker; // 1 or 2247        if (lcheck > 2 || lcheck < 1) {248          err++;249          printf("Error6, checker %d, not 1 or 2\n", lcheck);250        }251        #pragma omp atomic252          --checker;253      }254      #pragma omp task depend(in: i1, i2)255      { // task 5256        int lcheck, th;257        #pragma omp atomic capture258          lcheck = ++checker; // 1 or 2259        th = omp_get_thread_num();260        printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);261        if (lcheck > 2 || lcheck < 1) {262          err++; // no more than 2 tasks concurrently263          printf("Error7, checker %d, not 1 or 2\n", lcheck);264        }265        mysleep(DELAY);266        #pragma omp atomic read267          lcheck = checker; // 1 or 2268        if (lcheck > 2 || lcheck < 1) {269          err++;270          printf("Error8, checker %d, not 1 or 2\n", lcheck);271        }272        #pragma omp atomic273          --checker;274      }275// compiler codegen start276      // task6277      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);278      sdep[0].addr = (size_t)(-1); // omp_all_memory279      sdep[0].len = 0;   // not used280      sdep[0].flags = 2; // OUT281      ptr->f_priv = t + 30; // init single first-private variable282      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 1, sdep, 0, 0);283 284      // task7285      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);286      sdep[0].addr = 0;287      sdep[0].len = 0;   // not used288      sdep[0].flags = DEP_ALL_MEM; // omp_all_memory289      sdep[1].addr = (size_t)&i3; // to be ignored290      sdep[1].len = 0;   // not used291      sdep[1].flags = 4; // MUTEXINOUTSET292      ptr->f_priv = t + 40; // init single first-private variable293      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);294// compiler codegen end295      #pragma omp task depend(in: i3)296      { // task 8297        int lcheck, th;298        #pragma omp atomic capture299          lcheck = ++checker; // 1300        th = omp_get_thread_num();301        printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);302        if (lcheck != 1) {303          err++;304          printf("Error9, checker %d, != 1\n", lcheck);305        }306        mysleep(DELAY);307        #pragma omp atomic read308          lcheck = checker;309        if (lcheck != 1) {310          err++;311          printf("Error10, checker %d, != 1\n", lcheck);312        }313        #pragma omp atomic314          --checker;315      }316      mysleep(1); // wait a bit to ensure at least first task is stolen317//  #pragma omp taskwait depend(omp_all_memory: out)318      printf("all 10 tasks generated;\n"319             "taskwait depend(omp_all_memory: out)  started, th %d\n", t);320      __kmpc_omp_wait_deps(&loc, gtid, 1, sdep, 0, 0);321      #pragma omp atomic write322        taskwait_flag = 1;323      printf("taskwait depend(omp_all_memory: out)  passed, th %d\n", t);324      fflush(0);325    } // single326  } // parallel327  if (err == 0 && checker == 0) {328    printf("passed\n");329    return 0;330  } else {331    printf("failed, err = %d, checker = %d\n", err, checker);332    return 1;333  }334}335