Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / openmp / libompd / gdb-plugin / ompd / ompd_address_space.py
blob3c4f35715a1e70917deecb2af97cb452d5ae91d0
1 from __future__ import print_function
2 import ompdModule
3 from ompd_handles import ompd_thread, ompd_task, ompd_parallel
4 import gdb
5 import sys
6 import traceback
7 from enum import Enum
10 class ompd_scope(Enum):
11 ompd_scope_global = 1
12 ompd_scope_address_space = 2
13 ompd_scope_thread = 3
14 ompd_scope_parallel = 4
15 ompd_scope_implicit_task = 5
16 ompd_scope_task = 6
19 class ompd_address_space(object):
20 def __init__(self):
21 """Initializes an ompd_address_space object by calling ompd_initialize
22 in ompdModule.c
23 """
24 self.addr_space = ompdModule.call_ompd_initialize()
25 # maps thread_num (thread id given by gdb) to ompd_thread object with thread handle
26 self.threads = {}
27 self.states = None
28 self.icv_map = None
29 self.ompd_tool_test_bp = None
30 self.scope_map = {
31 1: "global",
32 2: "address_space",
33 3: "thread",
34 4: "parallel",
35 5: "implicit_task",
36 6: "task",
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
49 thread is created.
50 """
51 if isinstance(event, gdb.BreakpointEvent):
52 # check if breakpoint has already been hit
53 if self.new_thread_breakpoint in event.breakpoints:
54 self.add_thread()
55 gdb.execute("continue")
56 return
57 elif (
58 self.ompd_tool_test_bp is not None
59 and self.ompd_tool_test_bp in event.breakpoints
61 try:
62 self.compare_ompt_data()
63 gdb.execute("continue")
64 except ():
65 traceback.print_exc()
66 elif isinstance(event, gdb.SignalEvent):
67 # TODO: what do we need to do on SIGNALS?
68 pass
69 else:
70 # TODO: probably not possible?
71 pass
73 def get_icv_map(self):
74 """Fills ICV map."""
75 self.icv_map = {}
76 current = 0
77 more = 1
78 while more > 0:
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.")
96 return
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:
103 self.get_icv_map()
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:
112 print(
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:
122 print(
123 "OMPT-OMPD mismatch: ompt_wait_id (%d) does not match OMPD wait id (%d)!"
124 % (ompt_wait_id, ompd_wait_id)
127 # compare thread 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:
136 print(
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
146 )[0]
147 if ompt_thread_data != ompd_value:
148 print(
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:
162 print(
163 "OMPT-OMPD mismatch: omp_num_threads (%d) does not match OMPD num threads according to ICVs (%d)!"
164 % (ompt_num_threads, icv_value)
167 # compare omp level
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:
176 print(
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:
190 print(
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()[
198 "value"
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:
205 print(
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:
225 print(
226 "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (None Object)"
227 % (ompt_max_threads)
229 else:
230 if ompt_max_threads != int(icv_string.split(",")[0]):
231 print(
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]))
235 else:
236 if ompt_max_threads != icv_value:
237 print(
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],
251 if (
252 ompt_parallel == 1
253 and icv_value <= 0
254 or ompt_parallel == 0
255 and icv_value > 0
257 print(
258 "OMPT-OMPD mismatch: ompt_parallel (%d) does not match OMPD parallel according to ICVs (%d)!"
259 % (ompt_parallel, icv_value)
262 # compare omp_final
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(
267 current_task_handle,
268 self.icv_map["final-task-var"][1],
269 self.icv_map["final-task-var"][0],
271 if icv_value != ompt_final:
272 print(
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:
286 print(
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
292 if (
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:
303 print(
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:
318 print(
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)
334 else:
335 ompd_sched_mod = 0
336 if ompt_sched_mod != ompd_sched_mod:
337 print(
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:
356 print(
357 "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (None Object)"
358 % (ompt_proc_bind)
360 else:
361 if ompt_proc_bind != int(icv_string.split(",")[0]):
362 print(
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]))
366 else:
367 if ompt_proc_bind != icv_value:
368 print(
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()
376 ompt_task_frames = (
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:
383 print(
384 "OMPT-OMPD mismatch: ompt_task_frames (%s) do not match OMPD task frames (%s)!"
385 % (ompt_task_frames, ompd_task_frames)
388 # compare task data
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:
394 print(
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:
412 self.add_thread()
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()
418 try:
419 self.save_thread_object(inf_thread.num, inf_thread.ptid[1], self.addr_space)
420 except:
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.
427 list_tids = []
428 curr_inferior = gdb.selected_inferior()
430 for inf_thread in curr_inferior.threads():
431 list_tids.append((inf_thread.num, inf_thread.ptid))
432 if verbose:
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:
437 try:
438 print(
439 "Thread %i (%i) is an OpenMP thread; state: %s"
441 thread_num,
442 thread_ptid[1],
443 self.states[self.threads[thread_num].get_state()[0]],
446 except:
447 traceback.print_exc()
448 else:
449 print(
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
456 'ompd threads'.
458 if self.states is None:
459 self.states = {}
460 current = int("0x102", 0)
461 count = 0
462 more = 1
464 while more > 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
469 current = next_state