brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 9e0b412 Raw
156 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 With task dependencies one can generate proxy tasks from an explicit task17 being executed by a serial task team. The OpenMP runtime library didn't18 expect that and tries to free the explicit task that is the parent of the19 proxy task still working in background. It therefore has incomplete children20 which triggers a debugging assertion.21*/22 23// Compiler-generated code (emulation)24typedef intptr_t kmp_intptr_t;25typedef int32_t kmp_int32;26typedef uint8_t kmp_uint8;27 28typedef char bool;29 30// These structs need to match the implementation within libomp, in kmp.h.31 32typedef struct ident {33    kmp_int32 reserved_1;   /**<  might be used in Fortran; see above  */34    kmp_int32 flags;        /**<  also f.flags; KMP_IDENT_xxx flags; KMP_IDENT_KMPC identifies this union member  */35    kmp_int32 reserved_2;   /**<  not really used in Fortran any more; see above */36#if USE_ITT_BUILD37                            /*  but currently used for storing region-specific ITT */38                            /*  contextual information. */39#endif /* USE_ITT_BUILD */40    kmp_int32 reserved_3;   /**< source[4] in Fortran, do not use for C++  */41    char const *psource;    /**< String describing the source location.42                            The string is composed of semi-colon separated fields which describe the source file,43                            the function and a pair of line numbers that delimit the construct.44                             */45} ident_t;46 47typedef struct kmp_depend_info {48     kmp_intptr_t               base_addr;49     size_t                     len;50     union {51        kmp_uint8 flag; // flag as an unsigned char52        struct { // flag as a set of 8 bits53#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)54          unsigned all : 1;55          unsigned unused : 3;56          unsigned set : 1;57          unsigned mtx : 1;58          unsigned out : 1;59          unsigned in : 1;60#else61          unsigned in : 1;62          unsigned out : 1;63          unsigned mtx : 1;64          unsigned set : 1;65          unsigned unused : 3;66          unsigned all : 1;67#endif68        } flags;69     };70} kmp_depend_info_t;71 72struct kmp_task;73typedef kmp_int32 (* kmp_routine_entry_t)( kmp_int32, struct kmp_task * );74 75typedef struct kmp_task {                   /* GEH: Shouldn't this be aligned somehow? */76    void *              shareds;            /**< pointer to block of pointers to shared vars   */77    kmp_routine_entry_t routine;            /**< pointer to routine to call for executing task */78    kmp_int32           part_id;            /**< part id for the task                          */79} kmp_task_t;80 81#ifdef __cplusplus82extern "C" {83#endif84kmp_int32  __kmpc_global_thread_num  ( ident_t * );85kmp_task_t*86__kmpc_omp_task_alloc( ident_t *loc_ref, kmp_int32 gtid, kmp_int32 flags,87                       size_t sizeof_kmp_task_t, size_t sizeof_shareds,88                       kmp_routine_entry_t task_entry );89void __kmpc_proxy_task_completed_ooo ( kmp_task_t *ptask );90kmp_int32 __kmpc_omp_task_with_deps ( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task,91                                      kmp_int32 ndeps, kmp_depend_info_t *dep_list,92                                      kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list );93kmp_int3294__kmpc_omp_task( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task );95#ifdef __cplusplus96}97#endif98 99void *target(void *task)100{101    my_sleep( 0.1 );102    __kmpc_proxy_task_completed_ooo((kmp_task_t*) task);103    return NULL;104}105 106pthread_t target_thread;107 108// User's code109int task_entry(kmp_int32 gtid, kmp_task_t *task)110{111    pthread_create(&target_thread, NULL, &target, task);112    return 0;113}114 115int main()116{117    int dep;118 119#pragma omp taskgroup120{121/*122 *  Corresponds to:123    #pragma omp target nowait depend(out: dep)124    {125        my_sleep( 0.1 );126    }127*/128    kmp_depend_info_t dep_info = { 0 };129    dep_info.base_addr = (kmp_intptr_t) &dep;130    dep_info.len = sizeof(int);131    // out = inout per spec and runtime expects this132    dep_info.flags.in = 1;133    dep_info.flags.out = 1;134 135    kmp_int32 gtid = __kmpc_global_thread_num(NULL);136    kmp_task_t *proxy_task = __kmpc_omp_task_alloc(NULL,gtid,17,sizeof(kmp_task_t),0,&task_entry);137    __kmpc_omp_task_with_deps(NULL,gtid,proxy_task,1,&dep_info,0,NULL);138 139    #pragma omp task depend(in: dep)140    {141/*142 *      Corresponds to:143        #pragma omp target nowait144        {145            my_sleep( 0.1 );146        }147*/148        kmp_task_t *nested_proxy_task = __kmpc_omp_task_alloc(NULL,gtid,17,sizeof(kmp_task_t),0,&task_entry);149        __kmpc_omp_task(NULL,gtid,nested_proxy_task);150    }151}152 153    // only check that it didn't crash154    return 0;155}156