blob: bdf6bd18580a4678908f34ce8e9ba0315bc34513 [file] [log] [blame]
Andrey Churbanove5f44922015-04-29 16:22:07 +00001//******************************************************************************
2// include files
3//******************************************************************************
4
5#include "kmp.h"
Andrey Churbanove5f44922015-04-29 16:22:07 +00006#include "ompt-specific.h"
7
Joachim Protze82e94a52017-11-01 10:08:30 +00008#if KMP_OS_UNIX
9#include <dlfcn.h>
10#endif
11
12#if KMP_OS_WINDOWS
13#define THREAD_LOCAL __declspec(thread)
14#else
15#define THREAD_LOCAL __thread
16#endif
17
Andrey Churbanove5f44922015-04-29 16:22:07 +000018//******************************************************************************
19// macros
20//******************************************************************************
21
Joachim Protze82e94a52017-11-01 10:08:30 +000022#define LWT_FROM_TEAM(team) (team)->t.ompt_serialized_team_info
Andrey Churbanove5f44922015-04-29 16:22:07 +000023
24#define OMPT_THREAD_ID_BITS 16
25
Andrey Churbanove5f44922015-04-29 16:22:07 +000026//******************************************************************************
27// private operations
28//******************************************************************************
29
30//----------------------------------------------------------
31// traverse the team and task hierarchy
Joachim Protze82e94a52017-11-01 10:08:30 +000032// note: __ompt_get_teaminfo and __ompt_get_task_info_object
Andrey Churbanove5f44922015-04-29 16:22:07 +000033// traverse the hierarchy similarly and need to be
34// kept consistent
35//----------------------------------------------------------
36
Jonathan Peyton30419822017-05-12 18:01:32 +000037ompt_team_info_t *__ompt_get_teaminfo(int depth, int *size) {
38 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +000039
Jonathan Peyton30419822017-05-12 18:01:32 +000040 if (thr) {
41 kmp_team *team = thr->th.th_team;
42 if (team == NULL)
43 return NULL;
Jonathan Peytonf0344bb2015-10-09 17:42:52 +000044
Joachim Protze82e94a52017-11-01 10:08:30 +000045 ompt_lw_taskteam_t *next_lwt = LWT_FROM_TEAM(team), *lwt = NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +000046
Jonathan Peyton30419822017-05-12 18:01:32 +000047 while (depth > 0) {
48 // next lightweight team (if any)
49 if (lwt)
50 lwt = lwt->parent;
Andrey Churbanove5f44922015-04-29 16:22:07 +000051
Jonathan Peyton30419822017-05-12 18:01:32 +000052 // next heavyweight team (if any) after
53 // lightweight teams are exhausted
54 if (!lwt && team) {
Joachim Protze82e94a52017-11-01 10:08:30 +000055 if (next_lwt) {
56 lwt = next_lwt;
57 next_lwt = NULL;
58 } else {
59 team = team->t.t_parent;
60 if (team) {
61 next_lwt = LWT_FROM_TEAM(team);
62 }
Andrey Churbanove5f44922015-04-29 16:22:07 +000063 }
Jonathan Peyton30419822017-05-12 18:01:32 +000064 }
Andrey Churbanove5f44922015-04-29 16:22:07 +000065
Jonathan Peyton30419822017-05-12 18:01:32 +000066 depth--;
Andrey Churbanove5f44922015-04-29 16:22:07 +000067 }
68
Jonathan Peyton30419822017-05-12 18:01:32 +000069 if (lwt) {
70 // lightweight teams have one task
71 if (size)
72 *size = 1;
73
74 // return team info for lightweight team
75 return &lwt->ompt_team_info;
76 } else if (team) {
77 // extract size from heavyweight team
78 if (size)
79 *size = team->t.t_nproc;
80
81 // return team info for heavyweight team
82 return &team->t.ompt_team_info;
83 }
84 }
85
86 return NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +000087}
88
Joachim Protze82e94a52017-11-01 10:08:30 +000089ompt_task_info_t *__ompt_get_task_info_object(int depth) {
Jonathan Peyton30419822017-05-12 18:01:32 +000090 ompt_task_info_t *info = NULL;
91 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +000092
Jonathan Peyton30419822017-05-12 18:01:32 +000093 if (thr) {
94 kmp_taskdata_t *taskdata = thr->th.th_current_task;
Joachim Protze82e94a52017-11-01 10:08:30 +000095 ompt_lw_taskteam_t *lwt = NULL,
96 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +000097
Jonathan Peyton30419822017-05-12 18:01:32 +000098 while (depth > 0) {
99 // next lightweight team (if any)
100 if (lwt)
101 lwt = lwt->parent;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000102
Jonathan Peyton30419822017-05-12 18:01:32 +0000103 // next heavyweight team (if any) after
104 // lightweight teams are exhausted
105 if (!lwt && taskdata) {
Joachim Protze82e94a52017-11-01 10:08:30 +0000106 if (next_lwt) {
107 lwt = next_lwt;
108 next_lwt = NULL;
109 } else {
110 taskdata = taskdata->td_parent;
111 if (taskdata) {
112 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
113 }
114 }
115 }
116 depth--;
117 }
118
119 if (lwt) {
120 info = &lwt->ompt_task_info;
121 } else if (taskdata) {
122 info = &taskdata->ompt_task_info;
123 }
124 }
125
126 return info;
127}
128
129ompt_task_info_t *__ompt_get_scheduling_taskinfo(int depth) {
130 ompt_task_info_t *info = NULL;
131 kmp_info_t *thr = ompt_get_thread();
132
133 if (thr) {
134 kmp_taskdata_t *taskdata = thr->th.th_current_task;
135
136 ompt_lw_taskteam_t *lwt = NULL,
137 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
138
139 while (depth > 0) {
140 // next lightweight team (if any)
141 if (lwt)
142 lwt = lwt->parent;
143
144 // next heavyweight team (if any) after
145 // lightweight teams are exhausted
146 if (!lwt && taskdata) {
147 // first try scheduling parent (for explicit task scheduling)
148 if (taskdata->ompt_task_info.scheduling_parent) {
149 taskdata = taskdata->ompt_task_info.scheduling_parent;
150 } else if (next_lwt) {
151 lwt = next_lwt;
152 next_lwt = NULL;
153 } else {
154 // then go for implicit tasks
155 taskdata = taskdata->td_parent;
156 if (taskdata) {
157 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
158 }
Andrey Churbanove5f44922015-04-29 16:22:07 +0000159 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000160 }
161 depth--;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000162 }
163
Jonathan Peyton30419822017-05-12 18:01:32 +0000164 if (lwt) {
165 info = &lwt->ompt_task_info;
166 } else if (taskdata) {
167 info = &taskdata->ompt_task_info;
168 }
169 }
170
171 return info;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000172}
173
Andrey Churbanove5f44922015-04-29 16:22:07 +0000174//******************************************************************************
175// interface operations
176//******************************************************************************
177
178//----------------------------------------------------------
Andrey Churbanove5f44922015-04-29 16:22:07 +0000179// thread support
180//----------------------------------------------------------
181
Joachim Protze82e94a52017-11-01 10:08:30 +0000182ompt_data_t *__ompt_get_thread_data_internal() {
183 if (__kmp_get_gtid() >= 0) {
184 kmp_info_t *thread = ompt_get_thread();
185 if (thread == NULL)
186 return NULL;
187 return &(thread->th.ompt_thread_info.thread_data);
188 }
189 return NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000190}
191
192//----------------------------------------------------------
193// state support
194//----------------------------------------------------------
195
Jonathan Peyton30419822017-05-12 18:01:32 +0000196void __ompt_thread_assign_wait_id(void *variable) {
Joachim Protze82e94a52017-11-01 10:08:30 +0000197 kmp_info_t *ti = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000198
Jonathan Peyton30419822017-05-12 18:01:32 +0000199 ti->th.ompt_thread_info.wait_id = (ompt_wait_id_t)variable;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000200}
201
Joachim Protze82e94a52017-11-01 10:08:30 +0000202omp_state_t __ompt_get_state_internal(ompt_wait_id_t *ompt_wait_id) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000203 kmp_info_t *ti = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000204
Jonathan Peyton30419822017-05-12 18:01:32 +0000205 if (ti) {
206 if (ompt_wait_id)
207 *ompt_wait_id = ti->th.ompt_thread_info.wait_id;
208 return ti->th.ompt_thread_info.state;
209 }
Joachim Protze82e94a52017-11-01 10:08:30 +0000210 return omp_state_undefined;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000211}
212
Andrey Churbanove5f44922015-04-29 16:22:07 +0000213//----------------------------------------------------------
214// parallel region support
215//----------------------------------------------------------
216
Joachim Protze82e94a52017-11-01 10:08:30 +0000217int __ompt_get_parallel_info_internal(int ancestor_level,
218 ompt_data_t **parallel_data,
219 int *team_size) {
220 ompt_team_info_t *info;
221 if (team_size) {
222 info = __ompt_get_teaminfo(ancestor_level, team_size);
223 } else {
224 info = __ompt_get_teaminfo(ancestor_level, NULL);
225 }
226 if (parallel_data) {
227 *parallel_data = info ? &(info->parallel_data) : NULL;
228 }
229 return info ? 2 : 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000230}
231
Andrey Churbanove5f44922015-04-29 16:22:07 +0000232//----------------------------------------------------------
233// lightweight task team support
234//----------------------------------------------------------
235
Jonathan Peyton30419822017-05-12 18:01:32 +0000236void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid,
Joachim Protze82e94a52017-11-01 10:08:30 +0000237 ompt_data_t *ompt_pid, void *codeptr) {
238 // initialize parallel_data with input, return address to parallel_data on
239 // exit
240 lwt->ompt_team_info.parallel_data = *ompt_pid;
241 lwt->ompt_team_info.master_return_address = codeptr;
242 lwt->ompt_task_info.task_data.value = 0;
Jonathan Peyton30419822017-05-12 18:01:32 +0000243 lwt->ompt_task_info.frame.reenter_runtime_frame = NULL;
244 lwt->ompt_task_info.frame.exit_runtime_frame = NULL;
Joachim Protze82e94a52017-11-01 10:08:30 +0000245 lwt->ompt_task_info.scheduling_parent = NULL;
246 lwt->ompt_task_info.deps = NULL;
247 lwt->ompt_task_info.ndeps = 0;
248 lwt->heap = 0;
Jonathan Peyton30419822017-05-12 18:01:32 +0000249 lwt->parent = 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000250}
251
Joachim Protze82e94a52017-11-01 10:08:30 +0000252void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr,
253 int on_heap) {
254 ompt_lw_taskteam_t *link_lwt = lwt;
255 if (thr->th.th_team->t.t_serialized >
256 1) { // we already have a team, so link the new team and swap values
257 if (on_heap) { // the lw_taskteam cannot stay on stack, allocate it on heap
258 link_lwt =
259 (ompt_lw_taskteam_t *)__kmp_allocate(sizeof(ompt_lw_taskteam_t));
260 }
261 link_lwt->heap = on_heap;
262
263 // would be swap in the (on_stack) case.
264 ompt_team_info_t tmp_team = lwt->ompt_team_info;
265 link_lwt->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr);
266 *OMPT_CUR_TEAM_INFO(thr) = tmp_team;
267
268 ompt_task_info_t tmp_task = lwt->ompt_task_info;
269 link_lwt->ompt_task_info = *OMPT_CUR_TASK_INFO(thr);
270 *OMPT_CUR_TASK_INFO(thr) = tmp_task;
271
272 // link the taskteam into the list of taskteams:
273 ompt_lw_taskteam_t *my_parent =
274 thr->th.th_team->t.ompt_serialized_team_info;
275 link_lwt->parent = my_parent;
276 thr->th.th_team->t.ompt_serialized_team_info = link_lwt;
277 } else {
278 // this is the first serialized team, so we just store the values in the
279 // team and drop the taskteam-object
280 *OMPT_CUR_TEAM_INFO(thr) = lwt->ompt_team_info;
281 *OMPT_CUR_TASK_INFO(thr) = lwt->ompt_task_info;
282 }
Andrey Churbanove5f44922015-04-29 16:22:07 +0000283}
284
Joachim Protze82e94a52017-11-01 10:08:30 +0000285void __ompt_lw_taskteam_unlink(kmp_info_t *thr) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000286 ompt_lw_taskteam_t *lwtask = thr->th.th_team->t.ompt_serialized_team_info;
Joachim Protze82e94a52017-11-01 10:08:30 +0000287 if (lwtask) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000288 thr->th.th_team->t.ompt_serialized_team_info = lwtask->parent;
Joachim Protze82e94a52017-11-01 10:08:30 +0000289
290 ompt_team_info_t tmp_team = lwtask->ompt_team_info;
291 lwtask->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr);
292 *OMPT_CUR_TEAM_INFO(thr) = tmp_team;
293
294 ompt_task_info_t tmp_task = lwtask->ompt_task_info;
295 lwtask->ompt_task_info = *OMPT_CUR_TASK_INFO(thr);
296 *OMPT_CUR_TASK_INFO(thr) = tmp_task;
297
298 if (lwtask->heap) {
299 __kmp_free(lwtask);
300 lwtask = NULL;
301 }
302 }
303 // return lwtask;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000304}
305
Andrey Churbanove5f44922015-04-29 16:22:07 +0000306//----------------------------------------------------------
307// task support
308//----------------------------------------------------------
309
Joachim Protze82e94a52017-11-01 10:08:30 +0000310int __ompt_get_task_info_internal(int ancestor_level, int *type,
311 ompt_data_t **task_data,
312 ompt_frame_t **task_frame,
313 ompt_data_t **parallel_data,
314 int *thread_num) {
315 if (ancestor_level < 0)
316 return 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000317
Joachim Protze82e94a52017-11-01 10:08:30 +0000318 // copied from __ompt_get_scheduling_taskinfo
319 ompt_task_info_t *info = NULL;
320 ompt_team_info_t *team_info = NULL;
321 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000322
Joachim Protze82e94a52017-11-01 10:08:30 +0000323 if (thr) {
324 kmp_taskdata_t *taskdata = thr->th.th_current_task;
325 if (taskdata == NULL)
326 return 0;
327 kmp_team *team = thr->th.th_team;
328 if (team == NULL)
329 return 0;
330 ompt_lw_taskteam_t *lwt = NULL,
331 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000332
Joachim Protze82e94a52017-11-01 10:08:30 +0000333 while (ancestor_level > 0) {
334 // next lightweight team (if any)
335 if (lwt)
336 lwt = lwt->parent;
337
338 // next heavyweight team (if any) after
339 // lightweight teams are exhausted
340 if (!lwt && taskdata) {
341 // first try scheduling parent (for explicit task scheduling)
342 if (taskdata->ompt_task_info.scheduling_parent) {
343 taskdata = taskdata->ompt_task_info.scheduling_parent;
344 } else if (next_lwt) {
345 lwt = next_lwt;
346 next_lwt = NULL;
347 } else {
348 // then go for implicit tasks
349 taskdata = taskdata->td_parent;
350 if (team == NULL)
351 return 0;
352 team = team->t.t_parent;
353 if (taskdata) {
354 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
355 }
356 }
357 }
358 ancestor_level--;
359 }
360
361 if (lwt) {
362 info = &lwt->ompt_task_info;
363 team_info = &lwt->ompt_team_info;
364 if (type) {
365 *type = ompt_task_implicit;
366 }
367 } else if (taskdata) {
368 info = &taskdata->ompt_task_info;
369 team_info = &team->t.ompt_team_info;
370 if (type) {
371 if (taskdata->td_parent) {
372 *type = (taskdata->td_flags.tasktype ? ompt_task_explicit
373 : ompt_task_implicit) |
374 TASK_TYPE_DETAILS_FORMAT(taskdata);
375 } else {
376 *type = ompt_task_initial;
377 }
378 }
379 }
380 if (task_data) {
381 *task_data = info ? &info->task_data : NULL;
382 }
383 if (task_frame) {
384 // OpenMP spec asks for the scheduling task to be returned.
385 *task_frame = info ? &info->frame : NULL;
386 }
387 if (parallel_data) {
388 *parallel_data = team_info ? &(team_info->parallel_data) : NULL;
389 }
390 return info ? 2 : 0;
391 }
392 return 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000393}
394
Andrey Churbanove5f44922015-04-29 16:22:07 +0000395//----------------------------------------------------------
396// team support
397//----------------------------------------------------------
398
Joachim Protze82e94a52017-11-01 10:08:30 +0000399void __ompt_team_assign_id(kmp_team_t *team, ompt_data_t ompt_pid) {
400 team->t.ompt_team_info.parallel_data = ompt_pid;
401}
402
403//----------------------------------------------------------
404// misc
405//----------------------------------------------------------
406
407static uint64_t __ompt_get_unique_id_internal() {
408 static uint64_t thread = 1;
409 static THREAD_LOCAL uint64_t ID = 0;
410 if (ID == 0) {
411 uint64_t new_thread = KMP_TEST_THEN_INC64((kmp_int64 *)&thread);
412 ID = new_thread << (sizeof(uint64_t) * 8 - OMPT_THREAD_ID_BITS);
413 }
414 return ++ID;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000415}