import os
from collections import defaultdict
import gdb
import mcgdb
from mcgdb.toolbox import my_gdb
from . import interaction
api_has_events = False
[docs]class Runtime:
def __init__(self):
self.uid = "rt"
[docs] def event_id_name_kind(self):
return "rt", "", "Runtime"
runtime = None
@my_gdb.Listed
@my_gdb.Numbered
@my_gdb.Dicted
[docs]class Program:
def __init__(self, handle):
Program.init_dict(str(handle), self)
self.name = "Program #%d (%s)" % (self.numbers[Program], handle)
self.kernels = []
self.uid = handle
def __str__(self):
return self.name
@my_gdb.Listed
@my_gdb.Numbered
@my_gdb.Dicted
[docs]class Kernel:
RUNNING = "RUNNING"
def __init__(self, program, name, handle, stack):
Kernel.init_dict(str(handle), self)
self.name = name
self.handle = str(handle)
self.stack = stack
self.buffers = []
self.buffers_hist = defaultdict(int)
self.state = None
self.uid = self.handle
self.dead = False
self.use_count = 0
self.do_break = False
self.hide = False
if str(program) not in Program.dict_.keys():
self.program = Program(program)
else:
self.program = Program.key_to_value(program)
self.program.kernels.append(self)
print ("[New kernel %s --> %s]" % (self.name, self.handle))
Event("#!|NEW_K|%s|%s|%s|#" % (self.uid, self.name, self.program), key=self)
[docs] def event_id_name_kind(self):
return self.handle, "#%d %s " % (self.numbers[Kernel], self.name), "Kernel"
[docs] def count_buffer_use(self, buffer):
return self.buffers_hist[buffer] + (1 if buffer in self.buffers else 0)
@my_gdb.Listed
@my_gdb.Numbered
@my_gdb.Dicted
[docs]class Buffer:
READ_ONLY = 0
READ_WRITE = 1
WRITE_ONLY = 2
WRITE_AVAILABLE = "WRITE_AVAILABLE"
READ_AVAILABLE = "READ_AVAILABLE"
OVERWRITTEN = "OVERWRITTEN"
TRANSFERED = "TRANSFERED"
def __init__(self, handle, mode=None, stack=None, line=None, name=None, size=None):
Buffer.init_dict(str(handle), self)
self.handle = str(handle)
self.mode = mode
self.state = Buffer.WRITE_AVAILABLE
self.stack = stack
self.line = line
self.never_used = True
self.dead = False
self.size = size
self.do_break = False
self.use_count = 0
self.uid = self.handle
self.name = name if not name is None else self.handle
print ("[New buffer %s]" % (self.name))
Event("#!|NEW_B|%s|%s|%s|#" % (self.uid, self.name, self.mode[1]), key=self)
[docs] def get_name(self):
return "#%2d %s (%s)" % (self.numbers[Buffer], self.name, self.mode[1])
[docs] def event_id_name_kind(self):
return self.handle, self.get_name(), "Buffer"
[docs] def get_buffer_kernel_direction(self):
if self.mode[1] == Buffer.READ_ONLY:
return "forward"
elif self.mode[1] == Buffer.WRITE_ONLY:
return "back"
else:
return "both"
[docs] def count_kernel_use(self, kernel):
return kernel.count_buffer_use(self)
@my_gdb.Numbered
@my_gdb.Listed
[docs]class Event:
entities = []
lasts_ = []
def __init__(self, evt, key=False):
self.evt = evt
Event.lasts_.append(self)
self.key = key
if interaction.autograph.value:
interaction.print_flow.invoke("+clean", False)
def __str__(self):
return self.evt
[docs]def set_kernel_arg(kernel_p, index, size, value_p, value_pp, callsite):
kernel = Kernel.dict_[str(kernel_p)]
if not value_p or not str(value_p) in Buffer.dict_.keys():
src = runtime
name = str(value_pp)
else:
src = Buffer.dict_[str(value_p)]
name = "Buffer #%s" % src.numbers[Buffer]
kernel.buffers.append(src)
src.never_used = False
src.in_use = True
src.use_count += 1
if src.do_break:
my_gdb.push_stop_request("Catched buffer '%s' usage" % name)
Event("#!|SET_ARG|%d|%s|%s|%s|%s|#" % (index, src.uid, kernel.uid, name, callsite))
[docs]def enqueueKernel(kernel_p, ocl_event, callsite):
kernel = Kernel.dict_[str(kernel_p)]
gui_event = handle_event(ocl_event)
print ("[Execute kernel %s]" % (kernel.name))
Event("#!|EXECUTE_K|n|%s|%s|%s|#" % (kernel.uid, gui_event, callsite))
for buffer in kernel.buffers:
if buffer.mode[0] != Buffer.READ_ONLY:
buffer.state = Buffer.READ_AVAILABLE
buffer.in_use = False
kernel.buffers_hist[buffer] += 1
kernel.use_count += 1
kernel.buffers[:] = []
if kernel.do_break:
my_gdb.push_stop_request("Catched kernel '%s' execution" % kernel.name)
[docs]def releaseKernel(kernel_p):
kernel = Kernel.dict_[str(kernel_p)]
kernel.dead = True
Event("#!|DEL_K|%s|#" % kernel.uid)
print ("[Release kernel %s]" % (kernel.name))
[docs]def releaseBuffer(buffer_p):
try:
buffer = Buffer.dict_[str(buffer_p)]
except KeyError:
print ("Unknown buffer: %s" % str(buffer_p))
return
Event("#!|DEL_B|%s|#" % buffer.uid)
buffer.dead = True
print ("[Release buffer %s]" % (buffer.name))
[docs]def enqueue_transfer_buffer(buffer_val, blocking, ocl_event, is_read=True, callsite=None):
buffer = None
if not str(buffer_val) in Buffer.dict_.keys():
for b in Buffer.list_:
if b.size is None:
continue
dist = int(gdb.parse_and_eval("%s - %s" % (str(buffer_val), b.handle)))
if dist < b.size:
buffer = b
#break
return
else:
buffer = Buffer.dict_[str(buffer_val)]
if buffer is None:
print ("Unknown buffer")
return
gui_event = handle_event(ocl_event)
buffer.state = Buffer.TRANSFERED if is_read else Buffer.READ_AVAILABLE
buffer.use_count += 1
if buffer.do_break:
my_gdb.push_stop_request("Catched buffer '%s' usage" % buffer)
block = "X" if blocking else "O"
Event("#!|TRANSFER_B|%s|%s|n|%s|%s|%s|#" % ("R" if is_read else "W", block, buffer.uid, gui_event, callsite))
[docs]def handle_event(ocl_event):
"[event]>[event[+event]*]"
if not api_has_events:
return ">"
num_wait, wait_lst, new_event_p = ocl_event
event_str = str(new_event_p.dereference()) if str(new_event_p) != "0x0" else ""
event_str += ">"
event_str += "+".join(str(wait_lst[idx]) for idx in xrange(num_wait))
return event_str
[docs]def finishQueue():
Event("#!|FINISH|#")
[docs]def initialize():
global runtime
runtime = Runtime()