brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 1e86d57 Raw
159 lines · c
1// RUN: %libomp-compile-and-run2// The runtime currently does not get dependency information from GCC.3// UNSUPPORTED: gcc4 5// Very flaky on openmp-clang-x86_64-linux-debian.6// https://bugs.llvm.org/show_bug.cgi?id=453977// UNSUPPORTED: linux8 9#include <stdint.h>10#include <stdio.h>11#include <omp.h>12#include "omp_testsuite.h"13#include "omp_my_sleep.h"14 15/*16 An explicit task can have a dependency on a target task. If it is not17 directly satisfied, the runtime should not wait but resume execution.18*/19 20// Compiler-generated code (emulation)21typedef intptr_t kmp_intptr_t;22typedef int32_t kmp_int32;23typedef uint8_t kmp_uint8;24 25typedef char bool;26 27// These structs need to match the implementation within libomp, in kmp.h.28 29typedef struct ident {30    kmp_int32 reserved_1;   /**<  might be used in Fortran; see above  */31    kmp_int32 flags;        /**<  also f.flags; KMP_IDENT_xxx flags; KMP_IDENT_KMPC identifies this union member  */32    kmp_int32 reserved_2;   /**<  not really used in Fortran any more; see above */33#if USE_ITT_BUILD34                            /*  but currently used for storing region-specific ITT */35                            /*  contextual information. */36#endif /* USE_ITT_BUILD */37    kmp_int32 reserved_3;   /**< source[4] in Fortran, do not use for C++  */38    char const *psource;    /**< String describing the source location.39                            The string is composed of semi-colon separated fields which describe the source file,40                            the function and a pair of line numbers that delimit the construct.41                             */42} ident_t;43 44typedef struct kmp_depend_info {45     kmp_intptr_t               base_addr;46     size_t                     len;47     union {48        kmp_uint8 flag; // flag as an unsigned char49        struct { // flag as a set of 8 bits50#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)51          unsigned all : 1;52          unsigned unused : 3;53          unsigned set : 1;54          unsigned mtx : 1;55          unsigned out : 1;56          unsigned in : 1;57#else58          unsigned in : 1;59          unsigned out : 1;60          unsigned mtx : 1;61          unsigned set : 1;62          unsigned unused : 3;63          unsigned all : 1;64#endif65        } flags;66    };67} kmp_depend_info_t;68 69struct kmp_task;70typedef kmp_int32 (* kmp_routine_entry_t)( kmp_int32, struct kmp_task * );71 72typedef struct kmp_task {                   /* GEH: Shouldn't this be aligned somehow? */73    void *              shareds;            /**< pointer to block of pointers to shared vars   */74    kmp_routine_entry_t routine;            /**< pointer to routine to call for executing task */75    kmp_int32           part_id;            /**< part id for the task                          */76} kmp_task_t;77 78#ifdef __cplusplus79extern "C" {80#endif81kmp_int32  __kmpc_global_thread_num  ( ident_t * );82kmp_task_t*83__kmpc_omp_task_alloc( ident_t *loc_ref, kmp_int32 gtid, kmp_int32 flags,84                       size_t sizeof_kmp_task_t, size_t sizeof_shareds,85                       kmp_routine_entry_t task_entry );86void __kmpc_proxy_task_completed_ooo ( kmp_task_t *ptask );87kmp_int32 __kmpc_omp_task_with_deps ( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task,88                                      kmp_int32 ndeps, kmp_depend_info_t *dep_list,89                                      kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list );90kmp_int3291__kmpc_omp_task( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task );92#ifdef __cplusplus93}94#endif95 96void *target(void *task)97{98    my_sleep( 0.1 );99    __kmpc_proxy_task_completed_ooo((kmp_task_t*) task);100    return NULL;101}102 103pthread_t target_thread;104 105// User's code106int task_entry(kmp_int32 gtid, kmp_task_t *task)107{108    pthread_create(&target_thread, NULL, &target, task);109    return 0;110}111 112int main()113{114    int dep;115 116/*117 *  Corresponds to:118    #pragma omp target nowait depend(out: dep)119    {120        my_sleep( 0.1 );121    }122*/123    kmp_depend_info_t dep_info = { 0 };124    dep_info.base_addr = (kmp_intptr_t) &dep;125    dep_info.len = sizeof(int);126    // out = inout per spec and runtime expects this127    dep_info.flags.in = 1;128    dep_info.flags.out = 1;129 130    kmp_int32 gtid = __kmpc_global_thread_num(NULL);131    kmp_task_t *proxy_task = __kmpc_omp_task_alloc(NULL,gtid,17,sizeof(kmp_task_t),0,&task_entry);132    __kmpc_omp_task_with_deps(NULL,gtid,proxy_task,1,&dep_info,0,NULL);133 134    int first_task_finished = 0;135    #pragma omp task shared(first_task_finished) depend(inout: dep)136    {137        first_task_finished = 1;138    }139 140    int second_task_finished = 0;141    #pragma omp task shared(second_task_finished) depend(in: dep)142    {143        second_task_finished = 1;144    }145 146    // check that execution has been resumed and the runtime has not waited147    // for the dependencies to be satisfied.148    int error = (first_task_finished == 1);149    error += (second_task_finished == 1);150 151    #pragma omp taskwait152 153    // by now all tasks should have finished154    error += (first_task_finished != 1);155    error += (second_task_finished != 1);156 157    return error;158}159