LLVM OpenMP 19.0.0git
bug_nested_proxy_task.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 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.
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_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.
44 */
46
47typedef struct kmp_depend_info {
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
69 };
71
72struct 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 */
80
81#ifdef __cplusplus
82extern "C" {
83#endif
87 size_t sizeof_kmp_task_t, size_t sizeof_shareds,
91 kmp_int32 ndeps, kmp_depend_info_t *dep_list,
92 kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list );
94__kmpc_omp_task( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task );
95#ifdef __cplusplus
96}
97#endif
98
99void *target(void *task)
100{
101 my_sleep( 0.1 );
103 return NULL;
104}
105
107
108// User's code
110{
111 pthread_create(&target_thread, NULL, &target, task);
112 return 0;
113}
114
115int main()
116{
117 int dep;
118
119#pragma omp taskgroup
120{
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 this
132 dep_info.flags.in = 1;
133 dep_info.flags.out = 1;
134
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 nowait
144 {
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 crash
154 return 0;
155}
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
uint8_t kmp_uint8
pthread_t target_thread
struct kmp_depend_info kmp_depend_info_t
struct ident ident_t
intptr_t kmp_intptr_t
char bool
int main()
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:2521
struct kmp_depend_info::@8::@10 flags
size_t len
Definition: kmp.h:2506
kmp_intptr_t base_addr
Definition: kmp.h:2505
kmp_uint8 flag
Definition: kmp.h:2508
unsigned set
Definition: kmp.h:2522
unsigned out
Definition: kmp.h:2520
unsigned in
Definition: kmp.h:2519
unsigned unused
Definition: kmp.h:2523
unsigned all
Definition: kmp.h:2524
Definition: kmp.h:2463
void * shareds
pointer to block of pointers to shared vars
Definition: kmp.h:2464
kmp_int32 part_id
part id for the task
Definition: kmp.h:2467
kmp_routine_entry_t routine
pointer to routine to call for executing task
Definition: kmp.h:2466