tvm
ir_docsifier.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 #ifndef TVM_SCRIPT_PRINTER_IR_DOCSIFIER_H_
20 #define TVM_SCRIPT_PRINTER_IR_DOCSIFIER_H_
21 
22 #include <tvm/ir/module.h>
23 #include <tvm/node/node.h>
24 #include <tvm/script/printer/doc.h>
26 
27 #include <string>
28 #include <unordered_map>
29 #include <unordered_set>
30 #include <utility>
31 #include <vector>
32 
33 namespace tvm {
34 namespace script {
35 namespace printer {
36 
38 
39 class IRDocsifier;
40 class IRDocsifierNode;
41 
46 class FrameNode : public Object {
47  public:
53  std::vector<std::function<void()>> callbacks;
54 
56  v->Visit("stmts", &stmts);
57  // `d` is not visited
58  // `callbacks` is not visited
59  }
60 
61  static constexpr const char* _type_key = "script.printer.Frame";
63 
64  public:
65  virtual ~FrameNode() = default;
66 
71  template <typename TCallback>
72  void AddExitCallback(TCallback&& cb) {
73  callbacks.emplace_back(std::forward<TCallback>(cb));
74  }
81  void AddDispatchToken(const IRDocsifier& d, const String& token);
85  virtual void EnterWithScope();
89  virtual void ExitWithScope();
90 };
91 
95 class Frame : public ObjectRef {
96  protected:
97  Frame() = default;
98 
99  public:
100  virtual ~Frame() = default;
101 
103  void EnterWithScope() { get()->EnterWithScope(); }
104 
106  void ExitWithScope() { get()->ExitWithScope(); }
107 
109 };
110 
112 
119 class IRDocsifierNode : public Object {
120  public:
122  using DocCreator = std::function<ExprDoc()>;
124  struct VariableInfo {
129  };
131  PrinterConfig cfg{nullptr};
145  std::unordered_map<ObjectRef, VariableInfo, ObjectPtrHash, ObjectPtrEqual> obj2info;
147  std::unordered_map<String, Array<ObjectRef>> metadata;
149  std::unordered_map<String, Array<GlobalInfo>> global_infos;
151  std::unordered_set<String> defined_names;
153  std::unordered_map<const Object*, std::vector<const Object*>> common_prefix;
155  std::unordered_set<std::string> ir_usage;
156 
158  v->Visit("frames", &frames);
159  v->Visit("dispatch_tokens", &dispatch_tokens);
160  // `obj2info` is not visited
161  // `metadata` is not visited
162  // `defined_names` is not visited
163  // `common_prefix` is not visited
164  // `ir_usage` is not visited
165  }
166 
167  static constexpr const char* _type_key = "script.printer.IRDocsifier";
169 
170  public:
182  IdDoc Define(const ObjectRef& obj, const Frame& frame, const String& name_hint);
183 
200  void Define(const ObjectRef& obj, const Frame& frame, DocCreator doc_factory);
201 
215  void AddGlobalInfo(const String& name, const GlobalInfo& ginfo);
222  bool IsVarDefined(const ObjectRef& obj) const;
224  void RemoveVar(const ObjectRef& obj);
238  template <class TDoc = Doc>
239  inline TDoc AsDoc(const ObjectRef& obj, const ObjectPath& path) const;
240 };
241 
245 class IRDocsifier : public ObjectRef {
246  public:
249  explicit IRDocsifier(const PrinterConfig& cfg);
251  TVM_DLL static FType& vtable();
252 
254 };
255 
257 
259  if (d != nullptr) {
260  d->frames.push_back(GetRef<Frame>(this));
261  }
262 }
263 
265  for (const std::function<void()>& callback : callbacks) {
266  callback();
267  }
268  callbacks.clear();
269  if (d != nullptr) {
270  d->frames.pop_back();
271  }
272 }
273 
274 template <class TDoc>
275 inline static void AddDocDecoration(const Doc& d, const ObjectRef& obj, const ObjectPath& path,
276  const PrinterConfig& cfg) {
277  if (cfg->obj_to_annotate.count(obj)) {
278  if (const auto* stmt = d.as<StmtDocNode>()) {
279  if (stmt->comment.defined()) {
280  stmt->comment = stmt->comment.value() + "\n" + cfg->obj_to_annotate.at(obj);
281  } else {
282  stmt->comment = cfg->obj_to_annotate.at(obj);
283  }
284  } else {
285  LOG(WARNING) << "Expect StmtDoc to be annotated for object " << obj << ", but got "
286  << Downcast<TDoc>(d)->_type_key;
287  }
288  }
289  for (const ObjectRef& o : cfg->obj_to_underline) {
290  if (o.same_as(obj)) {
291  cfg->path_to_underline.push_back(path);
292  }
293  }
294  for (const auto& pair : cfg->path_to_annotate) {
295  ObjectPath p = pair.first;
296  String attn = pair.second;
297  if (p->IsPrefixOf(path) && path->IsPrefixOf(p)) {
298  if (const auto* stmt = d.as<StmtDocNode>()) {
299  if (stmt->comment.defined()) {
300  stmt->comment = stmt->comment.value() + "\n" + attn;
301  } else {
302  stmt->comment = attn;
303  }
304  } else {
305  LOG(WARNING) << "Expect StmtDoc to be annotated at object path " << p << ", but got "
306  << Downcast<TDoc>(d)->_type_key;
307  }
308  }
309  }
310 }
311 
312 template <class TDoc>
313 inline TDoc IRDocsifierNode::AsDoc(const ObjectRef& obj, const ObjectPath& path) const {
314  if (obj.defined()) {
315  Doc d = IRDocsifier::vtable()(dispatch_tokens.back(), obj, path, GetRef<IRDocsifier>(this));
316  d->source_paths.push_back(path);
317  AddDocDecoration<TDoc>(d, obj, path, cfg);
318  return Downcast<TDoc>(d);
319  }
320  return Downcast<TDoc>(LiteralDoc::None(path));
321 }
322 
323 inline void FrameNode::AddDispatchToken(const IRDocsifier& d, const String& token) {
324  d->dispatch_tokens.push_back(token);
325  this->AddExitCallback([doc = d.get()]() { doc->dispatch_tokens.pop_back(); });
326 }
327 
328 } // namespace printer
329 } // namespace script
330 } // namespace tvm
331 
332 #endif // TVM_SCRIPT_PRINTER_IR_DOCSIFIER_H_
Visitor class to get the attributes of an AST/IR node. The content is going to be called for each fie...
Definition: reflection.h:52
Managed reference to GlobalInfoNode.
Definition: global_info.h:54
Definition: object_path.h:122
Definition: script_printer.h:149
Array, container representing a contiguous sequence of ObjectRefs.
Definition: array.h:289
Base class of all object reference.
Definition: object.h:519
bool defined() const
Definition: object.h:552
const Object * get() const
Definition: object.h:554
const ObjectType * as() const
Try to downcast the internal Object to a raw pointer of a corresponding type.
Definition: object.h:910
base class of all object containers.
Definition: object.h:171
static constexpr const char * _type_key
Definition: object.h:226
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
Reference to string objects.
Definition: string.h:98
Please refer to TypedPackedFunc<R(Args..)>.
Definition: packed_func.h:63
Reference type of DocNode.
Definition: doc.h:78
Reference type of ExprDocNode.
Definition: doc.h:135
Definition: ir_docsifier.h:46
static constexpr const char * _type_key
Definition: ir_docsifier.h:61
virtual void EnterWithScope()
Method that's called when Frame enters the scope.
Definition: ir_docsifier.h:258
IRDocsifierNode * d
Definition: ir_docsifier.h:51
void VisitAttrs(tvm::AttrVisitor *v)
Definition: ir_docsifier.h:55
TVM_DECLARE_BASE_OBJECT_INFO(FrameNode, Object)
virtual void ExitWithScope()
Method that's called when Frame exits the scope.
Definition: ir_docsifier.h:264
void AddExitCallback(TCallback &&cb)
Add a callback function to be called when this frame exits.
Definition: ir_docsifier.h:72
Array< StmtDoc > stmts
Definition: ir_docsifier.h:49
std::vector< std::function< void()> > callbacks
Definition: ir_docsifier.h:53
void AddDispatchToken(const IRDocsifier &d, const String &token)
Add a dispatch token to the docsifier, and a callback that pops the token when this frame exits.
Definition: ir_docsifier.h:323
Reference type of FrameNode.
Definition: ir_docsifier.h:95
void EnterWithScope()
Method that's called when Frame enters the scope.
Definition: ir_docsifier.h:103
virtual ~Frame()=default
void ExitWithScope()
Method that's called when Frame exits the scope.
Definition: ir_docsifier.h:106
TVM_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(Frame, ObjectRef, FrameNode)
Dynamic dispatch functor based on ObjectPath.
Definition: ir_docsifier_functor.h:43
IRDocsifier is the top-level interface in the IR->Doc process.
Definition: ir_docsifier.h:119
void Define(const ObjectRef &obj, const Frame &frame, DocCreator doc_factory)
Define variable by doc factory.
std::unordered_set< std::string > ir_usage
The IR usages for headers printing.
Definition: ir_docsifier.h:155
std::function< ExprDoc()> DocCreator
A function that creates the doc for a variable.
Definition: ir_docsifier.h:122
TVM_DECLARE_FINAL_OBJECT_INFO(IRDocsifierNode, Object)
std::unordered_map< String, Array< GlobalInfo > > global_infos
GlobalInfo printing.
Definition: ir_docsifier.h:149
Optional< ExprDoc > GetVarDoc(const ObjectRef &obj) const
Get the doc for variable.
Array< String > dispatch_tokens
The stack of dispatch tokens.
Definition: ir_docsifier.h:143
void AddGlobalInfo(const String &name, const GlobalInfo &ginfo)
Add a GlobalInfo to the global_infos map.
std::unordered_set< String > defined_names
The variable names used already.
Definition: ir_docsifier.h:151
std::unordered_map< ObjectRef, VariableInfo, ObjectPtrHash, ObjectPtrEqual > obj2info
Mapping from a var to its info.
Definition: ir_docsifier.h:145
ExprDoc AddMetadata(const ObjectRef &obj)
Add a TVM object to the metadata section.
IdDoc Define(const ObjectRef &obj, const Frame &frame, const String &name_hint)
Define variable by name.
std::unordered_map< String, Array< ObjectRef > > metadata
Metadata printing.
Definition: ir_docsifier.h:147
PrinterConfig cfg
The configuration of the printer.
Definition: ir_docsifier.h:131
bool IsVarDefined(const ObjectRef &obj) const
Check if a variable exists in the table.
Array< Frame > frames
The stack of frames.
Definition: ir_docsifier.h:136
static constexpr const char * _type_key
Definition: ir_docsifier.h:167
std::unordered_map< const Object *, std::vector< const Object * > > common_prefix
Common prefixes of variable usages.
Definition: ir_docsifier.h:153
void RemoveVar(const ObjectRef &obj)
Remove the variable defined.
void SetCommonPrefix(const ObjectRef &root, runtime::TypedPackedFunc< bool(ObjectRef)> is_var)
Set the common prefix information of variable usage.
void VisitAttrs(tvm::AttrVisitor *v)
Definition: ir_docsifier.h:157
TDoc AsDoc(const ObjectRef &obj, const ObjectPath &path) const
Transform the input object into TDoc.
Definition: ir_docsifier.h:313
Reference type of IRDocsifierNode.
Definition: ir_docsifier.h:245
static FType & vtable()
The registration table for IRDocsifier.
IRDocsifier(const PrinterConfig &cfg)
Create a IRDocsifier.
TVM_DEFINE_MUTABLE_NOTNULLABLE_OBJECT_REF_METHODS(IRDocsifier, ObjectRef, IRDocsifierNode)
Reference type of IdDocNode.
Definition: doc.h:333
static LiteralDoc None(const Optional< ObjectPath > &p)
Create a LiteralDoc to represent None/null/empty value.
Definition: doc.h:263
The base class of statement doc.
Definition: doc.h:154
IRModule that holds the functions and type definitions.
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
Definitions and helper macros for IR/AST nodes.
Information about a variable, including its optional name and its doc creator.
Definition: ir_docsifier.h:124
DocCreator creator
The creator.
Definition: ir_docsifier.h:126
Optional< String > name
The name of the variable.
Definition: ir_docsifier.h:128