brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · 7a8063c Raw
351 lines · c
1// RUN--: %libarcher-compile-and-run | FileCheck %s --check-prefix=NOENV2// RUN: %libarcher-compile && env ARCHER_OPTIONS="all_memory=1" \3// RUN:   %libarcher-run | FileCheck %s --check-prefix=ENV4// REQUIRES: tsan5 6// The runtime currently does not get dependency information from GCC.7// UNSUPPORTED: gcc8 9// Tests OMP 5.x task dependence "omp_all_memory",10// emulates compiler codegen versions for new dep kind11//12// Task tree created:13//      task0 - task1 (in: i1, i2)14//             \15//        task2 (inoutset: i2), (in: i1)16//             /17//        task3 (omp_all_memory) via flag=0x8018//             /19//      task4 - task5 (in: i1, i2)20//           /21//       task6 (omp_all_memory) via addr=-122//           /23//       task7 (omp_all_memory) via flag=0x8024//           /25//       task8 (in: i3)26//27 28#include <omp.h>29#include <stdio.h>30 31#ifdef _WIN3232#include <windows.h>33#define mysleep(n) Sleep(n)34#else35#include <unistd.h>36#define mysleep(n) usleep((n)*1000)37#endif38 39// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)40static int checker = 0;41static int err = 0;42#ifndef DELAY43#define DELAY 10044#endif45 46// ---------------------------------------------------------------------------47// internal data to emulate compiler codegen48typedef struct DEP {49  size_t addr;50  size_t len;51  unsigned char flags;52} dep;53#define DEP_ALL_MEM 0x8054typedef struct task {55  void **shareds;56  void *entry;57  int part_id;58  void *destr_thunk;59  int priority;60  long long device_id;61  int f_priv;62} task_t;63#define TIED 164typedef int (*entry_t)(int, task_t *);65typedef struct ID {66  int reserved_1;67  int flags;68  int reserved_2;69  int reserved_3;70  char *psource;71} id;72// thunk routine for tasks with ALL dependency73int thunk_m(int gtid, task_t *ptask) {74  int lcheck, th;75#pragma omp atomic capture76  lcheck = ++checker;77  th = omp_get_thread_num();78  printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);79  if (lcheck != 1) { // no more than 1 task at a time80    err++;81    printf("Error m1, checker %d != 1\n", lcheck);82  }83  mysleep(DELAY);84#pragma omp atomic read85  lcheck = checker; // must still be equal to 186  if (lcheck != 1) {87    err++;88    printf("Error m2, checker %d != 1\n", lcheck);89  }90#pragma omp atomic91  --checker;92  return 0;93}94// thunk routine for tasks with inoutset dependency95int thunk_s(int gtid, task_t *ptask) {96  int lcheck, th;97#pragma omp atomic capture98  lcheck = ++checker; // 199  th = omp_get_thread_num();100  printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);101  if (lcheck != 1) { // no more than 1 task at a time102    err++;103    printf("Error s1, checker %d != 1\n", lcheck);104  }105  mysleep(DELAY);106#pragma omp atomic read107  lcheck = checker; // must still be equal to 1108  if (lcheck != 1) {109    err++;110    printf("Error s2, checker %d != 1\n", lcheck);111  }112#pragma omp atomic113  --checker;114  return 0;115}116 117#ifdef __cplusplus118extern "C" {119#endif120int __kmpc_global_thread_num(id *);121task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,122                              size_t shar, entry_t rtn);123int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,124                              dep *dep_lst, int nd_noalias, dep *noalias_lst);125static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};126#ifdef __cplusplus127} // extern "C"128#endif129// End of internal data130// ---------------------------------------------------------------------------131 132int main() {133  char *ompx_all_memory = (void *)0xffffffffffffffff;134  int i1, i2, i3;135  omp_set_num_threads(8);136  omp_set_dynamic(0);137#pragma omp parallel138  {139#pragma omp single nowait140    {141      dep sdep[2];142      task_t *ptr;143      int gtid = __kmpc_global_thread_num(&loc);144      int t = omp_get_thread_num();145#pragma omp task depend(in : i1, i2)146      { // task 0147        int lcheck, th;148#pragma omp atomic capture149        lcheck = ++checker; // 1 or 2150        th = omp_get_thread_num();151        printf("task 0_%d, th %d, checker %d\n", t, th, lcheck);152        if (lcheck > 2 || lcheck < 1) {153          err++; // no more than 2 tasks concurrently154          printf("Error1, checker %d, not 1 or 2\n", lcheck);155        }156        mysleep(DELAY);157#pragma omp atomic read158        lcheck = checker; // 1 or 2159        if (lcheck > 2 || lcheck < 1) {160#pragma omp atomic161          err++;162          printf("Error2, checker %d, not 1 or 2\n", lcheck);163        }164#pragma omp atomic165        --checker;166      }167#pragma omp task depend(in : i1, i2)168      { // task 1169        int lcheck, th;170#pragma omp atomic capture171        lcheck = ++checker; // 1 or 2172        th = omp_get_thread_num();173        printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);174        if (lcheck > 2 || lcheck < 1) {175          err++; // no more than 2 tasks concurrently176          printf("Error3, 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          err++;183          printf("Error4, checker %d, not 1 or 2\n", lcheck);184        }185#pragma omp atomic186        --checker;187      }188      // compiler codegen start189      // task2190      ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);191      sdep[0].addr = (size_t)&i1;192      sdep[0].len = 0;   // not used193      sdep[0].flags = 1; // IN194      sdep[1].addr = (size_t)&i2;195      sdep[1].len = 0;      // not used196      sdep[1].flags = 8;    // INOUTSET197      ptr->f_priv = t + 10; // init single first-private variable198      __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);199 200// task3201#pragma omp task depend(in : i1) depend(inout : ompx_all_memory[0])202      {203        int lcheck, th;204#pragma omp atomic capture205        lcheck = ++checker;206        th = omp_get_thread_num();207        printf("task 3_%d, th %d, checker %d\n", t, th, lcheck);208        if (lcheck != 1) { // no more than 1 task at a time209          err++;210          printf("Error m1, checker %d != 1\n", lcheck);211        }212        mysleep(DELAY);213#pragma omp atomic read214        lcheck = checker; // must still be equal to 1215        if (lcheck != 1) {216          err++;217          printf("Error m2, checker %d != 1\n", lcheck);218        }219#pragma omp atomic220        --checker;221      }222      // compiler codegen end223#pragma omp task depend(in : i1, i2)224      { // task 4225        int lcheck, th;226#pragma omp atomic capture227        lcheck = ++checker; // 1 or 2228        th = omp_get_thread_num();229        printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);230        if (lcheck > 2 || lcheck < 1) {231          err++; // no more than 2 tasks concurrently232          printf("Error5, checker %d, not 1 or 2\n", lcheck);233        }234        mysleep(DELAY);235#pragma omp atomic read236        lcheck = checker; // 1 or 2237        if (lcheck > 2 || lcheck < 1) {238          err++;239          printf("Error6, checker %d, not 1 or 2\n", lcheck);240        }241#pragma omp atomic242        --checker;243      }244#pragma omp task depend(in : i1, i2)245      { // task 5246        int lcheck, th;247#pragma omp atomic capture248        lcheck = ++checker; // 1 or 2249        th = omp_get_thread_num();250        printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);251        if (lcheck > 2 || lcheck < 1) {252          err++; // no more than 2 tasks concurrently253          printf("Error7, checker %d, not 1 or 2\n", lcheck);254        }255        mysleep(DELAY);256#pragma omp atomic read257        lcheck = checker; // 1 or 2258        if (lcheck > 2 || lcheck < 1) {259          err++;260          printf("Error8, checker %d, not 1 or 2\n", lcheck);261        }262#pragma omp atomic263        --checker;264      }265// task6266#pragma omp task depend(inout : ompx_all_memory[0])267      {268        int lcheck, th;269#pragma omp atomic capture270        lcheck = ++checker;271        th = omp_get_thread_num();272        printf("task 6_%d, th %d, checker %d\n", t, th, lcheck);273        if (lcheck != 1) { // no more than 1 task at a time274          err++;275          printf("Error m1, checker %d != 1\n", lcheck);276        }277        mysleep(DELAY);278#pragma omp atomic read279        lcheck = checker; // must still be equal to 1280        if (lcheck != 1) {281          err++;282          printf("Error m2, checker %d != 1\n", lcheck);283        }284#pragma omp atomic285        --checker;286      }287// task7288#pragma omp task depend(inout : ompx_all_memory[0]) depend(mutexinoutset : i3)289      {290        int lcheck, th;291#pragma omp atomic capture292        lcheck = ++checker;293        th = omp_get_thread_num();294        printf("task 7_%d, th %d, checker %d\n", t, th, lcheck);295        if (lcheck != 1) { // no more than 1 task at a time296          err++;297          printf("Error m1, checker %d != 1\n", lcheck);298        }299        mysleep(DELAY);300#pragma omp atomic read301        lcheck = checker; // must still be equal to 1302        if (lcheck != 1) {303          err++;304          printf("Error m2, checker %d != 1\n", lcheck);305        }306#pragma omp atomic307        --checker;308      }309#pragma omp task depend(in : i3)310      { // task 8311        int lcheck, th;312#pragma omp atomic capture313        lcheck = ++checker; // 1314        th = omp_get_thread_num();315        printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);316        if (lcheck != 1) {317          err++;318          printf("Error9, checker %d, != 1\n", lcheck);319        }320        mysleep(DELAY);321#pragma omp atomic read322        lcheck = checker;323        if (lcheck != 1) {324          err++;325          printf("Error10, checker %d, != 1\n", lcheck);326        }327#pragma omp atomic328        --checker;329      }330    } // single331  }   // parallel332  if (err == 0 && checker == 0) {333    printf("passed\n");334    return 0;335  } else {336    printf("failed, err = %d, checker = %d\n", err, checker);337    return 1;338  }339}340 341// NOENV-NOT: ThreadSanitizer: data race342// NOENV-NOT: ThreadSanitizer: reported343// NOENV: omp_all_memory344// NOENV-NOT: ThreadSanitizer: data race345// NOENV-NOT: ThreadSanitizer: reported346// NOENV: passed347 348// ENV-NOT: ThreadSanitizer: data race349// ENV-NOT: ThreadSanitizer: reported350// ENV: passed351