/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef TVM_SCRIPT_PRINTER_DOC_H_ #define TVM_SCRIPT_PRINTER_DOC_H_ #include #include #include #include #include #include #include #include namespace tvm { namespace script { namespace printer { using AccessPath = ffi::reflection::AccessPath; // Forward declaration class Doc; /*! * \brief Convert Doc into Python script. * \param doc Doc to be converted * \param cfg The configuration of the printer */ ffi::String DocToPythonScript(Doc doc, const PrinterConfig& cfg); /*! * \brief The base class of all Doc. * * Doc is an intermediate representation between IR from TVM * and the TVMScript code. * During printing, IR graph is first translated into Doc tree, * then the Doc tree is translated to the target language in * text format. * * \sa Doc */ class DocNode : public ffi::Object { public: /*! * \brief The list of object paths of the source IR node. * * This is used to trace back to the IR node position where * this Doc is generated, in order to position the diagnostic * message. */ mutable ffi::Array source_paths; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_rw("source_paths", &DocNode::source_paths); } static constexpr bool _type_mutable = true; TVM_FFI_DECLARE_OBJECT_INFO("script.printer.Doc", DocNode, ffi::Object); public: virtual ~DocNode() = default; }; /*! * \brief Reference type of DocNode. * * \sa DocNode */ class Doc : public ffi::ObjectRef { protected: Doc() = default; explicit Doc(ffi::ObjectPtr data) : ffi::ObjectRef(data) {} public: TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Doc, ffi::ObjectRef, DocNode); }; class ExprDoc; /*! * \brief The base class of expression doc. * * \sa ExprDoc */ class ExprDocNode : public DocNode { public: /*! * \brief Create a doc representing attribute access on the current ExprDoc * \param attr The attribute to access. */ ExprDoc Attr(ffi::String attr) const; /*! * \brief Create a doc representing index access on the current ExprDoc * \param indices The indices to access. */ ExprDoc operator[](ffi::Array indices) const; /*! * \brief Create a doc representing calling the current ExprDoc * \param args The positional arguments of the function call. */ ExprDoc Call(ffi::Array args) const; /*! * \brief Create a doc representing attribute access on the current ExprDoc * \param args The positional arguments of the function call. * \param kwargs_keys Keys of keywords arguments of the function call. * \param kwargs_values Values of keywords arguments of the function call. */ ExprDoc Call(ffi::Array args, // ffi::Array kwargs_keys, // ffi::Array kwargs_values) const; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef(); } TVM_FFI_DECLARE_OBJECT_INFO("script.printer.ExprDoc", ExprDocNode, DocNode); }; /*! * \brief Reference type of ExprDocNode. * * \sa ExprDocNode */ class ExprDoc : public Doc { protected: ExprDoc() = default; public: /*! * \brief Create a doc representing index access on the current ExprDoc * \param indices The indices to access. */ ExprDoc operator[](ffi::Array indices) const; explicit ExprDoc(ffi::ObjectPtr data) : Doc(data) { TVM_FFI_ICHECK(data != nullptr); } TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ExprDoc, Doc, ExprDocNode); }; /*! * \brief The base class of statement doc. * * \sa StmtDoc */ class StmtDocNode : public DocNode { public: /*! * \brief The comment of this doc. * * The actual position of the comment depends on the type of Doc * and also the DocPrinter implementation. It could be on the same * line as the statement, or the line above, or inside the statement * if it spans over multiple lines. * */ mutable ffi::Optional comment{std::nullopt}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_rw("comment", &StmtDocNode::comment); } TVM_FFI_DECLARE_OBJECT_INFO("script.printer.StmtDoc", StmtDocNode, DocNode); }; /*! * \brief Reference type of StmtDocNode. * * \sa StmtDocNode */ class StmtDoc : public Doc { protected: StmtDoc() = default; public: TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(StmtDoc, Doc, StmtDocNode); }; /*! * \brief The container doc that holds a list of StmtDoc. * \note `StmtBlockDoc` is never used in the IR, but a temporary container that allows holding a * list of StmtDoc. * \sa StmtBlockDoc */ class StmtBlockDocNode : public DocNode { public: /*! \brief The list of statements. */ ffi::Array stmts; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("stmts", &StmtBlockDocNode::stmts); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.StmtBlockDoc", StmtBlockDocNode, DocNode); }; /*! * \brief Reference type of StmtBlockDocNode. * \sa StmtBlockDocNode */ class StmtBlockDoc : public Doc { public: /*! * \brief Constructor of StmtBlockDoc. * \param stmts The list of statements. */ explicit StmtBlockDoc(ffi::Array stmts); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(StmtBlockDoc, Doc, StmtBlockDocNode); }; /*! * \brief Doc that represents literal value. * * \sa LiteralDoc */ class LiteralDocNode : public ExprDocNode { public: /*! * \brief the internal representation of the literal value. * * Possible actual types: * - IntImm (integer or boolean) * - FloatImm * - String * - null */ ffi::Any value; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("value", &LiteralDocNode::value); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.LiteralDoc", LiteralDocNode, ExprDocNode); }; /*! * \brief Reference type of LiteralDocNode. * * \sa LiteralDocNode */ class LiteralDoc : public ExprDoc { protected: explicit LiteralDoc(ffi::Any value, const ffi::Optional& object_path); public: /*! * \brief Create a LiteralDoc to represent None/null/empty value. * \param p The object path */ static LiteralDoc None(const ffi::Optional& p) { return LiteralDoc(ffi::Any(nullptr), p); } /*! * \brief Create a LiteralDoc to represent integer. * \param v The integer value. * \param p The object path */ static LiteralDoc Int(int64_t v, const ffi::Optional& p) { return LiteralDoc(IntImm::Int64(v), p); } /*! * \brief Create a LiteralDoc to represent boolean. * \param v The boolean value. * \param p The object path */ static LiteralDoc Boolean(bool v, const ffi::Optional& p) { return LiteralDoc(IntImm::Bool(v), p); } /*! * \brief Create a LiteralDoc to represent float. * \param v The float value. * \param p The object path */ static LiteralDoc Float(double v, const ffi::Optional& p) { return LiteralDoc(FloatImm(PrimType::Float(64), v), p); } /*! * \brief Create a LiteralDoc to represent string. * \param v The string value. * \param p The object path */ static LiteralDoc Str(const ffi::String& v, const ffi::Optional& p) { return LiteralDoc(v, p); } /*! * \brief Create a LiteralDoc to represent string. * \param v The string value. * \param p The object path */ static LiteralDoc DataType(DLDataType v, const ffi::Optional& p) { std::string dtype = v == DLDataType{kDLOpaqueHandle, 0, 0} ? "void" : ffi::DLDataTypeToString(v); return LiteralDoc::Str(dtype, p); } /*! * \brief Create a LiteralDoc to represent device. * \param v The device. * \param p The object path */ static LiteralDoc Device(const DLDevice& v, const ffi::Optional& p) { std::ostringstream os; runtime::operator<<(os, v); return LiteralDoc::Str(os.str(), p); } TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(LiteralDoc, ExprDoc, LiteralDocNode); }; /*! * \brief Doc that renders an expression as a Python string literal. * * \sa ExprStringDoc */ class ExprStringDocNode : public ExprDocNode { public: /*! \brief The expression to render as a string. */ ExprDoc value{ffi::UnsafeInit()}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("value", &ExprStringDocNode::value); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ExprStringDoc", ExprStringDocNode, ExprDocNode); }; /*! * \brief Reference type of ExprStringDocNode. * * \sa ExprStringDocNode */ class ExprStringDoc : public ExprDoc { public: /*! * \brief Constructor of ExprStringDoc. * \param value The expression to render as a string. * \param object_path The object path. */ explicit ExprStringDoc(ExprDoc value, const ffi::Optional& object_path); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ExprStringDoc, ExprDoc, ExprStringDocNode); }; /*! * \brief Doc that represents identifier. * * \sa IdDoc */ class IdDocNode : public ExprDocNode { public: /*! \brief The name of the identifier */ ffi::String name; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("name", &IdDocNode::name); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.IdDoc", IdDocNode, ExprDocNode); }; /*! * \brief Reference type of IdDocNode. * * \sa IdDocNode */ class IdDoc : public ExprDoc { public: /*! * \brief Constructor of IdDoc. * \param name The name of identifier. */ explicit IdDoc(ffi::String name); explicit IdDoc(std::nullptr_t) : ExprDoc(nullptr) {} TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(IdDoc, ExprDoc, IdDocNode); }; /*! * \brief Doc that represents attribute access on another expression. * * \sa AttrAccessDoc */ class AttrAccessDocNode : public ExprDocNode { public: /*! \brief The target expression to be accessed */ ExprDoc value{ffi::UnsafeInit()}; /*! \brief The attribute to be accessed */ ffi::String name; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("value", &AttrAccessDocNode::value) .def_ro("name", &AttrAccessDocNode::name); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.AttrAccessDoc", AttrAccessDocNode, ExprDocNode); }; /*! * \brief Reference type of AttrAccessDocNode. * * \sa AttrAccessDocNode */ class AttrAccessDoc : public ExprDoc { public: /*! * \brief Constructor of AttrAccessDoc * \param value The target expression of attribute access. * \param name The name of attribute to access. */ explicit AttrAccessDoc(ExprDoc value, ffi::String name); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(AttrAccessDoc, ExprDoc, AttrAccessDocNode); }; /*! * \brief Doc that represents index access on another expression. * * \sa IndexDoc */ class IndexDocNode : public ExprDocNode { public: /*! \brief The container value to be accessed */ ExprDoc value{ffi::UnsafeInit()}; /*! * \brief The indices to access * * Possible actual types: * - ExprDoc (single point access like a[1, 2]) * - SliceDoc (slice access like a[1:5, 2]) */ ffi::Array indices; // Each element is union of: Slice / ExprDoc static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("value", &IndexDocNode::value) .def_ro("indices", &IndexDocNode::indices); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.IndexDoc", IndexDocNode, ExprDocNode); }; /*! * \brief Reference type of IndexDocNode. * * \sa IndexDocNode */ class IndexDoc : public ExprDoc { public: /*! * \brief Constructor of IndexDoc * \param value The target expression of index access. * \param indices The indices to access. */ explicit IndexDoc(ExprDoc value, ffi::Array indices); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(IndexDoc, ExprDoc, IndexDocNode); }; /*! * \brief Doc that represents function call. * * \sa CallDoc */ class CallDocNode : public ExprDocNode { public: /*! \brief The callee of this function call */ ExprDoc callee{ffi::UnsafeInit()}; /*! \brief The positional arguments */ ffi::Array args; /*! \brief The keys of keyword arguments */ ffi::Array kwargs_keys; /*! * \brief The values of keyword arguments. * * The i-th element is the value of the i-th key in `kwargs_keys`. * It must have the same length as `kwargs_keys`. */ ffi::Array kwargs_values; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("callee", &CallDocNode::callee) .def_ro("args", &CallDocNode::args) .def_ro("kwargs_keys", &CallDocNode::kwargs_keys) .def_ro("kwargs_values", &CallDocNode::kwargs_values); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.CallDoc", CallDocNode, ExprDocNode); }; /*! * \brief Reference type of CallDocNode. * * \sa CallDocNode */ class CallDoc : public ExprDoc { public: /*! * \brief Constructor of CallDoc * \param callee The callee of this function call. * \param args The positional arguments. * \param kwargs_keys Keys of keyword arguments. * \param kwargs_values Values of keyword arguments, must have the same length as `kwargs_keys. */ CallDoc(ExprDoc callee, ffi::Array args, ffi::Array kwargs_keys, ffi::Array kwargs_values); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(CallDoc, ExprDoc, CallDocNode); }; /*! * \brief Doc that represents operation. * * It can be unary, binary and other special operators (for example, * the if-then-else expression). * * \sa OperationDoc */ class OperationDocNode : public ExprDocNode { public: enum class Kind : int32_t { // Unary operators kUnaryStart = 0, kUSub = 1, // -x kInvert = 2, // ~x kNot = 3, // not x kUnaryEnd = 4, // Binary operators kBinaryStart = 5, kAdd = 6, // + kSub = 7, // - kMult = 8, // * kDiv = 9, // / kFloorDiv = 10, // // in Python kMod = 11, // % in Python kPow = 12, // ** in Python kLShift = 13, // << kRShift = 14, // >> kBitAnd = 15, // & kBitOr = 16, // | kBitXor = 17, // ^ kLt = 18, // < kLtE = 19, // <= kEq = 20, // == kNotEq = 21, // != kGt = 22, // > kGtE = 23, // >= kAnd = 24, // and kOr = 25, // or kMatMul = 26, // @ kBinaryEnd = 27, // Special kSpecialStart = 28, kIfThenElse = 29, // if else kSpecialEnd = 30 }; /*! \brief The kind of operation (operator) */ Kind kind; /*! \brief Operands of this expression */ ffi::Array operands; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("kind", &OperationDocNode::kind) .def_ro("operands", &OperationDocNode::operands); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.OperationDoc", OperationDocNode, ExprDocNode); }; /*! * \brief Reference type of OperationDocNode. * * \sa OperationDocNode */ class OperationDoc : public ExprDoc { public: /*! * \brief Constructor of OperationDoc * \param kind The kind of operation. * \param operands Operands of this expression. */ explicit OperationDoc(OperationDocNode::Kind kind, ffi::Array operands); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(OperationDoc, ExprDoc, OperationDocNode); }; /*! * \brief Doc that represents anonymous function. * * LambdaDoc can only have positional arguments without type annotation, * and a single expression as body. * * \sa LambdaDoc */ class LambdaDocNode : public ExprDocNode { public: /*! \brief The arguments of this anonymous function */ ffi::Array args; /*! \brief The body of this anonymous function */ ExprDoc body{ffi::UnsafeInit()}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("args", &LambdaDocNode::args) .def_ro("body", &LambdaDocNode::body); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.LambdaDoc", LambdaDocNode, ExprDocNode); }; /*! * \brief Reference type of LambdaDocNode. * * \sa LambdaDocNode */ class LambdaDoc : public ExprDoc { public: /*! * \brief Constructor of LambdaDoc * \param args Arguments of this function. * \param body Body expression of this function. */ explicit LambdaDoc(ffi::Array args, ExprDoc body); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(LambdaDoc, ExprDoc, LambdaDocNode); }; /*! * \brief Doc that represents tuple literal. * * \sa TupleDoc */ class TupleDocNode : public ExprDocNode { public: /*! \brief Elements of tuple */ ffi::Array elements; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("elements", &TupleDocNode::elements); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.TupleDoc", TupleDocNode, ExprDocNode); }; /*! * \brief Reference type of TupleDocNode. * * \sa TupleDocNode */ class TupleDoc : public ExprDoc { public: /*! * \brief Create an empty TupleDoc */ TupleDoc() : ExprDoc(ffi::make_object()) {} /*! * \brief Constructor of TupleDoc * \param elements Elements of tuple. */ explicit TupleDoc(ffi::Array elements); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TupleDoc, ExprDoc, TupleDocNode); }; /*! * \brief Doc that represents list literal. * * \sa AttrAccessDoc */ class ListDocNode : public ExprDocNode { public: /*! \brief Elements of list */ ffi::Array elements; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("elements", &ListDocNode::elements); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ListDoc", ListDocNode, ExprDocNode); }; /*! * \brief Reference type of ListDocNode. * * \sa ListDocNode */ class ListDoc : public ExprDoc { public: /*! * \brief Create an empty ListDoc */ ListDoc() : ExprDoc(ffi::make_object()) {} /*! * \brief Constructor of ListDoc * \param elements Elements of list. */ explicit ListDoc(ffi::Array elements); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ListDoc, ExprDoc, ListDocNode); }; /*! * \brief Doc that represents dictionary literal. * * \sa AttrAccessDoc */ class DictDocNode : public ExprDocNode { public: /*! \brief keys of dictionary */ ffi::Array keys; /*! * \brief Values of dictionary * * The i-th element is the value of the i-th element of `keys`. * It must have the same length as `keys`. */ ffi::Array values; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("keys", &DictDocNode::keys) .def_ro("values", &DictDocNode::values); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.DictDoc", DictDocNode, ExprDocNode); }; /*! * \brief Reference type of DictDocNode. * * \sa DictDocNode */ class DictDoc : public ExprDoc { public: /*! * \brief Create an empty dictionary */ DictDoc() : ExprDoc(ffi::make_object()) {} /*! * \brief Constructor of DictDoc * \param keys Keys of dictionary. * \param values Values of dictionary, must have same length as `keys`. */ explicit DictDoc(ffi::Array keys, ffi::Array values); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(DictDoc, ExprDoc, DictDocNode); }; /*! * \brief Doc that represents slice in Index expression. * * This doc can only appear in IndexDoc::indices. * * \sa AttrAccessDoc */ class SliceDocNode : public DocNode { public: /*! \brief The start of slice */ ffi::Optional start; /*! \brief The exclusive end of slice */ ffi::Optional stop; /*! \brief The step of slice */ ffi::Optional step; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("start", &SliceDocNode::start) .def_ro("stop", &SliceDocNode::stop) .def_ro("step", &SliceDocNode::step); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.SliceDoc", SliceDocNode, DocNode); }; /*! * \brief Reference type of SliceDocNode. * * \sa SliceDocNode */ class SliceDoc : public Doc { public: /*! * \brief Constructor of SliceDoc * \param start The start of slice. * \param stop The exclusive end of slice. * \param step The step of slice. */ explicit SliceDoc(ffi::Optional start, ffi::Optional stop, ffi::Optional step); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(SliceDoc, Doc, SliceDocNode); }; /*! * \brief Doc that represents assign statement. * * \sa AssignDoc */ class AssignDocNode : public StmtDocNode { public: /*! \brief The left hand side of the assignment */ ExprDoc lhs{ffi::UnsafeInit()}; /*! * \brief The right hand side of the assignment. * * If null, this doc represents declaration, e.g. `A: T.Buffer((1,2))` * */ ffi::Optional rhs; /*! \brief The type annotation of this assignment. */ ffi::Optional annotation; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("lhs", &AssignDocNode::lhs) .def_ro("rhs", &AssignDocNode::rhs) .def_ro("annotation", &AssignDocNode::annotation); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.AssignDoc", AssignDocNode, StmtDocNode); }; /*! * \brief Reference type of AssignDocNode. * * \sa AssignDoc */ class AssignDoc : public StmtDoc { public: /*! * \brief Constructor of AssignDoc. * \param lhs The left hand side of the assignment. * \param rhs The right hand side of the assignment. * \param annotation The type annotation of this assignment. */ explicit AssignDoc(ExprDoc lhs, ffi::Optional rhs, ffi::Optional annotation); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(AssignDoc, StmtDoc, AssignDocNode); }; /*! * \brief Doc that represent if-then-else statement. * * \sa IfDoc */ class IfDocNode : public StmtDocNode { public: /*! \brief The predicate of the if-then-else statement. */ ExprDoc predicate{ffi::UnsafeInit()}; /*! \brief The then branch of the if-then-else statement. */ ffi::Array then_branch; /*! \brief The else branch of the if-then-else statement. */ ffi::Array else_branch; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("predicate", &IfDocNode::predicate) .def_ro("then_branch", &IfDocNode::then_branch) .def_ro("else_branch", &IfDocNode::else_branch); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.IfDoc", IfDocNode, StmtDocNode); }; /*! * \brief Reference type of IfDocNode. * * \sa IfDocNode */ class IfDoc : public StmtDoc { public: /*! * \brief Constructor of IfDoc. * \param predicate The predicate of the if-then-else statement. * \param then_branch The then branch of the if-then-else statement. * \param else_branch The else branch of the if-then-else statement. */ explicit IfDoc(ExprDoc predicate, ffi::Array then_branch, ffi::Array else_branch); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(IfDoc, StmtDoc, IfDocNode); }; /*! * \brief Doc that represents while statement. * * \sa WhileDoc */ class WhileDocNode : public StmtDocNode { public: /*! \brief The predicate of the while statement. */ ExprDoc predicate{ffi::UnsafeInit()}; /*! \brief The body of the while statement. */ ffi::Array body; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("predicate", &WhileDocNode::predicate) .def_ro("body", &WhileDocNode::body); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.WhileDoc", WhileDocNode, StmtDocNode); }; /*! * \brief Reference type of WhileDocNode. * * \sa WhileDocNode */ class WhileDoc : public StmtDoc { public: /*! * \brief Constructor of WhileDoc. * \param predicate The predicate of the while statement. * \param body The body of the while statement. */ explicit WhileDoc(ExprDoc predicate, ffi::Array body); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(WhileDoc, StmtDoc, WhileDocNode); }; /*! * \brief Doc that represents break statement. * * \sa BreakDoc */ class BreakDocNode : public StmtDocNode { public: static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef(); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.BreakDoc", BreakDocNode, StmtDocNode); }; /*! * \brief Reference type of BreakDocNode. * * \sa BreakDocNode */ class BreakDoc : public StmtDoc { public: /*! * \brief Constructor of BreakDoc. */ explicit BreakDoc(); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(BreakDoc, StmtDoc, BreakDocNode); }; /*! * \brief Doc that represents continue statement. * * \sa ContinueDoc */ class ContinueDocNode : public StmtDocNode { public: static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef(); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ContinueDoc", ContinueDocNode, StmtDocNode); }; /*! * \brief Reference type of ContinueDocNode. * * \sa ContinueDocNode */ class ContinueDoc : public StmtDoc { public: /*! * \brief Constructor of ContinueDoc. */ explicit ContinueDoc(); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ContinueDoc, StmtDoc, ContinueDocNode); }; /*! * \brief Doc that represents for statement. * * Example: * for 'lhs' in 'rhs': * 'body...' * * \sa ForDoc */ class ForDocNode : public StmtDocNode { public: /*! \brief The left hand side of the assignment of iterating variable. */ ExprDoc lhs{ffi::UnsafeInit()}; /*! \brief The right hand side of the assignment of iterating variable. */ ExprDoc rhs{ffi::UnsafeInit()}; /*! \brief The body of the for statement. */ ffi::Array body; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("lhs", &ForDocNode::lhs) .def_ro("rhs", &ForDocNode::rhs) .def_ro("body", &ForDocNode::body); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ForDoc", ForDocNode, StmtDocNode); }; /*! * \brief Reference type of ForDocNode. * * \sa ForDocNode */ class ForDoc : public StmtDoc { public: /*! * \brief Constructor of ForDoc. * \param lhs The left hand side of the assignment of iterating variable. * \param rhs The right hand side of the assignment of iterating variable. * \param body The body of the for statement. */ explicit ForDoc(ExprDoc lhs, ExprDoc rhs, ffi::Array body); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ForDoc, StmtDoc, ForDocNode); }; /*! * \brief Doc that represents special scopes. * * Specifically, this means the with statement in Python: * * with 'rhs' as 'lhs': * 'body...' * * \sa ScopeDoc */ class ScopeDocNode : public StmtDocNode { public: /*! \brief The name of the scoped variable. */ ffi::Optional lhs{std::nullopt}; /*! \brief The value of the scoped variable. */ ExprDoc rhs{ffi::UnsafeInit()}; /*! \brief The body of the scope doc. */ ffi::Array body; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("lhs", &ScopeDocNode::lhs) .def_ro("rhs", &ScopeDocNode::rhs) .def_ro("body", &ScopeDocNode::body); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ScopeDoc", ScopeDocNode, StmtDocNode); }; /*! * \brief Reference type of ScopeDocNode. * * \sa ScopeDocNode */ class ScopeDoc : public StmtDoc { public: /*! * \brief Constructor of ScopeDoc. * \param lhs The name of the scoped variable. * \param rhs The value of the scoped variable. * \param body The body of the scope doc. */ explicit ScopeDoc(ffi::Optional lhs, ExprDoc rhs, ffi::Array body); /*! * \brief Constructor of ScopeDoc. * \param rhs The value of the scoped variable. * \param body The body of the scope doc. */ explicit ScopeDoc(ExprDoc rhs, ffi::Array body); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ScopeDoc, StmtDoc, ScopeDocNode); }; /*! * \brief Doc that represents an expression as statement. * * \sa ExprStmtDoc */ class ExprStmtDocNode : public StmtDocNode { public: /*! \brief The expression represented by this doc. */ ExprDoc expr{ffi::UnsafeInit()}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("expr", &ExprStmtDocNode::expr); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ExprStmtDoc", ExprStmtDocNode, StmtDocNode); }; /*! * \brief Reference type of ExprStmtDocNode. * * \sa ExprStmtDocNode */ class ExprStmtDoc : public StmtDoc { public: /*! * \brief Constructor of ExprStmtDoc. * \param expr The expression represented by this doc. */ explicit ExprStmtDoc(ExprDoc expr); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ExprStmtDoc, StmtDoc, ExprStmtDocNode); }; /*! * \brief Doc that represents assert statement. * * \sa AssertDoc */ class AssertDocNode : public StmtDocNode { public: /*! \brief The expression to test. */ ExprDoc test{ffi::UnsafeInit()}; /*! \brief The optional error message when assertion failed. */ ffi::Optional msg{std::nullopt}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("test", &AssertDocNode::test) .def_ro("msg", &AssertDocNode::msg); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.AssertDoc", AssertDocNode, StmtDocNode); }; /*! * \brief Reference type of AssertDocNode. * * \sa AssertDocNode */ class AssertDoc : public StmtDoc { public: /*! * \brief Constructor of AssertDoc. * \param test The expression to test. * \param msg The optional error message when assertion failed. */ explicit AssertDoc(ExprDoc test, ffi::Optional msg = std::nullopt); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(AssertDoc, StmtDoc, AssertDocNode); }; /*! * \brief Doc that represents return statement. * * \sa ReturnDoc */ class ReturnDocNode : public StmtDocNode { public: /*! \brief The value to return. */ ExprDoc value{ffi::UnsafeInit()}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("value", &ReturnDocNode::value); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ReturnDoc", ReturnDocNode, StmtDocNode); }; /*! * \brief Reference type of ReturnDocNode. * * \sa ReturnDocNode */ class ReturnDoc : public StmtDoc { public: /*! * \brief Constructor of ReturnDoc. * \param value The value to return. */ explicit ReturnDoc(ExprDoc value); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ReturnDoc, StmtDoc, ReturnDocNode); }; /*! * \brief Doc that represents function definition. * * \sa FunctionDoc */ class FunctionDocNode : public StmtDocNode { public: /*! \brief The name of function. */ IdDoc name{ffi::UnsafeInit{}}; /*! * \brief The arguments of function. * * The `lhs` means argument name, * `annotation` means argument type, * and `rhs` means default value. */ ffi::Array args; /*! \brief Decorators of function. */ ffi::Array decorators; /*! \brief The return type of function. */ ffi::Optional return_type{std::nullopt}; /*! \brief The body of function. */ ffi::Array body; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("name", &FunctionDocNode::name) .def_ro("args", &FunctionDocNode::args) .def_ro("decorators", &FunctionDocNode::decorators) .def_ro("return_type", &FunctionDocNode::return_type) .def_ro("body", &FunctionDocNode::body); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.FunctionDoc", FunctionDocNode, StmtDocNode); }; /*! * \brief Reference type of FunctionDocNode. * * \sa FunctionDocNode */ class FunctionDoc : public StmtDoc { public: /*! * \brief Constructor of FunctionDoc. * \param name The name of function.. * \param args The arguments of function. * \param decorators The decorator of function. * \param return_type The return type of function. * \param body The body of function. */ explicit FunctionDoc(IdDoc name, ffi::Array args, ffi::Array decorators, ffi::Optional return_type, ffi::Array body); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(FunctionDoc, StmtDoc, FunctionDocNode); }; /*! * \brief Doc that represents class definition. * * \sa ClassDoc */ class ClassDocNode : public StmtDocNode { public: /*! \brief The name of class. */ IdDoc name{ffi::UnsafeInit{}}; /*! \brief Decorators of class. */ ffi::Array decorators; /*! \brief The body of class. */ ffi::Array body; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("name", &ClassDocNode::name) .def_ro("decorators", &ClassDocNode::decorators) .def_ro("body", &ClassDocNode::body); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.ClassDoc", ClassDocNode, StmtDocNode); }; /*! * \brief Reference type of ClassDocNode. * * \sa ClassDocNode */ class ClassDoc : public StmtDoc { public: /*! * \brief Constructor of ClassDoc. * \param name The name of class. * \param decorators The decorator of class. * \param body The body of class. */ explicit ClassDoc(IdDoc name, ffi::Array decorators, ffi::Array body); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ClassDoc, StmtDoc, ClassDocNode); }; /*! * \brief Doc that represents comment. * * \sa CommentDoc */ class CommentDocNode : public StmtDocNode { public: static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef(); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.CommentDoc", CommentDocNode, StmtDocNode); }; /*! * \brief Reference type of CommentDocNode. * * \sa CommentDocNode */ class CommentDoc : public StmtDoc { public: explicit CommentDoc(ffi::String comment); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(CommentDoc, StmtDoc, CommentDocNode); }; /*! * \brief Doc that represents docstring. * * \sa DocStringDoc */ class DocStringDocNode : public StmtDocNode { public: static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef(); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.DocStringDoc", DocStringDocNode, StmtDocNode); }; /*! * \brief Reference type of DocStringDocNode. * * \sa DocStringDocNode */ class DocStringDoc : public StmtDoc { public: explicit DocStringDoc(ffi::String docs); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(DocStringDoc, StmtDoc, DocStringDocNode); }; /*! * \brief Doc that represents call to an TIRX operator * * \sa OpCallDoc */ class OpCallDocNode : public StmtDocNode { public: /*! \brief The callee of this function call */ ExprDoc callee{ffi::UnsafeInit()}; /*! \brief The positional arguments */ ffi::Array args; /*! \brief The workspace of this op call */ ffi::Optional workspace{std::nullopt}; /*! \brief The config of this op call */ ffi::Optional config{std::nullopt}; /*! \brief The optional dispatch variant of this op call */ ffi::Optional dispatch{std::nullopt}; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("callee", &OpCallDocNode::callee) .def_ro("args", &OpCallDocNode::args) .def_ro("workspace", &OpCallDocNode::workspace) .def_ro("config", &OpCallDocNode::config) .def_ro("dispatch", &OpCallDocNode::dispatch); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.printer.OpCallDoc", OpCallDocNode, StmtDocNode); }; /*! * \brief Reference type of OpCallDocNode. * * \sa OpCallDocNode */ class OpCallDoc : public StmtDoc { public: /*! * \brief Constructor of OpCallDoc * \param callee The callee of this function call. * \param args The positional arguments. * \param workspace The workspace of this op call. * \param config The config of this op call. * \param dispatch The optional dispatch variant name of this op call. */ explicit OpCallDoc(ExprDoc callee, ffi::Array args, ffi::Optional workspace, ffi::Optional config, ffi::Optional dispatch = std::nullopt); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(OpCallDoc, StmtDoc, OpCallDocNode); }; } // namespace printer } // namespace script } // namespace tvm #endif // TVM_SCRIPT_PRINTER_DOC_H_