repr#
源码 tvm/include/tvm/node/repr_printer.h
ReprPrinter
#
/*! \brief A printer class to print the AST/IR nodes. */
class ReprPrinter {
public:
/*! \brief The output stream */
std::ostream& stream;
/*! \brief The indentation level. */
int indent{0};
explicit ReprPrinter(std::ostream& stream) // NOLINT(*)
: stream(stream) {}
/*! \brief The node to be printed. */
TVM_DLL void Print(const ObjectRef& node);
/*! \brief Print indent to the stream */
TVM_DLL void PrintIndent();
// Allow registration to be printer.
using FType = NodeFunctor<void(const ObjectRef&, ReprPrinter*)>;
TVM_DLL static FType& vtable();
};
ReprPrinter
打印类,用于打印抽象语法树(AST)或中间表示(IR)节点。它包含以下成员变量和成员函数:
std::ostream& stream
:输出流,用于将打印结果输出到指定的流中。int indent{0}
:缩进级别,用于控制打印时的缩进空格数。explicit ReprPrinter(std::ostream& stream)
:构造函数,接收一个输出流参数,并将其赋值给stream
成员变量。TVM_DLL void Print(const ObjectRef& node)
:打印节点的成员函数,接收ObjectRef
类型的参数,表示要打印的节点。TVM_DLL void PrintIndent()
:打印缩进的成员函数,用于在打印节点时添加适当的缩进。using FType = NodeFunctor<void(const ObjectRef&, ReprPrinter*)>
:定义了类型别名FType
,表示接受ObjectRef
和ReprPrinter*
参数的函数对象类型。TVM_DLL static FType& vtable()
:静态成员函数,返回FType
类型的引用,用于注册到打印器中。
namespace tvm {
namespace runtime {
// default print function for all objects
// provide in the runtime namespace as this is where objectref originally comes from.
inline std::ostream& operator<<(std::ostream& os, const ObjectRef& n) { // NOLINT(*)
ReprPrinter(os).Print(n);
return os;
}
}
}
这段代码是内联函数,用于重载 operator<<
运算符。它接受 std::ostream
引用和 ObjectRef
常量引用作为参数。函数的作用是将 ObjectRef
对象的内容输出到 std::ostream
中。
在函数内部,首先创建了 ReprPrinter
对象,并将 os
作为参数传递给它。然后调用 ReprPrinter
对象的 Print
方法,将 n
作为参数传递。最后返回 os
,以便可以继续使用该流进行其他操作。
这个函数通常用于自定义对象的打印输出,使得在调试或日志记录时能够更方便地查看对象的内容。
void ReprPrinter::Print(const ObjectRef& node) {
static const FType& f = vtable();
if (!node.defined()) {
stream << "(nullptr)";
} else {
if (f.can_dispatch(node)) {
f(node, this);
} else {
// default value, output type key and addr.
stream << node->GetTypeKey() << "(" << node.get() << ")";
}
}
}
void ReprPrinter::PrintIndent() {
for (int i = 0; i < indent; ++i) {
stream << ' ';
}
}
ReprPrinter::FType& ReprPrinter::vtable() {
static FType inst;
return inst;
}
这段代码是 C++ 中的类 ReprPrinter
的实现。这个类的主要功能是打印对象的内容。
Print(const ObjectRef& node)
函数:这个函数接受ObjectRef
类型的参数node
,表示要打印的对象。首先,它获取对象的虚函数表(vtable),然后检查node
是否已定义。如果node
未定义,它将输出"(nullptr)"
;否则,它将检查虚函数表是否可以调度node
。如果可以,它将调用虚函数表对应的函数;否则,它将输出对象的类型键和地址。PrintIndent()
函数:这个函数用于在打印对象内容时添加缩进。它通过循环输出空格来实现缩进效果。vtable()
函数:这个函数返回类的静态虚函数表实例。这是一个单例模式的实现,确保在整个程序中只有一个虚函数表实例。
Dump
#
Dump
用于将节点信息输出到标准错误流(stderr)以供调试使用。
第一个函数的声明如下:
TVM_DLL void Dump(const runtime::ObjectRef& node);
这个函数接受类型为 runtime::ObjectRef
的常量引用作为参数,表示输入的节点。函数没有返回值,并且使用了 TVM_DLL
宏来指定这是动态链接库中的函数。
第二个函数的声明如下:
TVM_DLL void Dump(const runtime::Object* node);
这个函数接受类型为 runtime::Object
的常量指针作为参数,表示输入的节点。函数同样没有返回值,并且也使用了 TVM_DLL
宏来指定这是动态链接库中的函数。
这两个函数的作用是将节点的信息输出到标准错误流,以便开发人员可以查看和调试。
void Dump(const runtime::ObjectRef& n) { std::cerr << n << "\n"; }
void Dump(const runtime::Object* n) { Dump(runtime::GetRef<runtime::ObjectRef>(n)); }
TVM_REGISTER_GLOBAL("node.AsRepr").set_body_typed([](runtime::ObjectRef obj) {
std::ostringstream os;
os << obj;
return os.str();
});
这段代码定义了三个函数,以及全局注册的 TVM 模块。
void Dump(const runtime::ObjectRef& n)
:这个函数接受runtime::ObjectRef
类型的参数n
,并将其输出到标准错误流(std::cerr)。void Dump(const runtime::Object* n)
:这个函数接受指向runtime::Object
的指针n
,然后调用Dump
函数将其转换为runtime::ObjectRef
类型,并输出到标准错误流。TVM_REGISTER_GLOBAL("node.AsRepr")
:这是 TVM 模块的全局注册,用于将名为"node.AsRepr"
的函数注册到 TVM 运行时环境中。这个函数接受runtime::ObjectRef
类型的参数,将其转换为字符串,并返回。 总结:这段代码定义了用于打印对象引用的函数,以及 TVM 模块的全局注册。