LLVM OpenMP 19.0.0git
kmp_cancel.cpp
Go to the documentation of this file.
1
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#include "kmp.h"
11#include "kmp_i18n.h"
12#include "kmp_io.h"
13#include "kmp_str.h"
14#if OMPT_SUPPORT
15#include "ompt-specific.h"
16#endif
17
18/*!
19@ingroup CANCELLATION
20@param loc_ref location of the original task directive
21@param gtid Global thread ID of encountering thread
22@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
23
24@return returns true if the cancellation request has been activated and the
25execution thread needs to proceed to the end of the canceled region.
26
27Request cancellation of the binding OpenMP region.
28*/
30 kmp_info_t *this_thr = __kmp_threads[gtid];
31
32 KC_TRACE(10, ("__kmpc_cancel: T#%d request %d OMP_CANCELLATION=%d\n", gtid,
33 cncl_kind, __kmp_omp_cancellation));
34
35 KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
36 KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
37 cncl_kind == cancel_sections ||
38 cncl_kind == cancel_taskgroup);
40
42 switch (cncl_kind) {
43 case cancel_parallel:
44 case cancel_loop:
45 case cancel_sections:
46 // cancellation requests for parallel and worksharing constructs
47 // are handled through the team structure
48 {
49 kmp_team_t *this_team = this_thr->th.th_team;
50 KMP_DEBUG_ASSERT(this_team);
52 this_team->t.t_cancel_request.compare_exchange_strong(old, cncl_kind);
53 if (old == cancel_noreq || old == cncl_kind) {
54// we do not have a cancellation request in this team or we do have
55// one that matches the current request -> cancel
56#if OMPT_SUPPORT && OMPT_OPTIONAL
57 if (ompt_enabled.ompt_callback_cancel) {
58 ompt_data_t *task_data;
59 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
60 NULL);
61 ompt_cancel_flag_t type = ompt_cancel_parallel;
62 if (cncl_kind == cancel_parallel)
63 type = ompt_cancel_parallel;
64 else if (cncl_kind == cancel_loop)
65 type = ompt_cancel_loop;
66 else if (cncl_kind == cancel_sections)
67 type = ompt_cancel_sections;
68 ompt_callbacks.ompt_callback(ompt_callback_cancel)(
69 task_data, type | ompt_cancel_activated,
71 }
72#endif // OMPT_SUPPORT && OMPT_OPTIONAL
73 return 1 /* true */;
74 }
75 break;
76 }
78 // cancellation requests for a task group
79 // are handled through the taskgroup structure
80 {
82 kmp_taskgroup_t *taskgroup;
83
84 task = this_thr->th.th_current_task;
86
87 taskgroup = task->td_taskgroup;
88 if (taskgroup) {
90 taskgroup->cancel_request.compare_exchange_strong(old, cncl_kind);
91 if (old == cancel_noreq || old == cncl_kind) {
92// we do not have a cancellation request in this taskgroup or we do
93// have one that matches the current request -> cancel
94#if OMPT_SUPPORT && OMPT_OPTIONAL
95 if (ompt_enabled.ompt_callback_cancel) {
96 ompt_data_t *task_data;
97 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
98 NULL);
99 ompt_callbacks.ompt_callback(ompt_callback_cancel)(
100 task_data, ompt_cancel_taskgroup | ompt_cancel_activated,
102 }
103#endif
104 return 1 /* true */;
105 }
106 } else {
107 // TODO: what needs to happen here?
108 // the specification disallows cancellation w/o taskgroups
109 // so we might do anything here, let's abort for now
110 KMP_ASSERT(0 /* false */);
111 }
112 }
113 break;
114 default:
115 KMP_ASSERT(0 /* false */);
116 }
117 }
118
119 // ICV OMP_CANCELLATION=false, so we ignored this cancel request
121 return 0 /* false */;
122}
123
124/*!
125@ingroup CANCELLATION
126@param loc_ref location of the original task directive
127@param gtid Global thread ID of encountering thread
128@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
129
130@return returns true if a matching cancellation request has been flagged in the
131RTL and the encountering thread has to cancel..
132
133Cancellation point for the encountering thread.
134*/
136 kmp_int32 cncl_kind) {
137 kmp_info_t *this_thr = __kmp_threads[gtid];
138
139 KC_TRACE(10,
140 ("__kmpc_cancellationpoint: T#%d request %d OMP_CANCELLATION=%d\n",
141 gtid, cncl_kind, __kmp_omp_cancellation));
142
143 KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
144 KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
145 cncl_kind == cancel_sections ||
146 cncl_kind == cancel_taskgroup);
148
150 switch (cncl_kind) {
151 case cancel_parallel:
152 case cancel_loop:
153 case cancel_sections:
154 // cancellation requests for parallel and worksharing constructs
155 // are handled through the team structure
156 {
157 kmp_team_t *this_team = this_thr->th.th_team;
158 KMP_DEBUG_ASSERT(this_team);
159 if (this_team->t.t_cancel_request) {
160 if (cncl_kind == this_team->t.t_cancel_request) {
161// the request in the team structure matches the type of
162// cancellation point so we can cancel
163#if OMPT_SUPPORT && OMPT_OPTIONAL
164 if (ompt_enabled.ompt_callback_cancel) {
165 ompt_data_t *task_data;
166 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
167 NULL);
168 ompt_cancel_flag_t type = ompt_cancel_parallel;
169 if (cncl_kind == cancel_parallel)
170 type = ompt_cancel_parallel;
171 else if (cncl_kind == cancel_loop)
172 type = ompt_cancel_loop;
173 else if (cncl_kind == cancel_sections)
174 type = ompt_cancel_sections;
175 ompt_callbacks.ompt_callback(ompt_callback_cancel)(
176 task_data, type | ompt_cancel_detected,
178 }
179#endif
180 return 1 /* true */;
181 }
182 KMP_ASSERT(0 /* false */);
183 } else {
184 // we do not have a cancellation request pending, so we just
185 // ignore this cancellation point
186 return 0;
187 }
188 break;
189 }
190 case cancel_taskgroup:
191 // cancellation requests for a task group
192 // are handled through the taskgroup structure
193 {
195 kmp_taskgroup_t *taskgroup;
196
197 task = this_thr->th.th_current_task;
199
200 taskgroup = task->td_taskgroup;
201 if (taskgroup) {
202// return the current status of cancellation for the taskgroup
203#if OMPT_SUPPORT && OMPT_OPTIONAL
204 if (ompt_enabled.ompt_callback_cancel &&
205 !!taskgroup->cancel_request) {
206 ompt_data_t *task_data;
207 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
208 NULL);
209 ompt_callbacks.ompt_callback(ompt_callback_cancel)(
210 task_data, ompt_cancel_taskgroup | ompt_cancel_detected,
212 }
213#endif
214 return !!taskgroup->cancel_request;
215 } else {
216 // if a cancellation point is encountered by a task that does not
217 // belong to a taskgroup, it is OK to ignore it
218 return 0 /* false */;
219 }
220 }
221 default:
222 KMP_ASSERT(0 /* false */);
223 }
224 }
225
226 // ICV OMP_CANCELLATION=false, so we ignore the cancellation point
228 return 0 /* false */;
229}
230
231/*!
232@ingroup CANCELLATION
233@param loc_ref location of the original task directive
234@param gtid Global thread ID of encountering thread
235
236@return returns true if a matching cancellation request has been flagged in the
237RTL and the encountering thread has to cancel..
238
239Barrier with cancellation point to send threads from the barrier to the
240end of the parallel region. Needs a special code pattern as documented
241in the design document for the cancellation feature.
242*/
244 int ret = 0 /* false */;
245 kmp_info_t *this_thr = __kmp_threads[gtid];
246 kmp_team_t *this_team = this_thr->th.th_team;
247
249
250 // call into the standard barrier
251 __kmpc_barrier(loc, gtid);
252
253 // if cancellation is active, check cancellation flag
255 // depending on which construct to cancel, check the flag and
256 // reset the flag
257 switch (KMP_ATOMIC_LD_RLX(&(this_team->t.t_cancel_request))) {
258 case cancel_parallel:
259 ret = 1;
260 // ensure that threads have checked the flag, when
261 // leaving the above barrier
262 __kmpc_barrier(loc, gtid);
263 this_team->t.t_cancel_request = cancel_noreq;
264 // the next barrier is the fork/join barrier, which
265 // synchronizes the threads leaving here
266 break;
267 case cancel_loop:
268 case cancel_sections:
269 ret = 1;
270 // ensure that threads have checked the flag, when
271 // leaving the above barrier
272 __kmpc_barrier(loc, gtid);
273 this_team->t.t_cancel_request = cancel_noreq;
274 // synchronize the threads again to make sure we do not have any run-away
275 // threads that cause a race on the cancellation flag
276 __kmpc_barrier(loc, gtid);
277 break;
278 case cancel_taskgroup:
279 // this case should not occur
280 KMP_ASSERT(0 /* false */);
281 break;
282 case cancel_noreq:
283 // do nothing
284 break;
285 default:
286 KMP_ASSERT(0 /* false */);
287 }
288 }
289
290 return ret;
291}
292
293/*!
294@ingroup CANCELLATION
295@param loc_ref location of the original task directive
296@param gtid Global thread ID of encountering thread
297
298@return returns true if a matching cancellation request has been flagged in the
299RTL and the encountering thread has to cancel..
300
301Query function to query the current status of cancellation requests.
302Can be used to implement the following pattern:
303
304if (kmp_get_cancellation_status(kmp_cancel_parallel)) {
305 perform_cleanup();
306 #pragma omp cancellation point parallel
307}
308*/
309int __kmp_get_cancellation_status(int cancel_kind) {
311 kmp_info_t *this_thr = __kmp_entry_thread();
312
313 switch (cancel_kind) {
314 case cancel_parallel:
315 case cancel_loop:
316 case cancel_sections: {
317 kmp_team_t *this_team = this_thr->th.th_team;
318 return this_team->t.t_cancel_request == cancel_kind;
319 }
320 case cancel_taskgroup: {
322 kmp_taskgroup_t *taskgroup;
323 task = this_thr->th.th_current_task;
324 taskgroup = task->td_taskgroup;
325 return taskgroup && taskgroup->cancel_request;
326 }
327 }
328 }
329
330 return 0 /* false */;
331}
KMP_EXPORT void __kmpc_barrier(ident_t *, kmp_int32 global_tid)
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 type
int __kmp_omp_cancellation
Definition: kmp_global.cpp:215
@ cancel_parallel
Definition: kmp.h:999
@ cancel_taskgroup
Definition: kmp.h:1002
@ cancel_sections
Definition: kmp.h:1001
@ cancel_loop
Definition: kmp.h:1000
@ cancel_noreq
Definition: kmp.h:998
static kmp_info_t * __kmp_entry_thread()
Definition: kmp.h:3731
kmp_info_t ** __kmp_threads
Definition: kmp_global.cpp:450
#define __kmp_get_gtid()
Definition: kmp.h:3600
union KMP_ALIGN_CACHE kmp_info kmp_info_t
kmp_int32 __kmpc_cancellationpoint(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind)
Definition: kmp_cancel.cpp:135
int __kmp_get_cancellation_status(int cancel_kind)
Definition: kmp_cancel.cpp:309
kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid)
Definition: kmp_cancel.cpp:243
kmp_int32 __kmpc_cancel(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind)
Definition: kmp_cancel.cpp:29
#define KMP_ASSERT(cond)
Definition: kmp_debug.h:59
#define KC_TRACE(d, x)
Definition: kmp_debug.h:159
#define KMP_DEBUG_ASSERT(cond)
Definition: kmp_debug.h:61
#define KMP_ATOMIC_LD_RLX(p)
Definition: kmp_os.h:1258
int32_t kmp_int32
ompt_callbacks_active_t ompt_enabled
return ret
ompt_callbacks_internal_t ompt_callbacks
#define OMPT_GET_RETURN_ADDRESS(level)
int __ompt_get_task_info_internal(int ancestor_level, int *type, ompt_data_t **task_data, ompt_frame_t **task_frame, ompt_data_t **parallel_data, int *thread_num)
static id loc
std::atomic< kmp_int32 > cancel_request
Definition: kmp.h:2482
int th
Definition: kmp_taskloop.c:38
Definition: kmp.h:3215
kmp_base_team_t t
Definition: kmp.h:3216