blob: 5488c6ede99138b4e5d683171d57a59c469879a7 [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
Jonathan Peyton40039ac2017-11-07 23:32:13 +000018#define OMPT_WEAK_ATTRIBUTE KMP_WEAK_ATTRIBUTE
19
Andrey Churbanove5f44922015-04-29 16:22:07 +000020//******************************************************************************
21// macros
22//******************************************************************************
23
Joachim Protze82e94a52017-11-01 10:08:30 +000024#define LWT_FROM_TEAM(team) (team)->t.ompt_serialized_team_info
Andrey Churbanove5f44922015-04-29 16:22:07 +000025
26#define OMPT_THREAD_ID_BITS 16
27
Andrey Churbanove5f44922015-04-29 16:22:07 +000028//******************************************************************************
29// private operations
30//******************************************************************************
31
32//----------------------------------------------------------
33// traverse the team and task hierarchy
Joachim Protze82e94a52017-11-01 10:08:30 +000034// note: __ompt_get_teaminfo and __ompt_get_task_info_object
Andrey Churbanove5f44922015-04-29 16:22:07 +000035// traverse the hierarchy similarly and need to be
36// kept consistent
37//----------------------------------------------------------
38
Jonathan Peyton30419822017-05-12 18:01:32 +000039ompt_team_info_t *__ompt_get_teaminfo(int depth, int *size) {
40 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +000041
Jonathan Peyton30419822017-05-12 18:01:32 +000042 if (thr) {
43 kmp_team *team = thr->th.th_team;
44 if (team == NULL)
45 return NULL;
Jonathan Peytonf0344bb2015-10-09 17:42:52 +000046
Joachim Protze82e94a52017-11-01 10:08:30 +000047 ompt_lw_taskteam_t *next_lwt = LWT_FROM_TEAM(team), *lwt = NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +000048
Jonathan Peyton30419822017-05-12 18:01:32 +000049 while (depth > 0) {
50 // next lightweight team (if any)
51 if (lwt)
52 lwt = lwt->parent;
Andrey Churbanove5f44922015-04-29 16:22:07 +000053
Jonathan Peyton30419822017-05-12 18:01:32 +000054 // next heavyweight team (if any) after
55 // lightweight teams are exhausted
56 if (!lwt && team) {
Joachim Protze82e94a52017-11-01 10:08:30 +000057 if (next_lwt) {
58 lwt = next_lwt;
59 next_lwt = NULL;
60 } else {
61 team = team->t.t_parent;
62 if (team) {
63 next_lwt = LWT_FROM_TEAM(team);
64 }
Andrey Churbanove5f44922015-04-29 16:22:07 +000065 }
Jonathan Peyton30419822017-05-12 18:01:32 +000066 }
Andrey Churbanove5f44922015-04-29 16:22:07 +000067
Jonathan Peyton30419822017-05-12 18:01:32 +000068 depth--;
Andrey Churbanove5f44922015-04-29 16:22:07 +000069 }
70
Jonathan Peyton30419822017-05-12 18:01:32 +000071 if (lwt) {
72 // lightweight teams have one task
73 if (size)
74 *size = 1;
75
76 // return team info for lightweight team
77 return &lwt->ompt_team_info;
78 } else if (team) {
79 // extract size from heavyweight team
80 if (size)
81 *size = team->t.t_nproc;
82
83 // return team info for heavyweight team
84 return &team->t.ompt_team_info;
85 }
86 }
87
88 return NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +000089}
90
Joachim Protze82e94a52017-11-01 10:08:30 +000091ompt_task_info_t *__ompt_get_task_info_object(int depth) {
Jonathan Peyton30419822017-05-12 18:01:32 +000092 ompt_task_info_t *info = NULL;
93 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +000094
Jonathan Peyton30419822017-05-12 18:01:32 +000095 if (thr) {
96 kmp_taskdata_t *taskdata = thr->th.th_current_task;
Joachim Protze82e94a52017-11-01 10:08:30 +000097 ompt_lw_taskteam_t *lwt = NULL,
98 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +000099
Jonathan Peyton30419822017-05-12 18:01:32 +0000100 while (depth > 0) {
101 // next lightweight team (if any)
102 if (lwt)
103 lwt = lwt->parent;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000104
Jonathan Peyton30419822017-05-12 18:01:32 +0000105 // next heavyweight team (if any) after
106 // lightweight teams are exhausted
107 if (!lwt && taskdata) {
Joachim Protze82e94a52017-11-01 10:08:30 +0000108 if (next_lwt) {
109 lwt = next_lwt;
110 next_lwt = NULL;
111 } else {
112 taskdata = taskdata->td_parent;
113 if (taskdata) {
114 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
115 }
116 }
117 }
118 depth--;
119 }
120
121 if (lwt) {
122 info = &lwt->ompt_task_info;
123 } else if (taskdata) {
124 info = &taskdata->ompt_task_info;
125 }
126 }
127
128 return info;
129}
130
131ompt_task_info_t *__ompt_get_scheduling_taskinfo(int depth) {
132 ompt_task_info_t *info = NULL;
133 kmp_info_t *thr = ompt_get_thread();
134
135 if (thr) {
136 kmp_taskdata_t *taskdata = thr->th.th_current_task;
137
138 ompt_lw_taskteam_t *lwt = NULL,
139 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
140
141 while (depth > 0) {
142 // next lightweight team (if any)
143 if (lwt)
144 lwt = lwt->parent;
145
146 // next heavyweight team (if any) after
147 // lightweight teams are exhausted
148 if (!lwt && taskdata) {
149 // first try scheduling parent (for explicit task scheduling)
150 if (taskdata->ompt_task_info.scheduling_parent) {
151 taskdata = taskdata->ompt_task_info.scheduling_parent;
152 } else if (next_lwt) {
153 lwt = next_lwt;
154 next_lwt = NULL;
155 } else {
156 // then go for implicit tasks
157 taskdata = taskdata->td_parent;
158 if (taskdata) {
159 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
160 }
Andrey Churbanove5f44922015-04-29 16:22:07 +0000161 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000162 }
163 depth--;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000164 }
165
Jonathan Peyton30419822017-05-12 18:01:32 +0000166 if (lwt) {
167 info = &lwt->ompt_task_info;
168 } else if (taskdata) {
169 info = &taskdata->ompt_task_info;
170 }
171 }
172
173 return info;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000174}
175
Andrey Churbanove5f44922015-04-29 16:22:07 +0000176//******************************************************************************
177// interface operations
178//******************************************************************************
179
180//----------------------------------------------------------
Andrey Churbanove5f44922015-04-29 16:22:07 +0000181// thread support
182//----------------------------------------------------------
183
Joachim Protze82e94a52017-11-01 10:08:30 +0000184ompt_data_t *__ompt_get_thread_data_internal() {
185 if (__kmp_get_gtid() >= 0) {
186 kmp_info_t *thread = ompt_get_thread();
187 if (thread == NULL)
188 return NULL;
189 return &(thread->th.ompt_thread_info.thread_data);
190 }
191 return NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000192}
193
194//----------------------------------------------------------
195// state support
196//----------------------------------------------------------
197
Jonathan Peyton30419822017-05-12 18:01:32 +0000198void __ompt_thread_assign_wait_id(void *variable) {
Joachim Protze82e94a52017-11-01 10:08:30 +0000199 kmp_info_t *ti = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000200
Jonathan Peyton30419822017-05-12 18:01:32 +0000201 ti->th.ompt_thread_info.wait_id = (ompt_wait_id_t)variable;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000202}
203
Joachim Protze82e94a52017-11-01 10:08:30 +0000204omp_state_t __ompt_get_state_internal(ompt_wait_id_t *ompt_wait_id) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000205 kmp_info_t *ti = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000206
Jonathan Peyton30419822017-05-12 18:01:32 +0000207 if (ti) {
208 if (ompt_wait_id)
209 *ompt_wait_id = ti->th.ompt_thread_info.wait_id;
210 return ti->th.ompt_thread_info.state;
211 }
Joachim Protze82e94a52017-11-01 10:08:30 +0000212 return omp_state_undefined;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000213}
214
Andrey Churbanove5f44922015-04-29 16:22:07 +0000215//----------------------------------------------------------
216// parallel region support
217//----------------------------------------------------------
218
Joachim Protze82e94a52017-11-01 10:08:30 +0000219int __ompt_get_parallel_info_internal(int ancestor_level,
220 ompt_data_t **parallel_data,
221 int *team_size) {
Joachim Protze1dc2afd2018-01-17 10:05:55 +0000222 if (__kmp_get_gtid() >= 0) {
223 ompt_team_info_t *info;
224 if (team_size) {
225 info = __ompt_get_teaminfo(ancestor_level, team_size);
226 } else {
227 info = __ompt_get_teaminfo(ancestor_level, NULL);
228 }
229 if (parallel_data) {
230 *parallel_data = info ? &(info->parallel_data) : NULL;
231 }
232 return info ? 2 : 0;
Joachim Protze82e94a52017-11-01 10:08:30 +0000233 } else {
Joachim Protze1dc2afd2018-01-17 10:05:55 +0000234 return 0;
Joachim Protze82e94a52017-11-01 10:08:30 +0000235 }
Andrey Churbanove5f44922015-04-29 16:22:07 +0000236}
237
Andrey Churbanove5f44922015-04-29 16:22:07 +0000238//----------------------------------------------------------
239// lightweight task team support
240//----------------------------------------------------------
241
Jonathan Peyton30419822017-05-12 18:01:32 +0000242void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid,
Joachim Protze82e94a52017-11-01 10:08:30 +0000243 ompt_data_t *ompt_pid, void *codeptr) {
244 // initialize parallel_data with input, return address to parallel_data on
245 // exit
246 lwt->ompt_team_info.parallel_data = *ompt_pid;
247 lwt->ompt_team_info.master_return_address = codeptr;
248 lwt->ompt_task_info.task_data.value = 0;
Joachim Protzec255ca72017-11-05 14:11:10 +0000249 lwt->ompt_task_info.frame.enter_frame = NULL;
250 lwt->ompt_task_info.frame.exit_frame = NULL;
Joachim Protze82e94a52017-11-01 10:08:30 +0000251 lwt->ompt_task_info.scheduling_parent = NULL;
252 lwt->ompt_task_info.deps = NULL;
253 lwt->ompt_task_info.ndeps = 0;
254 lwt->heap = 0;
Jonathan Peyton30419822017-05-12 18:01:32 +0000255 lwt->parent = 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000256}
257
Joachim Protze82e94a52017-11-01 10:08:30 +0000258void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr,
259 int on_heap) {
260 ompt_lw_taskteam_t *link_lwt = lwt;
261 if (thr->th.th_team->t.t_serialized >
262 1) { // we already have a team, so link the new team and swap values
263 if (on_heap) { // the lw_taskteam cannot stay on stack, allocate it on heap
264 link_lwt =
265 (ompt_lw_taskteam_t *)__kmp_allocate(sizeof(ompt_lw_taskteam_t));
266 }
267 link_lwt->heap = on_heap;
268
269 // would be swap in the (on_stack) case.
270 ompt_team_info_t tmp_team = lwt->ompt_team_info;
271 link_lwt->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr);
272 *OMPT_CUR_TEAM_INFO(thr) = tmp_team;
273
274 ompt_task_info_t tmp_task = lwt->ompt_task_info;
275 link_lwt->ompt_task_info = *OMPT_CUR_TASK_INFO(thr);
276 *OMPT_CUR_TASK_INFO(thr) = tmp_task;
277
278 // link the taskteam into the list of taskteams:
279 ompt_lw_taskteam_t *my_parent =
280 thr->th.th_team->t.ompt_serialized_team_info;
281 link_lwt->parent = my_parent;
282 thr->th.th_team->t.ompt_serialized_team_info = link_lwt;
283 } else {
284 // this is the first serialized team, so we just store the values in the
285 // team and drop the taskteam-object
286 *OMPT_CUR_TEAM_INFO(thr) = lwt->ompt_team_info;
287 *OMPT_CUR_TASK_INFO(thr) = lwt->ompt_task_info;
288 }
Andrey Churbanove5f44922015-04-29 16:22:07 +0000289}
290
Joachim Protze82e94a52017-11-01 10:08:30 +0000291void __ompt_lw_taskteam_unlink(kmp_info_t *thr) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000292 ompt_lw_taskteam_t *lwtask = thr->th.th_team->t.ompt_serialized_team_info;
Joachim Protze82e94a52017-11-01 10:08:30 +0000293 if (lwtask) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000294 thr->th.th_team->t.ompt_serialized_team_info = lwtask->parent;
Joachim Protze82e94a52017-11-01 10:08:30 +0000295
296 ompt_team_info_t tmp_team = lwtask->ompt_team_info;
297 lwtask->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr);
298 *OMPT_CUR_TEAM_INFO(thr) = tmp_team;
299
300 ompt_task_info_t tmp_task = lwtask->ompt_task_info;
301 lwtask->ompt_task_info = *OMPT_CUR_TASK_INFO(thr);
302 *OMPT_CUR_TASK_INFO(thr) = tmp_task;
303
304 if (lwtask->heap) {
305 __kmp_free(lwtask);
306 lwtask = NULL;
307 }
308 }
309 // return lwtask;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000310}
311
Andrey Churbanove5f44922015-04-29 16:22:07 +0000312//----------------------------------------------------------
313// task support
314//----------------------------------------------------------
315
Joachim Protze82e94a52017-11-01 10:08:30 +0000316int __ompt_get_task_info_internal(int ancestor_level, int *type,
317 ompt_data_t **task_data,
318 ompt_frame_t **task_frame,
319 ompt_data_t **parallel_data,
320 int *thread_num) {
Joachim Protze1dc2afd2018-01-17 10:05:55 +0000321 if (__kmp_get_gtid() < 0)
322 return 0;
323
Joachim Protze82e94a52017-11-01 10:08:30 +0000324 if (ancestor_level < 0)
325 return 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000326
Joachim Protze82e94a52017-11-01 10:08:30 +0000327 // copied from __ompt_get_scheduling_taskinfo
328 ompt_task_info_t *info = NULL;
329 ompt_team_info_t *team_info = NULL;
330 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000331
Joachim Protze82e94a52017-11-01 10:08:30 +0000332 if (thr) {
333 kmp_taskdata_t *taskdata = thr->th.th_current_task;
334 if (taskdata == NULL)
335 return 0;
336 kmp_team *team = thr->th.th_team;
337 if (team == NULL)
338 return 0;
339 ompt_lw_taskteam_t *lwt = NULL,
340 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000341
Joachim Protze82e94a52017-11-01 10:08:30 +0000342 while (ancestor_level > 0) {
343 // next lightweight team (if any)
344 if (lwt)
345 lwt = lwt->parent;
346
347 // next heavyweight team (if any) after
348 // lightweight teams are exhausted
349 if (!lwt && taskdata) {
350 // first try scheduling parent (for explicit task scheduling)
351 if (taskdata->ompt_task_info.scheduling_parent) {
352 taskdata = taskdata->ompt_task_info.scheduling_parent;
353 } else if (next_lwt) {
354 lwt = next_lwt;
355 next_lwt = NULL;
356 } else {
357 // then go for implicit tasks
358 taskdata = taskdata->td_parent;
359 if (team == NULL)
360 return 0;
361 team = team->t.t_parent;
362 if (taskdata) {
363 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
364 }
365 }
366 }
367 ancestor_level--;
368 }
369
370 if (lwt) {
371 info = &lwt->ompt_task_info;
372 team_info = &lwt->ompt_team_info;
373 if (type) {
374 *type = ompt_task_implicit;
375 }
376 } else if (taskdata) {
377 info = &taskdata->ompt_task_info;
378 team_info = &team->t.ompt_team_info;
379 if (type) {
380 if (taskdata->td_parent) {
381 *type = (taskdata->td_flags.tasktype ? ompt_task_explicit
382 : ompt_task_implicit) |
383 TASK_TYPE_DETAILS_FORMAT(taskdata);
384 } else {
385 *type = ompt_task_initial;
386 }
387 }
388 }
389 if (task_data) {
390 *task_data = info ? &info->task_data : NULL;
391 }
392 if (task_frame) {
393 // OpenMP spec asks for the scheduling task to be returned.
394 *task_frame = info ? &info->frame : NULL;
395 }
396 if (parallel_data) {
397 *parallel_data = team_info ? &(team_info->parallel_data) : NULL;
398 }
399 return info ? 2 : 0;
400 }
401 return 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000402}
403
Andrey Churbanove5f44922015-04-29 16:22:07 +0000404//----------------------------------------------------------
405// team support
406//----------------------------------------------------------
407
Joachim Protze82e94a52017-11-01 10:08:30 +0000408void __ompt_team_assign_id(kmp_team_t *team, ompt_data_t ompt_pid) {
409 team->t.ompt_team_info.parallel_data = ompt_pid;
410}
411
412//----------------------------------------------------------
413// misc
414//----------------------------------------------------------
415
416static uint64_t __ompt_get_unique_id_internal() {
417 static uint64_t thread = 1;
418 static THREAD_LOCAL uint64_t ID = 0;
419 if (ID == 0) {
420 uint64_t new_thread = KMP_TEST_THEN_INC64((kmp_int64 *)&thread);
421 ID = new_thread << (sizeof(uint64_t) * 8 - OMPT_THREAD_ID_BITS);
422 }
423 return ++ID;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000424}