brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 4b13793 Raw
160 lines · c
1// RUN: %libomp-compile-and-run2// RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run3#include <stdio.h>4#include <omp.h>5#include "omp_my_sleep.h"6 7#define N 48#define GRAIN 109#define STRIDE 310 11// globals12int th_counter[N];13int counter;14 15 16// Compiler-generated code (emulation)17typedef struct ident {18    void* dummy;19} ident_t;20 21typedef struct shar {22    int(*pth_counter)[N];23    int *pcounter;24    int *pj;25} *pshareds;26 27typedef struct task {28    pshareds shareds;29    int(* routine)(int,struct task*);30    int part_id;31// privates: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 52// OpenMP RTL interfaces53typedef unsigned long long kmp_uint64;54typedef long long kmp_int64;55 56#ifdef __cplusplus57extern "C" {58#endif59void60__kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int if_val,61                kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,62                int nogroup, int sched, kmp_int64 grainsize, 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 74// User's code75int task_entry(int gtid, ptask task)76{77    pshareds pshar = task->shareds;78    for( task->i = task->lb; task->i <= (int)task->ub; task->i += task->st ) {79        task->th = omp_get_thread_num();80        __kmpc_atomic_fixed4_add(NULL,gtid,pshar->pcounter,1);81        __kmpc_atomic_fixed4_add(NULL,gtid,&((*pshar->pth_counter)[task->th]),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 91int main()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    for( i=0; i<N; ++i )99        th_counter[i] = 0;100    #pragma omp parallel num_threads(N)101    {102      #pragma omp master103      {104        int gtid = __kmpc_global_thread_num(NULL);105/*106 *  This is what the OpenMP runtime calls correspond to:107    #pragma omp taskloop num_tasks(N) lastprivate(j)108    for( i=0; i<N*GRAIN*STRIDE-1; i+=STRIDE )109    {110        int th = omp_get_thread_num();111        #pragma omp atomic112            counter++;113        #pragma omp atomic114            th_counter[th]++;115        j = i;116    }117*/118    task = __kmpc_omp_task_alloc(NULL,gtid,1,sizeof(struct task),sizeof(struct shar),&task_entry);119    psh = task->shareds;120    psh->pth_counter = &th_counter;121    psh->pcounter = &counter;122    psh->pj = &j;123    task->lb = 0;124    task->ub = N*GRAIN*STRIDE-2;125    task->st = STRIDE;126 127    __kmpc_taskloop(128        NULL,             // location129        gtid,             // gtid130        task,             // task structure131        1,                // if clause value132        &task->lb,        // lower bound133        &task->ub,        // upper bound134        STRIDE,           // loop increment135        0,                // 1 if nogroup specified136        2,                // schedule type: 0-none, 1-grainsize, 2-num_tasks137        N,                // schedule value (ignored for type 0)138        (void*)&__task_dup_entry // tasks duplication routine139        );140      } // end master141    } // end parallel142// check results143    if( j != N*GRAIN*STRIDE-STRIDE ) {144        printf("Error in lastprivate, %d != %d\n",j,N*GRAIN*STRIDE-STRIDE);145        return 1;146    }147    if( counter != N*GRAIN ) {148        printf("Error, counter %d != %d\n",counter,N*GRAIN);149        return 1;150    }151    for( i=0; i<N; ++i ) {152        if( th_counter[i] % GRAIN ) {153            printf("Error, th_counter[%d] = %d\n",i,th_counter[i]);154            return 1;155        }156    }157    printf("passed\n");158    return 0;159}160