blob: 9e0d1eef03198826e9fbf548fdcd79f7204b9ee8 [file] [log] [blame]
Andrey Churbanove5f44922015-04-29 16:22:07 +00001//******************************************************************************
2// include files
3//******************************************************************************
4
5#include "kmp.h"
6#include "ompt-internal.h"
7#include "ompt-specific.h"
8
9//******************************************************************************
10// macros
11//******************************************************************************
12
Jonathan Peyton30419822017-05-12 18:01:32 +000013#define GTID_TO_OMPT_THREAD_ID(id) ((ompt_thread_id_t)(id >= 0) ? id + 1 : 0)
Andrey Churbanove5f44922015-04-29 16:22:07 +000014
15#define LWT_FROM_TEAM(team) (team)->t.ompt_serialized_team_info;
16
17#define OMPT_THREAD_ID_BITS 16
18
19// 2013 08 24 - John Mellor-Crummey
20// ideally, a thread should assign its own ids based on thread private data.
21// however, the way the intel runtime reinitializes thread data structures
22// when it creates teams makes it difficult to maintain persistent thread
23// data. using a shared variable instead is simple. I leave it to intel to
24// sort out how to implement a higher performance version in their runtime.
25
26// when using fetch_and_add to generate the IDs, there isn't any reason to waste
27// bits for thread id.
28#if 0
Jonathan Peyton30419822017-05-12 18:01:32 +000029#define NEXT_ID(id_ptr, tid) \
Andrey Churbanove5f44922015-04-29 16:22:07 +000030 ((KMP_TEST_THEN_INC64(id_ptr) << OMPT_THREAD_ID_BITS) | (tid))
31#else
Jonathan Peyton30419822017-05-12 18:01:32 +000032#define NEXT_ID(id_ptr, tid) (KMP_TEST_THEN_INC64((volatile kmp_int64 *)id_ptr))
Andrey Churbanove5f44922015-04-29 16:22:07 +000033#endif
34
35//******************************************************************************
36// private operations
37//******************************************************************************
38
39//----------------------------------------------------------
40// traverse the team and task hierarchy
41// note: __ompt_get_teaminfo and __ompt_get_taskinfo
42// traverse the hierarchy similarly and need to be
43// kept consistent
44//----------------------------------------------------------
45
Jonathan Peyton30419822017-05-12 18:01:32 +000046ompt_team_info_t *__ompt_get_teaminfo(int depth, int *size) {
47 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +000048
Jonathan Peyton30419822017-05-12 18:01:32 +000049 if (thr) {
50 kmp_team *team = thr->th.th_team;
51 if (team == NULL)
52 return NULL;
Jonathan Peytonf0344bb2015-10-09 17:42:52 +000053
Jonathan Peyton30419822017-05-12 18:01:32 +000054 ompt_lw_taskteam_t *lwt = LWT_FROM_TEAM(team);
Andrey Churbanove5f44922015-04-29 16:22:07 +000055
Jonathan Peyton30419822017-05-12 18:01:32 +000056 while (depth > 0) {
57 // next lightweight team (if any)
58 if (lwt)
59 lwt = lwt->parent;
Andrey Churbanove5f44922015-04-29 16:22:07 +000060
Jonathan Peyton30419822017-05-12 18:01:32 +000061 // next heavyweight team (if any) after
62 // lightweight teams are exhausted
63 if (!lwt && team) {
64 team = team->t.t_parent;
65 if (team) {
66 lwt = LWT_FROM_TEAM(team);
Andrey Churbanove5f44922015-04-29 16:22:07 +000067 }
Jonathan Peyton30419822017-05-12 18:01:32 +000068 }
Andrey Churbanove5f44922015-04-29 16:22:07 +000069
Jonathan Peyton30419822017-05-12 18:01:32 +000070 depth--;
Andrey Churbanove5f44922015-04-29 16:22:07 +000071 }
72
Jonathan Peyton30419822017-05-12 18:01:32 +000073 if (lwt) {
74 // lightweight teams have one task
75 if (size)
76 *size = 1;
77
78 // return team info for lightweight team
79 return &lwt->ompt_team_info;
80 } else if (team) {
81 // extract size from heavyweight team
82 if (size)
83 *size = team->t.t_nproc;
84
85 // return team info for heavyweight team
86 return &team->t.ompt_team_info;
87 }
88 }
89
90 return NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +000091}
92
Jonathan Peyton30419822017-05-12 18:01:32 +000093ompt_task_info_t *__ompt_get_taskinfo(int depth) {
94 ompt_task_info_t *info = NULL;
95 kmp_info_t *thr = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +000096
Jonathan Peyton30419822017-05-12 18:01:32 +000097 if (thr) {
98 kmp_taskdata_t *taskdata = thr->th.th_current_task;
99 ompt_lw_taskteam_t *lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000100
Jonathan Peyton30419822017-05-12 18:01:32 +0000101 while (depth > 0) {
102 // next lightweight team (if any)
103 if (lwt)
104 lwt = lwt->parent;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000105
Jonathan Peyton30419822017-05-12 18:01:32 +0000106 // next heavyweight team (if any) after
107 // lightweight teams are exhausted
108 if (!lwt && taskdata) {
109 taskdata = taskdata->td_parent;
110 if (taskdata) {
111 lwt = LWT_FROM_TEAM(taskdata->td_team);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000112 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000113 }
114 depth--;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000115 }
116
Jonathan Peyton30419822017-05-12 18:01:32 +0000117 if (lwt) {
118 info = &lwt->ompt_task_info;
119 } else if (taskdata) {
120 info = &taskdata->ompt_task_info;
121 }
122 }
123
124 return info;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000125}
126
Andrey Churbanove5f44922015-04-29 16:22:07 +0000127//******************************************************************************
128// interface operations
129//******************************************************************************
130
131//----------------------------------------------------------
Andrey Churbanove5f44922015-04-29 16:22:07 +0000132// thread support
133//----------------------------------------------------------
134
Jonathan Peyton30419822017-05-12 18:01:32 +0000135ompt_parallel_id_t __ompt_thread_id_new() {
136 static uint64_t ompt_thread_id = 1;
137 return NEXT_ID(&ompt_thread_id, 0);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000138}
139
Jonathan Peyton30419822017-05-12 18:01:32 +0000140void __ompt_thread_begin(ompt_thread_type_t thread_type, int gtid) {
141 ompt_callbacks.ompt_callback(ompt_event_thread_begin)(
142 thread_type, GTID_TO_OMPT_THREAD_ID(gtid));
Andrey Churbanove5f44922015-04-29 16:22:07 +0000143}
144
Jonathan Peyton30419822017-05-12 18:01:32 +0000145void __ompt_thread_end(ompt_thread_type_t thread_type, int gtid) {
146 ompt_callbacks.ompt_callback(ompt_event_thread_end)(
147 thread_type, GTID_TO_OMPT_THREAD_ID(gtid));
Andrey Churbanove5f44922015-04-29 16:22:07 +0000148}
149
Jonathan Peyton30419822017-05-12 18:01:32 +0000150ompt_thread_id_t __ompt_get_thread_id_internal() {
151 // FIXME: until we have a better way of assigning ids, use __kmp_get_gtid
152 // since the return value might be negative, we need to test that before
153 // assigning it to an ompt_thread_id_t, which is unsigned.
154 int id = __kmp_get_gtid();
155 assert(id >= 0);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000156
Jonathan Peyton30419822017-05-12 18:01:32 +0000157 return GTID_TO_OMPT_THREAD_ID(id);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000158}
159
160//----------------------------------------------------------
161// state support
162//----------------------------------------------------------
163
Jonathan Peyton30419822017-05-12 18:01:32 +0000164void __ompt_thread_assign_wait_id(void *variable) {
165 int gtid = __kmp_gtid_get_specific();
166 kmp_info_t *ti = ompt_get_thread_gtid(gtid);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000167
Jonathan Peyton30419822017-05-12 18:01:32 +0000168 ti->th.ompt_thread_info.wait_id = (ompt_wait_id_t)variable;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000169}
170
Jonathan Peyton30419822017-05-12 18:01:32 +0000171ompt_state_t __ompt_get_state_internal(ompt_wait_id_t *ompt_wait_id) {
172 kmp_info_t *ti = ompt_get_thread();
Andrey Churbanove5f44922015-04-29 16:22:07 +0000173
Jonathan Peyton30419822017-05-12 18:01:32 +0000174 if (ti) {
175 if (ompt_wait_id)
176 *ompt_wait_id = ti->th.ompt_thread_info.wait_id;
177 return ti->th.ompt_thread_info.state;
178 }
179 return ompt_state_undefined;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000180}
181
182//----------------------------------------------------------
183// idle frame support
184//----------------------------------------------------------
185
Jonathan Peyton30419822017-05-12 18:01:32 +0000186void *__ompt_get_idle_frame_internal(void) {
187 kmp_info_t *ti = ompt_get_thread();
188 return ti ? ti->th.ompt_thread_info.idle_frame : NULL;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000189}
190
Andrey Churbanove5f44922015-04-29 16:22:07 +0000191//----------------------------------------------------------
192// parallel region support
193//----------------------------------------------------------
194
Jonathan Peyton30419822017-05-12 18:01:32 +0000195ompt_parallel_id_t __ompt_parallel_id_new(int gtid) {
196 static uint64_t ompt_parallel_id = 1;
197 return gtid >= 0 ? NEXT_ID(&ompt_parallel_id, gtid) : 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000198}
199
Jonathan Peyton30419822017-05-12 18:01:32 +0000200void *__ompt_get_parallel_function_internal(int depth) {
201 ompt_team_info_t *info = __ompt_get_teaminfo(depth, NULL);
202 void *function = info ? info->microtask : NULL;
203 return function;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000204}
205
Jonathan Peyton30419822017-05-12 18:01:32 +0000206ompt_parallel_id_t __ompt_get_parallel_id_internal(int depth) {
207 ompt_team_info_t *info = __ompt_get_teaminfo(depth, NULL);
208 ompt_parallel_id_t id = info ? info->parallel_id : 0;
209 return id;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000210}
211
Jonathan Peyton30419822017-05-12 18:01:32 +0000212int __ompt_get_parallel_team_size_internal(int depth) {
213 // initialize the return value with the error value.
214 // if there is a team at the specified depth, the default
215 // value will be overwritten the size of that team.
216 int size = -1;
217 (void)__ompt_get_teaminfo(depth, &size);
218 return size;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000219}
220
Andrey Churbanove5f44922015-04-29 16:22:07 +0000221//----------------------------------------------------------
222// lightweight task team support
223//----------------------------------------------------------
224
Jonathan Peyton30419822017-05-12 18:01:32 +0000225void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid,
226 void *microtask, ompt_parallel_id_t ompt_pid) {
227 lwt->ompt_team_info.parallel_id = ompt_pid;
228 lwt->ompt_team_info.microtask = microtask;
229 lwt->ompt_task_info.task_id = 0;
230 lwt->ompt_task_info.frame.reenter_runtime_frame = NULL;
231 lwt->ompt_task_info.frame.exit_runtime_frame = NULL;
232 lwt->ompt_task_info.function = NULL;
233 lwt->parent = 0;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000234}
235
Jonathan Peyton30419822017-05-12 18:01:32 +0000236void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr) {
237 ompt_lw_taskteam_t *my_parent = thr->th.th_team->t.ompt_serialized_team_info;
238 lwt->parent = my_parent;
239 thr->th.th_team->t.ompt_serialized_team_info = lwt;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000240}
241
Jonathan Peyton30419822017-05-12 18:01:32 +0000242ompt_lw_taskteam_t *__ompt_lw_taskteam_unlink(kmp_info_t *thr) {
243 ompt_lw_taskteam_t *lwtask = thr->th.th_team->t.ompt_serialized_team_info;
244 if (lwtask)
245 thr->th.th_team->t.ompt_serialized_team_info = lwtask->parent;
246 return lwtask;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000247}
248
Andrey Churbanove5f44922015-04-29 16:22:07 +0000249//----------------------------------------------------------
250// task support
251//----------------------------------------------------------
252
Jonathan Peyton30419822017-05-12 18:01:32 +0000253ompt_task_id_t __ompt_task_id_new(int gtid) {
254 static uint64_t ompt_task_id = 1;
255 return NEXT_ID(&ompt_task_id, gtid);
Andrey Churbanove5f44922015-04-29 16:22:07 +0000256}
257
Jonathan Peyton30419822017-05-12 18:01:32 +0000258ompt_task_id_t __ompt_get_task_id_internal(int depth) {
259 ompt_task_info_t *info = __ompt_get_taskinfo(depth);
260 ompt_task_id_t task_id = info ? info->task_id : 0;
261 return task_id;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000262}
263
Jonathan Peyton30419822017-05-12 18:01:32 +0000264void *__ompt_get_task_function_internal(int depth) {
265 ompt_task_info_t *info = __ompt_get_taskinfo(depth);
266 void *function = info ? info->function : NULL;
267 return function;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000268}
269
Jonathan Peyton30419822017-05-12 18:01:32 +0000270ompt_frame_t *__ompt_get_task_frame_internal(int depth) {
271 ompt_task_info_t *info = __ompt_get_taskinfo(depth);
272 ompt_frame_t *frame = info ? frame = &info->frame : NULL;
273 return frame;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000274}
275
Andrey Churbanove5f44922015-04-29 16:22:07 +0000276//----------------------------------------------------------
277// team support
278//----------------------------------------------------------
279
Jonathan Peyton30419822017-05-12 18:01:32 +0000280void __ompt_team_assign_id(kmp_team_t *team, ompt_parallel_id_t ompt_pid) {
281 team->t.ompt_team_info.parallel_id = ompt_pid;
Andrey Churbanove5f44922015-04-29 16:22:07 +0000282}