brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · aca0e75 Raw
168 lines · c
1// RUN: %libomp-compile-and-run2// RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run3 4#include <stdio.h>5#include <omp.h>6#include "omp_my_sleep.h"7 8#define N 49#define ST 310#define UB 11811#define LB 012 13// globals14int counter;15int task_count;16 17// Compiler-generated code (emulation)18typedef struct ident {19  void* dummy;20} ident_t;21 22typedef struct shar {23  int *pcounter;24  int *pj;25  int *ptask_count;26} *pshareds;27 28typedef struct task {29  pshareds shareds;30  int(* routine)(int,struct task*);31  int part_id;32  unsigned long long lb; // library always uses ULONG33  unsigned long long ub;34  int st;35  int last;36  int i;37  int j;38  int th;39} *ptask, kmp_task_t;40 41typedef int(* task_entry_t)( int, ptask );42 43void44__task_dup_entry(ptask task_dst, ptask task_src, int lastpriv)45{46// setup lastprivate flag47  task_dst->last = lastpriv;48// could be constructor calls here...49}50 51// OpenMP RTL interfaces52typedef unsigned long long kmp_uint64;53typedef long long kmp_int64;54 55#ifdef __cplusplus56extern "C" {57#endif58void59__kmpc_taskloop_5(ident_t *loc, int gtid, kmp_task_t *task, int if_val,60                  kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,61                  int nogroup, int sched, kmp_int64 grainsize, int modifier,62                  void *task_dup);63ptask64__kmpc_omp_task_alloc(ident_t *loc, int gtid, int flags,65                      size_t sizeof_kmp_task_t, size_t sizeof_shareds,66                      task_entry_t task_entry);67void __kmpc_atomic_fixed4_add(void *id_ref, int gtid, int * lhs, int rhs);68int  __kmpc_global_thread_num(void *id_ref);69#ifdef __cplusplus70}71#endif72 73// User's code74int task_entry(int gtid, ptask task)75{76  pshareds pshar = task->shareds;77  __kmpc_atomic_fixed4_add(NULL, gtid, pshar->ptask_count, 1);78 79  for (task->i = task->lb; task->i <= (int)task->ub; task->i += task->st) {80    task->th = omp_get_thread_num();81    __kmpc_atomic_fixed4_add(NULL,gtid,pshar->pcounter,1);82    task->j = task->i;83  }84  my_sleep( 0.1 ); // sleep 100 ms in order to allow other threads to steal tasks85  if (task->last) {86    *(pshar->pj) = task->j; // lastprivate87  }88  return 0;89}90 91void task_loop(int sched_type, int sched_val, int modifier)92{93  int i, j, gtid = __kmpc_global_thread_num(NULL);94  ptask task;95  pshareds psh;96  omp_set_dynamic(0);97  counter = 0;98  task_count = 0;99  #pragma omp parallel num_threads(N)100  {101    #pragma omp master102    {103      int gtid = __kmpc_global_thread_num(NULL);104      task = __kmpc_omp_task_alloc(NULL, gtid, 1, sizeof(struct task),105                                   sizeof(struct shar), &task_entry);106      psh = task->shareds;107      psh->pcounter = &counter;108      psh->ptask_count = &task_count;109      psh->pj = &j;110      task->lb = LB;111      task->ub = UB;112      task->st = ST;113 114      __kmpc_taskloop_5(115        NULL,             // location116        gtid,             // gtid117        task,             // task structure118        1,                // if clause value119        &task->lb,        // lower bound120        &task->ub,        // upper bound121        ST,               // loop increment122        0,                // 1 if nogroup specified123        sched_type,       // schedule type: 0-none, 1-grainsize, 2-num_tasks124        sched_val,        // schedule value (ignored for type 0)125        modifier,         // strict modifier126        (void*)&__task_dup_entry // tasks duplication routine127      );128    } // end master129  } // end parallel130// check results131  int tc;132  if (ST == 1) { // most common case133    tc = UB - LB + 1;134  } else if (ST < 0) {135    tc = (LB - UB) / (-ST) + 1;136  } else { // ST > 0137    tc = (UB - LB) / ST + 1;138  }139  int count;140  if (sched_type == 1) {141    count = (sched_val > tc) ? 1 : (tc + sched_val - 1) / sched_val;142  } else {143    count = (sched_val > tc) ? tc : sched_val;144  }145  if (j != LB + (tc - 1) * ST) {146    printf("Error in lastprivate, %d != %d\n", j, LB + (tc - 1) * ST);147    exit(1);148  }149  if (counter != tc) {150    printf("Error, counter %d != %d\n", counter, tc);151    exit(1);152  }153  if (task_count != count) {154    printf("Error, task count %d != %d\n", task_count, count);155    exit(1);156  }157}158 159int main(int argc, char *argv[]) {160  task_loop(1, 6, 1); // create 7 tasks161  task_loop(2, 6, 1); // create 6 tasks162  task_loop(1, 50, 1); // create 1 task163  task_loop(2, 50, 1); // create 40 tasks164 165  printf("Test passed\n");166  return 0;167}168