19 #ifndef TVM_SCRIPT_PRINTER_IR_DOCSIFIER_H_
20 #define TVM_SCRIPT_PRINTER_IR_DOCSIFIER_H_
22 #include <tvm/ffi/reflection/access_path.h>
23 #include <tvm/ffi/reflection/registry.h>
30 #include <unordered_map>
31 #include <unordered_set>
44 class IRDocsifierNode;
60 namespace refl = tvm::ffi::reflection;
74 template <
typename TCallback>
76 callbacks.emplace_back(std::forward<TCallback>(cb));
98 class Frame :
public ffi::ObjectRef {
131 ffi::Optional<ffi::String>
name;
148 std::unordered_map<ffi::ObjectRef, VariableInfo, ffi::ObjectPtrHash, ffi::ObjectPtrEqual>
151 std::unordered_map<ffi::String, ffi::Array<ffi::Any>>
metadata;
157 std::unordered_map<const ffi::Object*, std::vector<const ffi::Object*>>
common_prefix;
162 namespace refl = tvm::ffi::reflection;
163 refl::ObjectDef<IRDocsifierNode>()
209 ffi::Optional<ExprDoc>
GetVarDoc(
const ffi::ObjectRef& obj)
const;
231 void SetCommonPrefix(
const ffi::ObjectRef& root, ffi::TypedFunction<
bool(ffi::ObjectRef)> is_var);
239 template <
class TDoc = Doc>
261 d->
frames.push_back(ffi::GetRef<Frame>(
this));
266 for (
const std::function<
void()>& callback :
callbacks) {
275 template <
class TDoc>
276 inline static void AddDocDecoration(
const Doc& d,
const ffi::ObjectRef& obj,
const AccessPath& path,
278 if (cfg->obj_to_annotate.count(obj)) {
280 if (stmt->comment.has_value()) {
281 stmt->comment = stmt->comment.value() +
"\n" + cfg->obj_to_annotate.at(obj);
283 stmt->comment = cfg->obj_to_annotate.at(obj);
286 LOG(WARNING) <<
"Expect StmtDoc to be annotated for object " << obj <<
", but got "
287 << Downcast<TDoc>(d)->_type_key;
290 for (
const ffi::ObjectRef& o : cfg->obj_to_underline) {
291 if (o.same_as(obj)) {
292 cfg->path_to_underline.push_back(path);
295 for (
const auto& pair : cfg->path_to_annotate) {
297 ffi::String attn = pair.second;
298 if (p->IsPrefixOf(path) && path->IsPrefixOf(p)) {
299 if (
const auto* stmt = d.as<StmtDocNode>()) {
300 if (stmt->comment.has_value()) {
301 stmt->comment = stmt->comment.value() +
"\n" + attn;
303 stmt->comment = attn;
306 LOG(WARNING) <<
"Expect StmtDoc to be annotated at object path " << p <<
", but got "
307 << Downcast<TDoc>(d)->_type_key;
313 template <
class TDoc>
315 switch (value.type_index()) {
316 case ffi::TypeIndex::kTVMFFINone:
318 case ffi::TypeIndex::kTVMFFIBool:
320 case ffi::TypeIndex::kTVMFFIInt:
321 return Downcast<TDoc>(
LiteralDoc::Int(value.as<int64_t>().value(), path));
322 case ffi::TypeIndex::kTVMFFIFloat:
324 case ffi::TypeIndex::kTVMFFISmallStr:
325 case ffi::TypeIndex::kTVMFFIStr: {
326 std::string string_value = value.cast<std::string>();
327 bool has_multiple_lines = string_value.find_first_of(
'\n') != std::string::npos;
328 if (has_multiple_lines) {
331 return Downcast<TDoc>(d);
335 case ffi::TypeIndex::kTVMFFIDataType:
337 case ffi::TypeIndex::kTVMFFIDevice:
340 if (
auto opt_obj = value.as<ffi::ObjectRef>()) {
341 ffi::ObjectRef obj = opt_obj.value();
343 ffi::GetRef<IRDocsifier>(
this));
344 d->source_paths.push_back(path);
345 AddDocDecoration<TDoc>(d, obj, path,
cfg);
346 return Downcast<TDoc>(d);
348 TVM_FFI_THROW(TypeError) <<
"Cannot handle Any type: `" << value.GetTypeKey() <<
"`";
349 TVM_FFI_UNREACHABLE();
357 this->
AddExitCallback([doc =
d.get()]() { doc->dispatch_tokens.pop_back(); });
Managed reference to GlobalInfoNode.
Definition: global_info.h:54
Runtime primitive data type.
Definition: data_type.h:45
Reference type of DocNode.
Definition: doc.h:86
Reference type of ExprDocNode.
Definition: doc.h:144
Definition: ir_docsifier.h:50
virtual void EnterWithScope()
Method that's called when Frame enters the scope.
Definition: ir_docsifier.h:259
static void RegisterReflection()
Definition: ir_docsifier.h:59
IRDocsifierNode * d
Definition: ir_docsifier.h:55
virtual void ExitWithScope()
Method that's called when Frame exits the scope.
Definition: ir_docsifier.h:265
void AddExitCallback(TCallback &&cb)
Add a callback function to be called when this frame exits.
Definition: ir_docsifier.h:75
TVM_FFI_DECLARE_OBJECT_INFO("script.printer.Frame", FrameNode, ffi::Object)
std::vector< std::function< void()> > callbacks
Definition: ir_docsifier.h:57
ffi::Array< StmtDoc > stmts
Definition: ir_docsifier.h:53
void AddDispatchToken(const IRDocsifier &d, const ffi::String &token)
Add a dispatch token to the docsifier, and a callback that pops the token when this frame exits.
Definition: ir_docsifier.h:355
static constexpr const bool _type_mutable
Definition: ir_docsifier.h:64
virtual ~FrameNode()=default
Reference type of FrameNode.
Definition: ir_docsifier.h:98
void EnterWithScope()
Method that's called when Frame enters the scope.
Definition: ir_docsifier.h:106
void ExitWithScope()
Method that's called when Frame exits the scope.
Definition: ir_docsifier.h:109
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Frame, ffi::ObjectRef, FrameNode)
Dynamic dispatch functor based on AccessPath.
Definition: ir_docsifier_functor.h:42
IRDocsifier is the top-level interface in the IR->Doc process.
Definition: ir_docsifier.h:122
std::unordered_set< std::string > ir_usage
The IR usages for headers printing.
Definition: ir_docsifier.h:159
std::function< ExprDoc()> DocCreator
A function that creates the doc for a variable.
Definition: ir_docsifier.h:125
IdDoc Define(const ffi::ObjectRef &obj, const Frame &frame, const ffi::String &name_hint)
Define variable by name.
bool IsVarDefined(const ffi::ObjectRef &obj) const
Check if a variable exists in the table.
ExprDoc AddMetadata(const ffi::Any &obj)
Add a TVM object to the metadata section.
std::unordered_map< ffi::ObjectRef, VariableInfo, ffi::ObjectPtrHash, ffi::ObjectPtrEqual > obj2info
Mapping from a var to its info.
Definition: ir_docsifier.h:149
std::unordered_map< ffi::String, ffi::Array< ffi::Any > > metadata
Metadata printing.
Definition: ir_docsifier.h:151
TDoc AsDoc(const Any &obj, const AccessPath &path) const
Transform the input object into TDoc.
Definition: ir_docsifier.h:314
ffi::Optional< ExprDoc > GetVarDoc(const ffi::ObjectRef &obj) const
Get the doc for variable.
ffi::Array< Frame > frames
The stack of frames.
Definition: ir_docsifier.h:139
ffi::Array< ffi::String > dispatch_tokens
The stack of dispatch tokens.
Definition: ir_docsifier.h:146
std::unordered_set< ffi::String > defined_names
The variable names used already.
Definition: ir_docsifier.h:155
PrinterConfig cfg
The configuration of the printer.
Definition: ir_docsifier.h:134
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.IRDocsifier", IRDocsifierNode, ffi::Object)
static void RegisterReflection()
Definition: ir_docsifier.h:161
std::unordered_map< ffi::String, ffi::Array< GlobalInfo > > global_infos
GlobalInfo printing.
Definition: ir_docsifier.h:153
std::unordered_map< const ffi::Object *, std::vector< const ffi::Object * > > common_prefix
Common prefixes of variable usages.
Definition: ir_docsifier.h:157
void SetCommonPrefix(const ffi::ObjectRef &root, ffi::TypedFunction< bool(ffi::ObjectRef)> is_var)
Set the common prefix information of variable usage.
static constexpr const bool _type_mutable
Definition: ir_docsifier.h:168
void Define(const ffi::ObjectRef &obj, const Frame &frame, DocCreator doc_factory)
Define variable by doc factory.
void AddGlobalInfo(const ffi::String &name, const GlobalInfo &ginfo)
Add a GlobalInfo to the global_infos map.
void RemoveVar(const ffi::ObjectRef &obj)
Remove the variable defined.
Reference type of IRDocsifierNode.
Definition: ir_docsifier.h:246
static FType & vtable()
The registration table for IRDocsifier.
IRDocsifier(const PrinterConfig &cfg)
Create a IRDocsifier.
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(IRDocsifier, ffi::ObjectRef, IRDocsifierNode)
Reference type of IdDocNode.
Definition: doc.h:350
static LiteralDoc Boolean(bool v, const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent boolean.
Definition: doc.h:286
static LiteralDoc DataType(const runtime::DataType &v, const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent string.
Definition: doc.h:310
static LiteralDoc Device(const DLDevice &v, const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent device.
Definition: doc.h:319
static LiteralDoc Int(int64_t v, const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent integer.
Definition: doc.h:278
static LiteralDoc Float(double v, const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent float.
Definition: doc.h:294
static LiteralDoc None(const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent None/null/empty value.
Definition: doc.h:270
static LiteralDoc Str(const ffi::String &v, const ffi::Optional< AccessPath > &p)
Create a LiteralDoc to represent string.
Definition: doc.h:302
The base class of statement doc.
Definition: doc.h:167
IRModule that holds the functions and type definitions.
ffi::reflection::AccessPath AccessPath
Definition: doc.h:34
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition: analyzer.h:37
Information about a variable, including its optional name and its doc creator.
Definition: ir_docsifier.h:127
DocCreator creator
The creator.
Definition: ir_docsifier.h:129
ffi::Optional< ffi::String > name
The name of the variable.
Definition: ir_docsifier.h:131