import ompdModule
import imp
class ompd_parallel(object):
def __init__(self, parallel_handle):
"""Initializes an ompd_parallel object with the pointer
to a handle of a parallel region."""
self.parallel_handle = parallel_handle
self.threads = {}
self.itasks = {}
self.enclosing_parallel_handle = None
self.enclosing_parallel = False
self.task_handle = None
def get_thread_in_parallel(self, thread_num):
"""Obtains thread handles for the threads associated with the
parallel region specified by parallel_handle."""
if not thread_num in self.threads:
thread_handle = ompdModule.call_ompd_get_thread_in_parallel(
self.parallel_handle, thread_num
)
self.threads[thread_num] = ompd_thread(thread_handle)
return self.threads[thread_num]
def get_enclosing_parallel_handle(self):
"""Obtains a parallel handle for the parallel region enclosing
the parallel region specified by parallel_handle."""
if not self.enclosing_parallel_handle:
self.enclosing_parallel_handle = (
ompdModule.call_ompd_get_enclosing_parallel_handle(self.parallel_handle)
)
return self.enclosing_parallel_handle
def get_enclosing_parallel(self):
if not self.enclosing_parallel:
self.enclosing_parallel = ompd_parallel(
self.get_enclosing_parallel_handle()
)
return self.enclosing_parallel
def get_task_in_parallel(self, thread_num):
"""Obtains handles for the implicit tasks associated with the
parallel region specified by parallel_handle."""
if not thread_num in self.itasks:
task_handle = ompdModule.call_ompd_get_task_in_parallel(
self.parallel_handle, thread_num
)
self.itasks[thread_num] = ompd_task(task_handle)
return self.itasks[thread_num]
def __del__(self):
"""Releases the parallel handle."""
pass # let capsule destructors do the job
class ompd_task(object):
def __init__(self, task_handle):
"""Initializes a new ompd_task_handle object and sets the attribute
to the task handle specified."""
self.task_handle = task_handle
self.task_parallel_handle = False
self.generating_task_handle = False
self.scheduling_task_handle = False
self.task_parallel = False
self.generating_task = False
self.scheduling_task = False
self.task_frames = None
self.task_frame_flags = None
def get_task_parallel_handle(self):
"""Obtains a task parallel handle for the parallel region enclosing
the task region specified."""
if not self.task_parallel_handle:
self.task_parallel_handle = ompdModule.call_ompd_get_task_parallel_handle(
self.task_handle
)
return self.task_parallel_handle
def get_task_parallel(self):
if not self.task_parallel:
self.task_parallel = ompd_parallel(self.get_task_parallel_handle())
return self.task_parallel
def get_generating_task_handle(self):
"""Obtains the task handle for the task that created the task specified
by the task handle."""
if not self.generating_task_handle:
self.generating_task_handle = (
ompdModule.call_ompd_get_generating_task_handle(self.task_handle)
)
return self.generating_task_handle
def get_generating_task(self):
if not self.generating_task:
self.generating_task = ompd_task(
ompdModule.call_ompd_get_generating_task_handle(self.task_handle)
)
return self.generating_task
def get_scheduling_task_handle(self):
"""Obtains the task handle for the task that scheduled the task specified."""
if not self.scheduling_task_handle:
self.scheduling_task_handle = (
ompdModule.call_ompd_get_scheduling_task_handle(self.task_handle)
)
return self.scheduling_task_handle
def get_scheduling_task(self):
"""Returns ompd_task object for the task that scheduled the current task."""
if not self.scheduling_task:
self.scheduling_task = ompd_task(self.get_scheduling_task_handle())
return self.scheduling_task
def get_task_function(self):
"""Returns long with address of function entry point."""
return ompdModule.call_ompd_get_task_function(self.task_handle)
def get_task_frame_with_flags(self):
"""Returns enter frame address and flag, exit frame address and flag for current task handle."""
if self.task_frames is None or self.task_frame_flags is None:
ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle)
if isinstance(ret_value, tuple):
self.task_frames = (ret_value[0], ret_value[2])
self.task_frame_flags = (ret_value[1], ret_value[3])
else:
return ret_value
return (
self.task_frames[0],
self.task_frame_flags[0],
self.task_frames[1],
self.task_frame_flags[1],
)
def get_task_frame(self):
"""Returns enter and exit frame address for current task handle."""
if self.task_frames is None:
ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle)
if isinstance(ret_value, tuple):
self.task_frames = (ret_value[0], ret_value[2])
else:
return ret_value
return self.task_frames
def __del__(self):
"""Releases the task handle."""
pass # let capsule destructors do the job
class ompd_thread(object):
def __init__(self, thread_handle):
"""Initializes an ompd_thread with the data received from
GDB."""
self.thread_handle = thread_handle
self.parallel_handle = None
self.task_handle = None
self.current_task = False
self.current_parallel = False
self.thread_id = False
def get_current_parallel_handle(self):
"""Obtains the parallel handle for the parallel region associated with
the given thread handle."""
# TODO: invalidate thread objects based on `gdb.event.cont`. This should invalidate all internal state.
self.parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(
self.thread_handle
)
return self.parallel_handle
def get_current_parallel(self):
"""Returns parallel object for parallel handle of the parallel region
associated with the current thread handle."""
if not self.current_parallel:
self.current_parallel = ompd_parallel(self.get_current_parallel_handle())
return self.current_parallel
def get_current_task_handle(self):
"""Obtains the task handle for the current task region of the
given thread."""
return ompdModule.call_ompd_get_curr_task_handle(self.thread_handle)
def get_thread_id(self):
"""Obtains the ID for the given thread."""
if not self.thread_id:
self.thread_id = ompdModule.call_ompd_get_thread_id(self.thread_handle)
return self.thread_id
def get_current_task(self):
"""Returns task object for task handle of the current task region."""
return ompd_task(self.get_current_task_handle())
def get_state(self):
"""Returns tuple with OMPD state (long) and wait_id, in case the thread is in a
waiting state. Helper function for 'ompd threads' command."""
(state, wait_id) = ompdModule.call_ompd_get_state(self.thread_handle)
return (state, wait_id)
def __del__(self):
"""Releases the given thread handle."""
pass # let capsule destructors do the job