1 from __future__
import print_function
3 from ompd_handles
import ompd_thread
, ompd_task
, ompd_parallel
10 class ompd_scope(Enum
):
12 ompd_scope_address_space
= 2
14 ompd_scope_parallel
= 4
15 ompd_scope_implicit_task
= 5
19 class ompd_address_space(object):
21 """Initializes an ompd_address_space object by calling ompd_initialize
24 self
.addr_space
= ompdModule
.call_ompd_initialize()
25 # maps thread_num (thread id given by gdb) to ompd_thread object with thread handle
29 self
.ompd_tool_test_bp
= None
38 self
.sched_map
= {1: "static", 2: "dynamic", 3: "guided", 4: "auto"}
39 gdb
.events
.stop
.connect(self
.handle_stop_event
)
40 self
.new_thread_breakpoint
= gdb
.Breakpoint(
41 "ompd_bp_thread_begin", internal
=True
43 tool_break_symbol
= gdb
.lookup_global_symbol("ompd_tool_break")
44 if tool_break_symbol
is not None:
45 self
.ompd_tool_test_bp
= gdb
.Breakpoint("ompd_tool_break", internal
=True)
47 def handle_stop_event(self
, event
):
48 """Sets a breakpoint at different events, e.g. when a new OpenMP
51 if isinstance(event
, gdb
.BreakpointEvent
):
52 # check if breakpoint has already been hit
53 if self
.new_thread_breakpoint
in event
.breakpoints
:
55 gdb
.execute("continue")
58 self
.ompd_tool_test_bp
is not None
59 and self
.ompd_tool_test_bp
in event
.breakpoints
62 self
.compare_ompt_data()
63 gdb
.execute("continue")
66 elif isinstance(event
, gdb
.SignalEvent
):
67 # TODO: what do we need to do on SIGNALS?
70 # TODO: probably not possible?
73 def get_icv_map(self
):
79 tup
= ompdModule
.call_ompd_enumerate_icvs(self
.addr_space
, current
)
80 (current
, next_icv
, next_scope
, more
) = tup
81 self
.icv_map
[next_icv
] = (current
, next_scope
, self
.scope_map
[next_scope
])
82 print("Initialized ICV map successfully for checking OMP API values.")
84 def compare_ompt_data(self
):
85 """Compares OMPT tool data about parallel region to data returned by OMPD functions."""
86 # make sure all threads and states are set
87 self
.list_threads(False)
89 thread_id
= gdb
.selected_thread().ptid
[1]
90 curr_thread
= self
.get_curr_thread()
92 # check if current thread is LWP thread; return if "ompd_rc_unavailable"
93 thread_handle
= ompdModule
.get_thread_handle(thread_id
, self
.addr_space
)
94 if thread_handle
== -1:
95 print("Skipping OMPT-OMPD checks for non-LWP thread.")
98 print("Comparing OMPT data to OMPD data...")
99 field_names
= [i
.name
for i
in gdb
.parse_and_eval("thread_data").type.fields()]
100 thread_data
= gdb
.parse_and_eval("thread_data")
102 if self
.icv_map
is None:
105 # compare state values
106 if "ompt_state" in field_names
:
107 if self
.states
is None:
108 self
.enumerate_states()
109 ompt_state
= str(thread_data
["ompt_state"])
110 ompd_state
= str(self
.states
[curr_thread
.get_state()[0]])
111 if ompt_state
!= ompd_state
:
113 "OMPT-OMPD mismatch: ompt_state (%s) does not match OMPD state (%s)!"
114 % (ompt_state
, ompd_state
)
117 # compare wait_id values
118 if "ompt_wait_id" in field_names
:
119 ompt_wait_id
= thread_data
["ompt_wait_id"]
120 ompd_wait_id
= curr_thread
.get_state()[1]
121 if ompt_wait_id
!= ompd_wait_id
:
123 "OMPT-OMPD mismatch: ompt_wait_id (%d) does not match OMPD wait id (%d)!"
124 % (ompt_wait_id
, ompd_wait_id
)
128 if "omp_thread_num" in field_names
and "thread-num-var" in self
.icv_map
:
129 ompt_thread_num
= thread_data
["omp_thread_num"]
130 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
131 curr_thread
.thread_handle
,
132 self
.icv_map
["thread-num-var"][1],
133 self
.icv_map
["thread-num-var"][0],
135 if ompt_thread_num
!= icv_value
:
137 "OMPT-OMPD mismatch: omp_thread_num (%d) does not match OMPD thread num according to ICVs (%d)!"
138 % (ompt_thread_num
, icv_value
)
141 # compare thread data
142 if "ompt_thread_data" in field_names
:
143 ompt_thread_data
= thread_data
["ompt_thread_data"].dereference()["value"]
144 ompd_value
= ompdModule
.call_ompd_get_tool_data(
145 3, curr_thread
.thread_handle
147 if ompt_thread_data
!= ompd_value
:
149 "OMPT-OMPD mismatch: value of ompt_thread_data (%d) does not match that of OMPD data union (%d)!"
150 % (ompt_thread_data
, ompd_value
)
153 # compare number of threads
154 if "omp_num_threads" in field_names
and "team-size-var" in self
.icv_map
:
155 ompt_num_threads
= thread_data
["omp_num_threads"]
156 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
157 curr_thread
.get_current_parallel_handle(),
158 self
.icv_map
["team-size-var"][1],
159 self
.icv_map
["team-size-var"][0],
161 if ompt_num_threads
!= icv_value
:
163 "OMPT-OMPD mismatch: omp_num_threads (%d) does not match OMPD num threads according to ICVs (%d)!"
164 % (ompt_num_threads
, icv_value
)
168 if "omp_level" in field_names
and "levels-var" in self
.icv_map
:
169 ompt_levels
= thread_data
["omp_level"]
170 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
171 curr_thread
.get_current_parallel_handle(),
172 self
.icv_map
["levels-var"][1],
173 self
.icv_map
["levels-var"][0],
175 if ompt_levels
!= icv_value
:
177 "OMPT-OMPD mismatch: omp_level (%d) does not match OMPD levels according to ICVs (%d)!"
178 % (ompt_levels
, icv_value
)
181 # compare active level
182 if "omp_active_level" in field_names
and "active-levels-var" in self
.icv_map
:
183 ompt_active_levels
= thread_data
["omp_active_level"]
184 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
185 curr_thread
.get_current_parallel_handle(),
186 self
.icv_map
["active-levels-var"][1],
187 self
.icv_map
["active-levels-var"][0],
189 if ompt_active_levels
!= icv_value
:
191 "OMPT-OMPD mismatch: active levels (%d) do not match active levels according to ICVs (%d)!"
192 % (ompt_active_levels
, icv_value
)
195 # compare parallel data
196 if "ompt_parallel_data" in field_names
:
197 ompt_parallel_data
= thread_data
["ompt_parallel_data"].dereference()[
200 current_parallel_handle
= curr_thread
.get_current_parallel_handle()
201 ompd_value
= ompdModule
.call_ompd_get_tool_data(4, current_parallel_handle
)[
204 if ompt_parallel_data
!= ompd_value
:
206 "OMPT-OMPD mismatch: value of ompt_parallel_data (%d) does not match that of OMPD data union (%d)!"
207 % (ompt_parallel_data
, ompd_value
)
210 # compare max threads
211 if "omp_max_threads" in field_names
and "nthreads-var" in self
.icv_map
:
212 ompt_max_threads
= thread_data
["omp_max_threads"]
213 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
214 curr_thread
.thread_handle
,
215 self
.icv_map
["nthreads-var"][1],
216 self
.icv_map
["nthreads-var"][0],
218 if icv_value
is None:
219 icv_string
= ompdModule
.call_ompd_get_icv_string_from_scope(
220 curr_thread
.thread_handle
,
221 self
.icv_map
["nthreads-var"][1],
222 self
.icv_map
["nthreads-var"][0],
224 if icv_string
is None:
226 "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (None Object)"
230 if ompt_max_threads
!= int(icv_string
.split(",")[0]):
232 "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!"
233 % (ompt_max_threads
, int(icv_string
.split(",")[0]))
236 if ompt_max_threads
!= icv_value
:
238 "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!"
239 % (ompt_max_threads
, icv_value
)
242 # compare omp_parallel
243 # NOTE: omp_parallel = true if active-levels-var > 0
244 if "omp_parallel" in field_names
:
245 ompt_parallel
= thread_data
["omp_parallel"]
246 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
247 curr_thread
.get_current_parallel_handle(),
248 self
.icv_map
["active-levels-var"][1],
249 self
.icv_map
["active-levels-var"][0],
254 or ompt_parallel
== 0
258 "OMPT-OMPD mismatch: ompt_parallel (%d) does not match OMPD parallel according to ICVs (%d)!"
259 % (ompt_parallel
, icv_value
)
263 if "omp_final" in field_names
and "final-task-var" in self
.icv_map
:
264 ompt_final
= thread_data
["omp_final"]
265 current_task_handle
= curr_thread
.get_current_task_handle()
266 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
268 self
.icv_map
["final-task-var"][1],
269 self
.icv_map
["final-task-var"][0],
271 if icv_value
!= ompt_final
:
273 "OMPT-OMPD mismatch: omp_final (%d) does not match OMPD final according to ICVs (%d)!"
274 % (ompt_final
, icv_value
)
277 # compare omp_dynamic
278 if "omp_dynamic" in field_names
and "dyn-var" in self
.icv_map
:
279 ompt_dynamic
= thread_data
["omp_dynamic"]
280 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
281 curr_thread
.thread_handle
,
282 self
.icv_map
["dyn-var"][1],
283 self
.icv_map
["dyn-var"][0],
285 if icv_value
!= ompt_dynamic
:
287 "OMPT-OMPD mismatch: omp_dynamic (%d) does not match OMPD dynamic according to ICVs (%d)!"
288 % (ompt_dynamic
, icv_value
)
291 # compare omp_max_active_levels
293 "omp_max_active_levels" in field_names
294 and "max-active-levels-var" in self
.icv_map
296 ompt_max_active_levels
= thread_data
["omp_max_active_levels"]
297 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
298 curr_thread
.get_current_task_handle(),
299 self
.icv_map
["max-active-levels-var"][1],
300 self
.icv_map
["max-active-levels-var"][0],
302 if ompt_max_active_levels
!= icv_value
:
304 "OMPT-OMPD mismatch: omp_max_active_levels (%d) does not match OMPD max active levels (%d)!"
305 % (ompt_max_active_levels
, icv_value
)
308 # compare omp_kind: TODO: Add the test for monotonic/nonmonotonic modifier
309 if "omp_kind" in field_names
and "run-sched-var" in self
.icv_map
:
310 ompt_sched_kind
= thread_data
["omp_kind"]
311 icv_value
= ompdModule
.call_ompd_get_icv_string_from_scope(
312 curr_thread
.get_current_task_handle(),
313 self
.icv_map
["run-sched-var"][1],
314 self
.icv_map
["run-sched-var"][0],
316 ompd_sched_kind
= icv_value
.split(",")[0]
317 if self
.sched_map
.get(int(ompt_sched_kind
)) != ompd_sched_kind
:
319 "OMPT-OMPD mismatch: omp_kind kind (%s) does not match OMPD schedule kind according to ICVs (%s)!"
320 % (self
.sched_map
.get(int(ompt_sched_kind
)), ompd_sched_kind
)
323 # compare omp_modifier
324 if "omp_modifier" in field_names
and "run-sched-var" in self
.icv_map
:
325 ompt_sched_mod
= thread_data
["omp_modifier"]
326 icv_value
= ompdModule
.call_ompd_get_icv_string_from_scope(
327 curr_thread
.get_current_task_handle(),
328 self
.icv_map
["run-sched-var"][1],
329 self
.icv_map
["run-sched-var"][0],
331 token
= icv_value
.split(",")[1]
332 if token
is not None:
333 ompd_sched_mod
= int(token
)
336 if ompt_sched_mod
!= ompd_sched_mod
:
338 "OMPT-OMPD mismatch: omp_kind modifier does not match OMPD schedule modifier according to ICVs!"
341 # compare omp_proc_bind
342 if "omp_proc_bind" in field_names
and "bind-var" in self
.icv_map
:
343 ompt_proc_bind
= thread_data
["omp_proc_bind"]
344 icv_value
= ompdModule
.call_ompd_get_icv_from_scope(
345 curr_thread
.get_current_task_handle(),
346 self
.icv_map
["bind-var"][1],
347 self
.icv_map
["bind-var"][0],
349 if icv_value
is None:
350 icv_string
= ompdModule
.call_ompd_get_icv_string_from_scope(
351 curr_thread
.get_current_task_handle(),
352 self
.icv_map
["bind-var"][1],
353 self
.icv_map
["bind-var"][0],
355 if icv_string
is None:
357 "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (None Object)"
361 if ompt_proc_bind
!= int(icv_string
.split(",")[0]):
363 "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!"
364 % (ompt_proc_bind
, int(icv_string
.split(",")[0]))
367 if ompt_proc_bind
!= icv_value
:
369 "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!"
370 % (ompt_proc_bind
, icv_value
)
373 # compare enter and exit frames
374 if "ompt_frame_list" in field_names
:
375 ompt_task_frame_dict
= thread_data
["ompt_frame_list"].dereference()
377 int(ompt_task_frame_dict
["enter_frame"].cast(gdb
.lookup_type("long"))),
378 int(ompt_task_frame_dict
["exit_frame"].cast(gdb
.lookup_type("long"))),
380 current_task
= curr_thread
.get_current_task()
381 ompd_task_frames
= current_task
.get_task_frame()
382 if ompt_task_frames
!= ompd_task_frames
:
384 "OMPT-OMPD mismatch: ompt_task_frames (%s) do not match OMPD task frames (%s)!"
385 % (ompt_task_frames
, ompd_task_frames
)
389 if "ompt_task_data" in field_names
:
390 ompt_task_data
= thread_data
["ompt_task_data"].dereference()["value"]
391 current_task_handle
= curr_thread
.get_current_task_handle()
392 ompd_value
= ompdModule
.call_ompd_get_tool_data(6, current_task_handle
)[0]
393 if ompt_task_data
!= ompd_value
:
395 "OMPT-OMPD mismatch: value of ompt_task_data (%d) does not match that of OMPD data union (%d)!"
396 % (ompt_task_data
, ompd_value
)
399 def save_thread_object(self
, thread_num
, thread_id
, addr_space
):
400 """Saves thread object for thread_num inside threads dictionary."""
401 thread_handle
= ompdModule
.get_thread_handle(thread_id
, addr_space
)
402 self
.threads
[int(thread_num
)] = ompd_thread(thread_handle
)
404 def get_thread(self
, thread_num
):
405 """Get thread object from map."""
406 return self
.threads
[int(thread_num
)]
408 def get_curr_thread(self
):
409 """Get current thread object from map or add new one to map, if missing."""
410 thread_num
= int(gdb
.selected_thread().num
)
411 if thread_num
not in self
.threads
:
413 return self
.threads
[thread_num
]
415 def add_thread(self
):
416 """Add currently selected (*) thread to dictionary threads."""
417 inf_thread
= gdb
.selected_thread()
419 self
.save_thread_object(inf_thread
.num
, inf_thread
.ptid
[1], self
.addr_space
)
421 traceback
.print_exc()
423 def list_threads(self
, verbose
):
424 """Prints OpenMP threads only that are being tracking inside the "threads" dictionary.
425 See handle_stop_event and add_thread.
428 curr_inferior
= gdb
.selected_inferior()
430 for inf_thread
in curr_inferior
.threads():
431 list_tids
.append((inf_thread
.num
, inf_thread
.ptid
))
433 if self
.states
is None:
434 self
.enumerate_states()
435 for (thread_num
, thread_ptid
) in sorted(list_tids
):
436 if thread_num
in self
.threads
:
439 "Thread %i (%i) is an OpenMP thread; state: %s"
443 self
.states
[self
.threads
[thread_num
].get_state()[0]],
447 traceback
.print_exc()
450 "Thread %i (%i) is no OpenMP thread"
451 % (thread_num
, thread_ptid
[1])
454 def enumerate_states(self
):
455 """Helper function for list_threads: initializes map of OMPD states for output of
458 if self
.states
is None:
460 current
= int("0x102", 0)
465 tup
= ompdModule
.call_ompd_enumerate_states(self
.addr_space
, current
)
466 (next_state
, next_state_name
, more
) = tup
468 self
.states
[next_state
] = next_state_name