LLVM OpenMP 20.0.0git
bug_proxy_task_dep_waiting.c
Go to the documentation of this file.
1// RUN: %libomp-compile-and-run
2// The runtime currently does not get dependency information from GCC.
3// UNSUPPORTED: gcc
4
5// Very flaky on openmp-clang-x86_64-linux-debian.
6// https://bugs.llvm.org/show_bug.cgi?id=45397
7// UNSUPPORTED: linux
8
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 not
17 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_BUILD
34 /* 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 */
43
44typedef struct kmp_depend_info {
46 size_t len;
47 union {
48 kmp_uint8 flag; // flag as an unsigned char
49 struct { // flag as a set of 8 bits
50#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#else
58 unsigned in : 1;
59 unsigned out : 1;
60 unsigned mtx : 1;
61 unsigned set : 1;
62 unsigned unused : 3;
63 unsigned all : 1;
64#endif
66 };
68
69struct 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 */
77
78#ifdef __cplusplus
79extern "C" {
80#endif
84 size_t sizeof_kmp_task_t, size_t sizeof_shareds,
88 kmp_int32 ndeps, kmp_depend_info_t *dep_list,
89 kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list );
91__kmpc_omp_task( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task );
92#ifdef __cplusplus
93}
94#endif
95
96void *target(void *task)
97{
98 my_sleep( 0.1 );
100 return NULL;
101}
102
104
105// User's code
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 this
127 dep_info.flags.in = 1;
128 dep_info.flags.out = 1;
129
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 waited
147 // for the dependencies to be satisfied.
148 int error = (first_task_finished == 1);
149 error += (second_task_finished == 1);
150
151 #pragma omp taskwait
152
153 // by now all tasks should have finished
154 error += (first_task_finished != 1);
155 error += (second_task_finished != 1);
156
157 return error;
158}
uint8_t kmp_uint8
void * target(void *task)
kmp_task_t * __kmpc_omp_task_alloc(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, kmp_routine_entry_t task_entry)
kmp_int32 __kmpc_omp_task(ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *new_task)
int32_t kmp_int32
struct kmp_task kmp_task_t
pthread_t target_thread
struct kmp_depend_info kmp_depend_info_t
struct ident ident_t
uint8_t kmp_uint8
intptr_t kmp_intptr_t
int task_entry(kmp_int32 gtid, kmp_task_t *task)
kmp_int32(*)(kmp_int32, void *) kmp_routine_entry_t
Definition: common.h:11
void __kmpc_proxy_task_completed_ooo(kmp_task_t *ptask)
kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list)
kmp_int32 __kmpc_global_thread_num(ident_t *)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
long kmp_intptr_t
Definition: kmp_os.h:204
int32_t kmp_int32
static void my_sleep(double sleeptime)
Utility function to have a sleep function with better resolution and which only stops one thread.
Definition: omp_my_sleep.h:24
struct DEP dep
The ident structure that describes a source location.
Definition: kmp.h:247
char const * psource
String describing the source location.
Definition: kmp.h:257
kmp_int32 reserved_1
might be used in Fortran; see above
Definition: kmp.h:248
kmp_int32 reserved_2
not really used in Fortran any more; see above
Definition: kmp.h:251
kmp_int32 reserved_3
source[4] in Fortran, do not use for C++
Definition: kmp.h:256
kmp_int32 flags
also f.flags; KMP_IDENT_xxx flags; KMP_IDENT_KMPC identifies this union member
Definition: kmp.h:249
unsigned mtx
Definition: kmp.h:2530
struct kmp_depend_info::@8::@10 flags
size_t len
Definition: kmp.h:2515
kmp_intptr_t base_addr
Definition: kmp.h:2514
kmp_uint8 flag
Definition: kmp.h:2517
unsigned set
Definition: kmp.h:2531
unsigned out
Definition: kmp.h:2529
unsigned in
Definition: kmp.h:2528
unsigned unused
Definition: kmp.h:2532
unsigned all
Definition: kmp.h:2533
Definition: kmp.h:2472
void * shareds
pointer to block of pointers to shared vars
Definition: kmp.h:2473
kmp_int32 part_id
part id for the task
Definition: kmp.h:2476
kmp_routine_entry_t routine
pointer to routine to call for executing task
Definition: kmp.h:2475