提交 c674bf0e 编写于 作者: M Megvii Engine Team

feat(debug): add gdb-scripts

GitOrigin-RevId: 43f9674f505637d3ad367c1d20a94b844f96a04b
上级 dc42417f
source ./scripts/gdb/pretty_printers.py
source ./scripts/gdb/xmethods.py
catch throw
......@@ -137,7 +137,7 @@ Handle ChannelImpl::put(const HostTensorND& value, bool no_cache) {
auto& state = get_channel_state();
auto _ = StackManager::Guard{"Put", &state.stack_manager};
auto info = put_impl(value, no_cache);
return info;
return reinterpret_cast<Handle>(info);
}
TensorInfo* ChannelImpl::put_impl(const HostTensorND& value, bool no_cache) {
......@@ -161,7 +161,7 @@ TensorInfo* ChannelImpl::put_impl(const HostTensorND& value, bool no_cache) {
Handle ChannelImpl::put(const DeviceTensorND& data, const HostTensorND& hvalue) {
MGB_LOCK_GUARD(m_spin);
mgb_assert(check_available(), "Channel already closed");
return put_impl(data, hvalue);
return reinterpret_cast<Handle>(put_impl(data, hvalue));
}
TensorInfo* ChannelImpl::put_impl(const DeviceTensorND& data, const HostTensorND& hvalue) {
auto& state = get_channel_state();
......@@ -287,7 +287,7 @@ void ChannelImpl::dispatch_default_cpu(
auto info = reinterpret_cast<TensorInfo*>(put_impl(host_tensornd, false));
mgb_assert(info->desc.layout.ndim != 0);
output_infos.push_back(info);
outputs->push_back(info);
outputs->push_back(reinterpret_cast<Handle>(info));
}
auto op_info_getter = [op]{
std::unordered_map<std::string, std::string> op_info;
......@@ -330,7 +330,7 @@ void ChannelImpl::dispatch_kernel(
.proxy_to_comp_node(desc.comp_node);
}
cmd.outputs.push_back(info);
outputs->push_back(info);
outputs->push_back(reinterpret_cast<Handle>(info));
}
auto op_info_getter = [op=cmd.op]{
std::unordered_map<std::string, std::string> op_info;
......@@ -519,7 +519,7 @@ TensorInfo* ChannelImpl::alloc() {
}
void ChannelImpl::init(TensorInfo* info, LogicalTensorDesc desc) {
m_valid_handle.insert(info);
m_valid_handle.insert(reinterpret_cast<Handle>(info));
MGB_RECORD_EVENT(TensorDeclareEvent, info->id, info->name);
info->status = TensorInfo::Allocated;
info->desc = std::move(desc);
......
......@@ -28,7 +28,8 @@ struct AsyncError : std::nested_exception, std::exception {
};
struct Interpreter {
using Handle = void*;
struct HandleImpl{};
using Handle = HandleImpl*;
struct Channel {
virtual ~Channel() = default;
......
......@@ -33,7 +33,7 @@ struct Expr {
template <typename T>
struct ToStringTrait<Expr<T>> {
std::string operator()(const Expr<T>& expr) {
return ssprintf("%s = %s %s\n", to_string(expr.inputs).c_str(), to_string(expr.op.get()).c_str(), to_string(expr.outputs).c_str());
return ssprintf("%s = %s %s\n", to_string(expr.outputs).c_str(), to_string(expr.op.get()).c_str(), to_string(expr.inputs).c_str());
}
};
......
import gdb
import gdb.printing
import gdb.types
def eval_on_val(val, eval_str):
eval_str = "(*({}*)({})).{}".format(val.type, val.address, eval_str)
return gdb.parse_and_eval(eval_str)
class SmallVectorPrinter:
def __init__(self, val):
t = val.type.template_argument(0)
self.begin = val['m_begin_ptr'].cast(t.pointer())
self.end = val['m_end_ptr'].cast(t.pointer())
self.size = self.end - self.begin
self.capacity = val['m_capacity_ptr'].cast(t.pointer()) - val['m_begin_ptr'].cast(t.pointer())
def to_string(self):
return 'SmallVector of Size {}'.format(self.size)
def display_hint(self):
return 'array'
def children(self):
for i in range(self.size):
yield "[{}]".format(i), (self.begin+i).dereference()
class MaybePrinter:
def __init__(self, val):
self.val = val['m_ptr']
def to_string(self):
if self.val:
return 'Some {}'.format(self.val)
else:
return 'None'
def display_hint(self):
return 'array'
def children(self):
if self.val:
yield '[0]', self.val.dereference()
class ToStringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return eval_on_val(self.val, "to_string().c_str()").string()
class ReprPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return eval_on_val(self.val, "repr().c_str()").string()
class HandlePrinter:
def __init__(self, val):
impl = gdb.lookup_type("mgb::imperative::interpreter::intl::TensorInfo")
self.val = val.cast(impl.pointer())
def to_string(self):
if self.val:
return 'Handle of TensorInfo at {}'.format(self.val)
else:
return 'Empty Handle'
def display_hint(self):
return 'array'
def children(self):
if self.val:
yield '[0]', self.val.dereference()
def print_small_tensor(device_nd):
size = device_nd["m_storage"]["m_size"]
ndim = device_nd["m_layout"]["ndim"]
dim0 = device_nd["m_layout"]["shape"][0]
stride0 = device_nd["m_layout"]["stride"][0]
dtype = device_nd["m_layout"]["dtype"]
if size == 0:
return "<empty>"
if ndim > 1:
return "<ndim > 1>"
if dim0 > 64:
return "<size tool large>"
raw_ptr = device_nd["m_storage"]["m_data"]["_M_ptr"]
dtype_name = dtype["m_trait"]["name"].string()
dtype_map = {
"Float32": (gdb.lookup_type("float"), float),
"Int32": (gdb.lookup_type("int"), int),
}
if dtype_name not in dtype_map:
return "<dtype unsupported>"
else:
ctype, pytype = dtype_map[dtype_name]
ptr = raw_ptr.cast(ctype.pointer())
array = []
for i in range(dim0):
array.append((pytype)((ptr + i * int(stride0)).dereference()))
return str(array)
class LogicalTensorDescPrinter:
def __init__(self, val):
self.layout = val['layout']
self.comp_node = val['comp_node']
self.value = val['value']
def to_string(self):
return 'LogicalTensorDesc'
def children(self):
yield 'layout', self.layout
yield 'comp_node', self.comp_node
yield 'value', print_small_tensor(self.value)
class OpDefPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return self.val.dynamic_type.name
def children(self):
concrete_val = self.val.address.cast(self.val.dynamic_type.pointer()).dereference()
for field in concrete_val.type.fields():
if field.is_base_class or field.artificial:
continue
if field.name == 'sm_typeinfo':
continue
yield field.name, concrete_val[field.name]
pp = gdb.printing.RegexpCollectionPrettyPrinter("MegEngine")
# megdnn
pp.add_printer('megdnn::SmallVectorImpl', '^megdnn::SmallVector(Impl)?<.*>$', SmallVectorPrinter)
pp.add_printer('megdnn::TensorLayout', '^megdnn::TensorLayout$', ToStringPrinter)
pp.add_printer('megdnn::TensorShape', '^megdnn::TensorShape$', ToStringPrinter)
# megbrain
pp.add_printer('mgb::CompNode', '^mgb::CompNode$', ToStringPrinter)
pp.add_printer('mgb::Maybe', '^mgb::Maybe<.*>$', MaybePrinter)
# imperative
pp.add_printer('mgb::imperative::LogicalTensorDesc', '^mgb::imperative::LogicalTensorDesc$', LogicalTensorDescPrinter)
pp.add_printer('mgb::imperative::OpDef', '^mgb::imperative::OpDef$', OpDefPrinter)
pp.add_printer('mgb::imperative::Subgraph', '^mgb::imperative::Subgraph$', ReprPrinter)
pp.add_printer('mgb::imperative::EncodedSubgraph', '^mgb::imperative::EncodedSubgraph$', ReprPrinter)
gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
def override_pretty_printer_for(val):
type = val.type.strip_typedefs()
if type.code == gdb.TYPE_CODE_PTR:
if not val:
return None
target_typename = str(type.target().strip_typedefs())
if target_typename == "mgb::imperative::OpDef":
return OpDefPrinter(val.dereference())
if target_typename == "mgb::imperative::interpreter::Interpreter::HandleImpl":
return HandlePrinter(val)
gdb.pretty_printers.append(override_pretty_printer_for)
import re
import gdb
import gdb.types
import gdb.xmethod
class SmallVectorImplWorker_at(gdb.xmethod.XMethodWorker):
def __init__(self, t):
self.t = t
def get_arg_types(self):
return gdb.lookup_type('int')
def get_result_type(self, *args):
return self.t
def __call__(self, obj, i):
return (obj['m_begin_ptr'].cast(self.t.pointer()) + i).dereference()
class SmallVectorImplWorker_size(gdb.xmethod.XMethodWorker):
def __init__(self, t):
self.t = t
def get_arg_types(self):
return None
def get_result_type(self, *args):
return gdb.lookup_type('int')
def __call__(self, obj):
return obj['m_end_ptr'].cast(self.t.pointer()) - obj['m_begin_ptr'].cast(self.t.pointer())
class SmallVectorImplMatcher(gdb.xmethod.XMethodMatcher):
def __init__(self):
super().__init__('SmallVectorImplMatcher')
def match(self, class_type, method_name):
if re.match('^megdnn::SmallVector(Impl)?<.*>',
class_type.tag):
if method_name == 'at':
return SmallVectorImplWorker_at(class_type.template_argument(0))
if method_name == 'operator[]':
return SmallVectorImplWorker_at(class_type.template_argument(0))
if method_name == 'size':
return SmallVectorImplWorker_size(class_type.template_argument(0))
gdb.xmethod.register_xmethod_matcher(None, SmallVectorImplMatcher())
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册