1import ompdModule 2import imp 3 4 5class ompd_parallel(object): 6 def __init__(self, parallel_handle): 7 """Initializes an ompd_parallel object with the pointer 8 to a handle of a parallel region.""" 9 self.parallel_handle = parallel_handle 10 self.threads = {} 11 self.itasks = {} 12 self.enclosing_parallel_handle = None 13 self.enclosing_parallel = False 14 self.task_handle = None 15 16 def get_thread_in_parallel(self, thread_num): 17 """Obtains thread handles for the threads associated with the 18 parallel region specified by parallel_handle.""" 19 if not thread_num in self.threads: 20 thread_handle = ompdModule.call_ompd_get_thread_in_parallel( 21 self.parallel_handle, thread_num 22 ) 23 self.threads[thread_num] = ompd_thread(thread_handle) 24 return self.threads[thread_num] 25 26 def get_enclosing_parallel_handle(self): 27 """Obtains a parallel handle for the parallel region enclosing 28 the parallel region specified by parallel_handle.""" 29 if not self.enclosing_parallel_handle: 30 self.enclosing_parallel_handle = ( 31 ompdModule.call_ompd_get_enclosing_parallel_handle(self.parallel_handle) 32 ) 33 return self.enclosing_parallel_handle 34 35 def get_enclosing_parallel(self): 36 if not self.enclosing_parallel: 37 self.enclosing_parallel = ompd_parallel( 38 self.get_enclosing_parallel_handle() 39 ) 40 return self.enclosing_parallel 41 42 def get_task_in_parallel(self, thread_num): 43 """Obtains handles for the implicit tasks associated with the 44 parallel region specified by parallel_handle.""" 45 if not thread_num in self.itasks: 46 task_handle = ompdModule.call_ompd_get_task_in_parallel( 47 self.parallel_handle, thread_num 48 ) 49 self.itasks[thread_num] = ompd_task(task_handle) 50 return self.itasks[thread_num] 51 52 def __del__(self): 53 """Releases the parallel handle.""" 54 pass # let capsule destructors do the job 55 56 57class ompd_task(object): 58 def __init__(self, task_handle): 59 """Initializes a new ompd_task_handle object and sets the attribute 60 to the task handle specified.""" 61 self.task_handle = task_handle 62 self.task_parallel_handle = False 63 self.generating_task_handle = False 64 self.scheduling_task_handle = False 65 self.task_parallel = False 66 self.generating_task = False 67 self.scheduling_task = False 68 self.task_frames = None 69 self.task_frame_flags = None 70 71 def get_task_parallel_handle(self): 72 """Obtains a task parallel handle for the parallel region enclosing 73 the task region specified.""" 74 if not self.task_parallel_handle: 75 self.task_parallel_handle = ompdModule.call_ompd_get_task_parallel_handle( 76 self.task_handle 77 ) 78 return self.task_parallel_handle 79 80 def get_task_parallel(self): 81 if not self.task_parallel: 82 self.task_parallel = ompd_parallel(self.get_task_parallel_handle()) 83 return self.task_parallel 84 85 def get_generating_task_handle(self): 86 """Obtains the task handle for the task that created the task specified 87 by the task handle.""" 88 if not self.generating_task_handle: 89 self.generating_task_handle = ( 90 ompdModule.call_ompd_get_generating_task_handle(self.task_handle) 91 ) 92 return self.generating_task_handle 93 94 def get_generating_task(self): 95 if not self.generating_task: 96 self.generating_task = ompd_task( 97 ompdModule.call_ompd_get_generating_task_handle(self.task_handle) 98 ) 99 return self.generating_task 100 101 def get_scheduling_task_handle(self): 102 """Obtains the task handle for the task that scheduled the task specified.""" 103 if not self.scheduling_task_handle: 104 self.scheduling_task_handle = ( 105 ompdModule.call_ompd_get_scheduling_task_handle(self.task_handle) 106 ) 107 return self.scheduling_task_handle 108 109 def get_scheduling_task(self): 110 """Returns ompd_task object for the task that scheduled the current task.""" 111 if not self.scheduling_task: 112 self.scheduling_task = ompd_task(self.get_scheduling_task_handle()) 113 return self.scheduling_task 114 115 def get_task_function(self): 116 """Returns long with address of function entry point.""" 117 return ompdModule.call_ompd_get_task_function(self.task_handle) 118 119 def get_task_frame_with_flags(self): 120 """Returns enter frame address and flag, exit frame address and flag for current task handle.""" 121 if self.task_frames is None or self.task_frame_flags is None: 122 ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle) 123 if isinstance(ret_value, tuple): 124 self.task_frames = (ret_value[0], ret_value[2]) 125 self.task_frame_flags = (ret_value[1], ret_value[3]) 126 else: 127 return ret_value 128 return ( 129 self.task_frames[0], 130 self.task_frame_flags[0], 131 self.task_frames[1], 132 self.task_frame_flags[1], 133 ) 134 135 def get_task_frame(self): 136 """Returns enter and exit frame address for current task handle.""" 137 if self.task_frames is None: 138 ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle) 139 if isinstance(ret_value, tuple): 140 self.task_frames = (ret_value[0], ret_value[2]) 141 else: 142 return ret_value 143 return self.task_frames 144 145 def __del__(self): 146 """Releases the task handle.""" 147 pass # let capsule destructors do the job 148 149 150class ompd_thread(object): 151 def __init__(self, thread_handle): 152 """Initializes an ompd_thread with the data received from 153 GDB.""" 154 self.thread_handle = thread_handle 155 self.parallel_handle = None 156 self.task_handle = None 157 self.current_task = False 158 self.current_parallel = False 159 self.thread_id = False 160 161 def get_current_parallel_handle(self): 162 """Obtains the parallel handle for the parallel region associated with 163 the given thread handle.""" 164 # TODO: invalidate thread objects based on `gdb.event.cont`. This should invalidate all internal state. 165 self.parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( 166 self.thread_handle 167 ) 168 return self.parallel_handle 169 170 def get_current_parallel(self): 171 """Returns parallel object for parallel handle of the parallel region 172 associated with the current thread handle.""" 173 if not self.current_parallel: 174 self.current_parallel = ompd_parallel(self.get_current_parallel_handle()) 175 return self.current_parallel 176 177 def get_current_task_handle(self): 178 """Obtains the task handle for the current task region of the 179 given thread.""" 180 return ompdModule.call_ompd_get_curr_task_handle(self.thread_handle) 181 182 def get_thread_id(self): 183 """Obtains the ID for the given thread.""" 184 if not self.thread_id: 185 self.thread_id = ompdModule.call_ompd_get_thread_id(self.thread_handle) 186 return self.thread_id 187 188 def get_current_task(self): 189 """Returns task object for task handle of the current task region.""" 190 return ompd_task(self.get_current_task_handle()) 191 192 def get_state(self): 193 """Returns tuple with OMPD state (long) and wait_id, in case the thread is in a 194 waiting state. Helper function for 'ompd threads' command.""" 195 (state, wait_id) = ompdModule.call_ompd_get_state(self.thread_handle) 196 return (state, wait_id) 197 198 def __del__(self): 199 """Releases the given thread handle.""" 200 pass # let capsule destructors do the job 201