repr

目录

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)节点。它包含以下成员变量和成员函数:

  1. std::ostream& stream:输出流,用于将打印结果输出到指定的流中。

  2. int indent{0}:缩进级别,用于控制打印时的缩进空格数。

  3. explicit ReprPrinter(std::ostream& stream):构造函数,接收一个输出流参数,并将其赋值给 stream 成员变量。

  4. TVM_DLL void Print(const ObjectRef& node):打印节点的成员函数,接收 ObjectRef 类型的参数,表示要打印的节点。

  5. TVM_DLL void PrintIndent():打印缩进的成员函数,用于在打印节点时添加适当的缩进。

  6. using FType = NodeFunctor<void(const ObjectRef&, ReprPrinter*)>:定义了类型别名 FType,表示接受 ObjectRefReprPrinter* 参数的函数对象类型。

  7. 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 的实现。这个类的主要功能是打印对象的内容。

  1. Print(const ObjectRef& node) 函数:这个函数接受 ObjectRef 类型的参数 node,表示要打印的对象。首先,它获取对象的虚函数表(vtable),然后检查 node 是否已定义。如果 node 未定义,它将输出 "(nullptr)";否则,它将检查虚函数表是否可以调度 node。如果可以,它将调用虚函数表对应的函数;否则,它将输出对象的类型键和地址。

  2. PrintIndent() 函数:这个函数用于在打印对象内容时添加缩进。它通过循环输出空格来实现缩进效果。

  3. 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 模块。

  1. void Dump(const runtime::ObjectRef& n):这个函数接受 runtime::ObjectRef 类型的参数 n,并将其输出到标准错误流(std::cerr)。

  2. void Dump(const runtime::Object* n):这个函数接受指向 runtime::Object 的指针 n,然后调用 Dump 函数将其转换为 runtime::ObjectRef 类型,并输出到标准错误流。

  3. TVM_REGISTER_GLOBAL("node.AsRepr"):这是 TVM 模块的全局注册,用于将名为 "node.AsRepr" 的函数注册到 TVM 运行时环境中。这个函数接受 runtime::ObjectRef 类型的参数,将其转换为字符串,并返回。 总结:这段代码定义了用于打印对象引用的函数,以及 TVM 模块的全局注册。