ai-content-maker/.venv/Lib/site-packages/numba/misc/gdb_print_extension.py

205 lines
7.5 KiB
Python

"""gdb printing extension for Numba types.
"""
import re
try:
import gdb.printing
import gdb
except ImportError:
raise ImportError("GDB python support is not available.")
class NumbaArrayPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
try:
import numpy as np
HAVE_NUMPY = True
except ImportError:
HAVE_NUMPY = False
try:
NULL = 0x0
# Raw data references, these need unpacking/interpreting.
# Member "data" is...
# DW_TAG_member of DIDerivedType, tag of DW_TAG_pointer_type
# encoding e.g. DW_ATE_float
data = self.val["data"]
# Member "itemsize" is...
# DW_TAG_member of DIBasicType encoding DW_ATE_signed
itemsize = self.val["itemsize"]
# Members "shape" and "strides" are...
# DW_TAG_member of DIDerivedType, the type is a DICompositeType
# (it's a Numba UniTuple) with tag: DW_TAG_array_type, i.e. it's an
# array repr, it has a basetype of e.g. DW_ATE_unsigned and also
# "elements" which are referenced with a DISubrange(count: <const>)
# to say how many elements are in the array.
rshp = self.val["shape"]
rstrides = self.val["strides"]
# bool on whether the data is aligned.
is_aligned = False
# type information decode, simple type:
ty_str = str(self.val.type)
if HAVE_NUMPY and ('aligned' in ty_str or 'Record' in ty_str):
ty_str = ty_str.replace('unaligned ','').strip()
matcher = re.compile(r"array\((Record.*), (.*), (.*)\)\ \(.*")
# NOTE: need to deal with "Alignment" else dtype size is wrong
arr_info = [x.strip() for x in matcher.match(ty_str).groups()]
dtype_str, ndim_str, order_str = arr_info
rstr = r'Record\((.*\[.*\]);([0-9]+);(True|False)'
rstr_match = re.match(rstr, dtype_str)
# balign is unused, it's the alignment
fields, balign, is_aligned_str = rstr_match.groups()
is_aligned = is_aligned_str == 'True'
field_dts = fields.split(',')
struct_entries = []
for f in field_dts:
splitted = f.split('[')
name = splitted[0]
dt_part = splitted[1:]
if len(dt_part) > 1:
raise TypeError('Unsupported sub-type: %s' % f)
else:
dt_part = dt_part[0]
if "nestedarray" in dt_part:
raise TypeError('Unsupported sub-type: %s' % f)
dt_as_str = dt_part.split(';')[0].split('=')[1]
dtype = np.dtype(dt_as_str)
struct_entries.append((name, dtype))
# The dtype is actually a record of some sort
dtype_str = struct_entries
else: # simple type
matcher = re.compile(r"array\((.*),(.*),(.*)\)\ \(.*")
arr_info = [x.strip() for x in matcher.match(ty_str).groups()]
dtype_str, ndim_str, order_str = arr_info
# fix up unichr dtype
if 'unichr x ' in dtype_str:
dtype_str = dtype_str[1:-1].replace('unichr x ', '<U')
def dwarr2inttuple(dwarr):
# Converts a gdb handle to a dwarf array to a tuple of ints
fields = dwarr.type.fields()
lo, hi = fields[0].type.range()
return tuple([int(dwarr[x]) for x in range(lo, hi + 1)])
# shape/strides extraction
shape = dwarr2inttuple(rshp)
strides = dwarr2inttuple(rstrides)
# if data is not NULL
if data != NULL:
if HAVE_NUMPY:
# The data extent in bytes is:
# sum(shape * strides)
# get the data, then wire to as_strided
shp_arr = np.array([max(0, x - 1) for x in shape])
strd_arr = np.array(strides)
extent = np.sum(shp_arr * strd_arr)
extent += int(itemsize)
dtype_clazz = np.dtype(dtype_str, align=is_aligned)
dtype = dtype_clazz
this_proc = gdb.selected_inferior()
mem = this_proc.read_memory(int(data), extent)
arr_data = np.frombuffer(mem, dtype=dtype)
new_arr = np.lib.stride_tricks.as_strided(arr_data,
shape=shape,
strides=strides,)
return '\n' + str(new_arr)
# Catch all for no NumPy
return "array([...], dtype=%s, shape=%s)" % (dtype_str, shape)
else:
# Not yet initialized or NULLed out data
buf = list(["NULL/Uninitialized"])
return "array([" + ', '.join(buf) + "]" + ")"
except Exception as e:
return 'array[Exception: Failed to parse. %s]' % e
class NumbaComplexPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return "%s+%sj" % (self.val['real'], self.val['imag'])
class NumbaTuplePrinter:
def __init__(self, val):
self.val = val
def to_string(self):
buf = []
fields = self.val.type.fields()
for f in fields:
buf.append(str(self.val[f.name]))
return "(%s)" % ', '.join(buf)
class NumbaUniTuplePrinter:
def __init__(self, val):
self.val = val
def to_string(self):
# unituples are arrays
fields = self.val.type.fields()
lo, hi = fields[0].type.range()
buf = []
for i in range(lo, hi + 1):
buf.append(str(self.val[i]))
return "(%s)" % ', '.join(buf)
class NumbaUnicodeTypePrinter:
def __init__(self, val):
self.val = val
def to_string(self):
NULL = 0x0
data = self.val["data"]
nitems = self.val["length"]
kind = self.val["kind"]
if data != NULL:
# This needs sorting out, encoding is wrong
this_proc = gdb.selected_inferior()
mem = this_proc.read_memory(int(data), nitems * kind)
if isinstance(mem, memoryview):
buf = bytes(mem).decode()
else:
buf = mem.decode('utf-8')
else:
buf = str(data)
return "'%s'" % buf
def _create_printers():
printer = gdb.printing.RegexpCollectionPrettyPrinter("Numba")
printer.add_printer('Numba unaligned array printer', '^unaligned array\\(',
NumbaArrayPrinter)
printer.add_printer('Numba array printer', '^array\\(', NumbaArrayPrinter)
printer.add_printer('Numba complex printer', '^complex[0-9]+\\ ',
NumbaComplexPrinter)
printer.add_printer('Numba Tuple printer', '^Tuple\\(',
NumbaTuplePrinter)
printer.add_printer('Numba UniTuple printer', '^UniTuple\\(',
NumbaUniTuplePrinter)
printer.add_printer('Numba unicode_type printer', '^unicode_type\\s+\\(',
NumbaUnicodeTypePrinter)
return printer
# register the Numba pretty printers for the current object
gdb.printing.register_pretty_printer(gdb.current_objfile(), _create_printers())