[flang][cuda] Do not register global constants (#118582)
[llvm-project.git] / openmp / runtime / test / tasking / bug_nested_proxy_task.c
blob9e0b412efce6092213d33e09459ac36a43474acd
1 // RUN: %libomp-compile-and-run
2 // The runtime currently does not get dependency information from GCC.
3 // UNSUPPORTED: gcc
5 // Very flaky on openmp-clang-x86_64-linux-debian.
6 // https://bugs.llvm.org/show_bug.cgi?id=45397
7 // UNSUPPORTED: linux
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <omp.h>
12 #include "omp_testsuite.h"
13 #include "omp_my_sleep.h"
16 With task dependencies one can generate proxy tasks from an explicit task
17 being executed by a serial task team. The OpenMP runtime library didn't
18 expect that and tries to free the explicit task that is the parent of the
19 proxy task still working in background. It therefore has incomplete children
20 which triggers a debugging assertion.
23 // Compiler-generated code (emulation)
24 typedef intptr_t kmp_intptr_t;
25 typedef int32_t kmp_int32;
26 typedef uint8_t kmp_uint8;
28 typedef char bool;
30 // These structs need to match the implementation within libomp, in kmp.h.
32 typedef 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_BUILD
37 /* 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.
45 } ident_t;
47 typedef struct kmp_depend_info {
48 kmp_intptr_t base_addr;
49 size_t len;
50 union {
51 kmp_uint8 flag; // flag as an unsigned char
52 struct { // flag as a set of 8 bits
53 #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 #else
61 unsigned in : 1;
62 unsigned out : 1;
63 unsigned mtx : 1;
64 unsigned set : 1;
65 unsigned unused : 3;
66 unsigned all : 1;
67 #endif
68 } flags;
70 } kmp_depend_info_t;
72 struct kmp_task;
73 typedef kmp_int32 (* kmp_routine_entry_t)( kmp_int32, struct kmp_task * );
75 typedef 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;
81 #ifdef __cplusplus
82 extern "C" {
83 #endif
84 kmp_int32 __kmpc_global_thread_num ( ident_t * );
85 kmp_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 );
89 void __kmpc_proxy_task_completed_ooo ( kmp_task_t *ptask );
90 kmp_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 );
93 kmp_int32
94 __kmpc_omp_task( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task );
95 #ifdef __cplusplus
97 #endif
99 void *target(void *task)
101 my_sleep( 0.1 );
102 __kmpc_proxy_task_completed_ooo((kmp_task_t*) task);
103 return NULL;
106 pthread_t target_thread;
108 // User's code
109 int task_entry(kmp_int32 gtid, kmp_task_t *task)
111 pthread_create(&target_thread, NULL, &target, task);
112 return 0;
115 int main()
117 int dep;
119 #pragma omp taskgroup
122 * Corresponds to:
123 #pragma omp target nowait depend(out: dep)
125 my_sleep( 0.1 );
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 this
132 dep_info.flags.in = 1;
133 dep_info.flags.out = 1;
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);
139 #pragma omp task depend(in: dep)
142 * Corresponds to:
143 #pragma omp target nowait
145 my_sleep( 0.1 );
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);
153 // only check that it didn't crash
154 return 0;