blob: 92665ade53636ebd75577a664650f4079d8b864c [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) {
222 ompt_team_info_t *info;
223 if (team_size) {
224 info = __ompt_get_teaminfo(ancestor_level, team_size);
225 } else {
226 info = __ompt_get_teaminfo(ancestor_level, NULL);
227 }
228 if (parallel_data) {
229 *parallel_data = info ? &(info->parallel_data) : NULL;
230 }
231 return info ? 2 : 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000232}
233
Andrey Churbanove5f44922015-04-29 16:22:07 +0000234//----------------------------------------------------------
235// lightweight task team support
236//----------------------------------------------------------
237
Jonathan Peyton30419822017-05-12 18:01:32 +0000238void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid,
Joachim Protze82e94a52017-11-01 10:08:30 +0000239 ompt_data_t *ompt_pid, void *codeptr) {
240 // initialize parallel_data with input, return address to parallel_data on
241 // exit
242 lwt->ompt_team_info.parallel_data = *ompt_pid;
243 lwt->ompt_team_info.master_return_address = codeptr;
244 lwt->ompt_task_info.task_data.value = 0;
Joachim Protzec255ca72017-11-05 14:11:10 +0000245 lwt->ompt_task_info.frame.enter_frame = NULL;
246 lwt->ompt_task_info.frame.exit_frame = NULL;
Joachim Protze82e94a52017-11-01 10:08:30 +0000247 lwt->ompt_task_info.scheduling_parent = NULL;
248 lwt->ompt_task_info.deps = NULL;
249 lwt->ompt_task_info.ndeps = 0;
250 lwt->heap = 0;
Jonathan Peyton30419822017-05-12 18:01:32 +0000251 lwt->parent = 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000252}
253
Joachim Protze82e94a52017-11-01 10:08:30 +0000254void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr,
255 int on_heap) {
256 ompt_lw_taskteam_t *link_lwt = lwt;
257 if (thr->th.th_team->t.t_serialized >
258 1) { // we already have a team, so link the new team and swap values
259 if (on_heap) { // the lw_taskteam cannot stay on stack, allocate it on heap
260 link_lwt =
261 (ompt_lw_taskteam_t *)__kmp_allocate(sizeof(ompt_lw_taskteam_t));
262 }
263 link_lwt->heap = on_heap;
264
265 // would be swap in the (on_stack) case.
266 ompt_team_info_t tmp_team = lwt->ompt_team_info;
267 link_lwt->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr);
268 *OMPT_CUR_TEAM_INFO(thr) = tmp_team;
269
270 ompt_task_info_t tmp_task = lwt->ompt_task_info;
271 link_lwt->ompt_task_info = *OMPT_CUR_TASK_INFO(thr);
272 *OMPT_CUR_TASK_INFO(thr) = tmp_task;
273
274 // link the taskteam into the list of taskteams:
275 ompt_lw_taskteam_t *my_parent =
276 thr->th.th_team->t.ompt_serialized_team_info;
277 link_lwt->parent = my_parent;
278 thr->th.th_team->t.ompt_serialized_team_info = link_lwt;
279 } else {
280 // this is the first serialized team, so we just store the values in the
281 // team and drop the taskteam-object
282 *OMPT_CUR_TEAM_INFO(thr) = lwt->ompt_team_info;
283 *OMPT_CUR_TASK_INFO(thr) = lwt->ompt_task_info;
284 }
Andrey Churbanove5f44922015-04-29 16:22:07 +0000285}
286
Joachim Protze82e94a52017-11-01 10:08:30 +0000287void __ompt_lw_taskteam_unlink(kmp_info_t *thr) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000288 ompt_lw_taskteam_t *lwtask = thr->th.th_team->t.ompt_serialized_team_info;
Joachim Protze82e94a52017-11-01 10:08:30 +0000289 if (lwtask) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000290 thr->th.th_team->t.ompt_serialized_team_info = lwtask->parent;
Joachim Protze82e94a52017-11-01 10:08:30 +0000291
292 ompt_team_info_t tmp_team = lwtask->ompt_team_info;
293 lwtask->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr);
294 *OMPT_CUR_TEAM_INFO(thr) = tmp_team;
295
296 ompt_task_info_t tmp_task = lwtask->ompt_task_info;
297 lwtask->ompt_task_info = *OMPT_CUR_TASK_INFO(thr);
298 *OMPT_CUR_TASK_INFO(thr) = tmp_task;
299
300 if (lwtask->heap) {
301 __kmp_free(lwtask);
302 lwtask = NULL;
303 }
304 }
305 // return lwtask;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000306}
307
Andrey Churbanove5f44922015-04-29 16:22:07 +0000308//----------------------------------------------------------
309// task support
310//----------------------------------------------------------
311
Joachim Protze82e94a52017-11-01 10:08:30 +0000312int __ompt_get_task_info_internal(int ancestor_level, int *type,
313 ompt_data_t **task_data,
314 ompt_frame_t **task_frame,
315 ompt_data_t **parallel_data,
316 int *thread_num) {
317 if (ancestor_level < 0)
318 return 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000319
Joachim Protze82e94a52017-11-01 10:08:30 +0000320 // copied from __ompt_get_scheduling_taskinfo
321 ompt_task_info_t *info = NULL;
322 ompt_team_info_t *team_info = NULL;
323 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000324
Joachim Protze82e94a52017-11-01 10:08:30 +0000325 if (thr) {
326 kmp_taskdata_t *taskdata = thr->th.th_current_task;
327 if (taskdata == NULL)
328 return 0;
329 kmp_team *team = thr->th.th_team;
330 if (team == NULL)
331 return 0;
332 ompt_lw_taskteam_t *lwt = NULL,
333 *next_lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000334
Joachim Protze82e94a52017-11-01 10:08:30 +0000335 while (ancestor_level > 0) {
336 // next lightweight team (if any)
337 if (lwt)
338 lwt = lwt->parent;
339
340 // next heavyweight team (if any) after
341 // lightweight teams are exhausted
342 if (!lwt && taskdata) {
343 // first try scheduling parent (for explicit task scheduling)
344 if (taskdata->ompt_task_info.scheduling_parent) {
345 taskdata = taskdata->ompt_task_info.scheduling_parent;
346 } else if (next_lwt) {
347 lwt = next_lwt;
348 next_lwt = NULL;
349 } else {
350 // then go for implicit tasks
351 taskdata = taskdata->td_parent;
352 if (team == NULL)
353 return 0;
354 team = team->t.t_parent;
355 if (taskdata) {
356 next_lwt = LWT_FROM_TEAM(taskdata->td_team);
357 }
358 }
359 }
360 ancestor_level--;
361 }
362
363 if (lwt) {
364 info = &lwt->ompt_task_info;
365 team_info = &lwt->ompt_team_info;
366 if (type) {
367 *type = ompt_task_implicit;
368 }
369 } else if (taskdata) {
370 info = &taskdata->ompt_task_info;
371 team_info = &team->t.ompt_team_info;
372 if (type) {
373 if (taskdata->td_parent) {
374 *type = (taskdata->td_flags.tasktype ? ompt_task_explicit
375 : ompt_task_implicit) |
376 TASK_TYPE_DETAILS_FORMAT(taskdata);
377 } else {
378 *type = ompt_task_initial;
379 }
380 }
381 }
382 if (task_data) {
383 *task_data = info ? &info->task_data : NULL;
384 }
385 if (task_frame) {
386 // OpenMP spec asks for the scheduling task to be returned.
387 *task_frame = info ? &info->frame : NULL;
388 }
389 if (parallel_data) {
390 *parallel_data = team_info ? &(team_info->parallel_data) : NULL;
391 }
392 return info ? 2 : 0;
393 }
394 return 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000395}
396
Andrey Churbanove5f44922015-04-29 16:22:07 +0000397//----------------------------------------------------------
398// team support
399//----------------------------------------------------------
400
Joachim Protze82e94a52017-11-01 10:08:30 +0000401void __ompt_team_assign_id(kmp_team_t *team, ompt_data_t ompt_pid) {
402 team->t.ompt_team_info.parallel_data = ompt_pid;
403}
404
405//----------------------------------------------------------
406// misc
407//----------------------------------------------------------
408
409static uint64_t __ompt_get_unique_id_internal() {
410 static uint64_t thread = 1;
411 static THREAD_LOCAL uint64_t ID = 0;
412 if (ID == 0) {
413 uint64_t new_thread = KMP_TEST_THEN_INC64((kmp_int64 *)&thread);
414 ID = new_thread << (sizeof(uint64_t) * 8 - OMPT_THREAD_ID_BITS);
415 }
416 return ++ID;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000417}