tvm
Loading...
Searching...
No Matches
expr.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_RELAX_EXPR_H_
20#define TVM_RELAX_EXPR_H_
21
22#include <tvm/ffi/container/array.h>
23#include <tvm/ffi/container/map.h>
24#include <tvm/ffi/reflection/registry.h>
25#include <tvm/ir/cow.h>
26#include <tvm/ir/expr.h>
27#include <tvm/ir/function.h>
28#include <tvm/ir/prim/expr.h>
29#include <tvm/ir/source_map.h>
30#include <tvm/relax/type.h>
31#include <tvm/runtime/tensor.h>
32#include <tvm/tirx/op.h>
33
34#include <functional>
35
36namespace tvm {
37namespace relax {
38
39// Compatibility aliases. Tuple expressions are defined in the common IR.
40using ::tvm::Tuple;
41using ::tvm::TupleGetItem;
42using ::tvm::TupleGetItemNode;
43using ::tvm::TupleNode;
44
47class ShapeExprNode : public ExprNode {
48 public:
50 ffi::Array<PrimExpr> values;
51
52 static void RegisterReflection() {
53 namespace refl = tvm::ffi::reflection;
54 refl::ObjectDef<ShapeExprNode>().def_ro("values", &ShapeExprNode::values);
55 }
57};
58
65
69class DataflowVarNode : public VarNode {
70 public:
71 static void RegisterReflection() {
72 namespace refl = tvm::ffi::reflection;
73 refl::ObjectDef<DataflowVarNode>();
74 }
75
78};
79
80class DataflowVar : public Var {
81 public:
82 TVM_DLL explicit DataflowVar(ffi::String name, ffi::Optional<Type> ty_annotation,
83 Span span = Span());
84
86};
87
93class ConstantNode : public ExprNode {
94 public:
97
100
102 bool is_scalar() const { return data->ndim == 0; }
103
104 static void RegisterReflection() {
105 namespace refl = tvm::ffi::reflection;
106 refl::ObjectDef<ConstantNode>().def_ro("data", &ConstantNode::data);
107 }
109};
110
126
130class StringImmNode : public ExprNode {
131 public:
133 ffi::String value;
134
135 static void RegisterReflection() {
136 namespace refl = tvm::ffi::reflection;
137 refl::ObjectDef<StringImmNode>().def_ro("value", &StringImmNode::value);
138 }
140};
141
158
162class DataTypeImmNode : public ExprNode {
163 public:
166
167 static void RegisterReflection() {
168 namespace refl = tvm::ffi::reflection;
169 refl::ObjectDef<DataTypeImmNode>().def_ro("value", &DataTypeImmNode::value);
170 }
172};
173
190
192class BindingNode : public ffi::Object {
193 public:
194 mutable Span span;
197
198 static void RegisterReflection() {
199 namespace refl = tvm::ffi::reflection;
200 refl::ObjectDef<BindingNode>()
201 .def_ro("span", &BindingNode::span, refl::AttachFieldFlag::SEqHashIgnore())
202 // TODO(tqchen): use SEqHashDefNonRecursive after the next pypi tvm-ffi release
203 .def_ro("var", &BindingNode::var, refl::AttachFieldFlag::SEqHashDefRecursive());
204 }
205
207
208 TVM_FFI_DECLARE_OBJECT_INFO("relax.expr.Binding", BindingNode, ffi::Object);
209};
210
211class Binding : public ffi::ObjectRef {
212 protected:
213 Binding() = default;
214
215 public:
216 explicit Binding(ffi::ObjectPtr<BindingNode> n) : ffi::ObjectRef(n) {}
217 explicit Binding(ffi::UnsafeInit tag) : ffi::ObjectRef(tag) {}
218 Binding(const Binding&) = default;
219 Binding(Binding&&) = default;
220 Binding& operator=(const Binding&) = default;
221 Binding& operator=(Binding&&) = default;
222 const BindingNode* operator->() const { return static_cast<const BindingNode*>(data_.get()); }
223 const BindingNode* get() const { return operator->(); }
225};
226
235 public:
240
241 static void RegisterReflection() {
242 namespace refl = tvm::ffi::reflection;
243 refl::ObjectDef<MatchCastNode>()
244 .def_ro("value", &MatchCastNode::value)
245 // TODO(tqchen): use SEqHashDefNonRecursive after the next pypi tvm-ffi release
246 .def_ro("ty", &MatchCastNode::ty, refl::AttachFieldFlag::SEqHashDefRecursive());
247 }
249};
250
262
264 public:
267
268 static void RegisterReflection() {
269 namespace refl = tvm::ffi::reflection;
270 refl::ObjectDef<VarBindingNode>().def_ro("value", &VarBindingNode::value);
271 // customize the SEqual and SHash methods for better error messages
272 refl::TypeAttrDef<VarBindingNode>()
273 .def("__s_equal__", &VarBindingNode::SEqual)
274 .def("__s_hash__", &VarBindingNode::SHash);
275 }
276
278 ffi::TypedFunction<bool(AnyView, AnyView, bool, AnyView)> equal) const;
279 int64_t SHash(int64_t init_hash, ffi::TypedFunction<int64_t(AnyView, int64_t, bool)> hash) const;
281};
282
289
290class BindingBlockNode : public ffi::Object {
291 public:
292 ffi::Array<Binding> bindings;
293 mutable Span span;
294
295 static void RegisterReflection() {
296 namespace refl = tvm::ffi::reflection;
297 refl::ObjectDef<BindingBlockNode>()
298 .def_ro("bindings", &BindingBlockNode::bindings)
299 .def_ro("span", &BindingBlockNode::span, refl::AttachFieldFlag::SEqHashIgnore(),
300 refl::DefaultValue(Span()));
301 }
302
304 TVM_FFI_DECLARE_OBJECT_INFO("relax.expr.BindingBlock", BindingBlockNode, ffi::Object);
305};
306
307class BindingBlock : public ffi::ObjectRef {
308 public:
309 TVM_DLL explicit BindingBlock(ffi::Array<Binding> bindings, Span span = Span());
311
313};
314
316 public:
317 static void RegisterReflection() {
318 namespace refl = tvm::ffi::reflection;
319 refl::ObjectDef<DataflowBlockNode>();
320 }
323};
324
331
336class SeqExprNode : public ExprNode {
337 public:
338 ffi::Array<BindingBlock> blocks;
340
341 static void RegisterReflection() {
342 namespace refl = tvm::ffi::reflection;
343 refl::ObjectDef<SeqExprNode>()
344 .def_ro("blocks", &SeqExprNode::blocks)
345 .def_ro("body", &SeqExprNode::body);
346 refl::TypeAttrDef<SeqExprNode>()
347 .def("__s_equal__", &SeqExprNode::SEqual)
348 .def("__s_hash__", &SeqExprNode::SHash);
349 }
350
352 ffi::TypedFunction<bool(AnyView, AnyView, bool, AnyView)> equal) const {
353 // Establish mappings for symbolic variables defined by bindings before
354 // comparing their uses in the SeqExpr result type and body.
355 return equal(blocks, other->blocks, false, "blocks") && equal(ty, other->ty, false, "ty") &&
356 equal(body, other->body, false, "body");
357 }
358
359 int64_t SHash(int64_t init_hash, ffi::TypedFunction<int64_t(AnyView, int64_t, bool)> hash) const {
361 hash_value = hash(blocks, hash_value, false);
362 hash_value = hash(ty, hash_value, false);
363 hash_value = hash(body, hash_value, false);
364 return hash_value;
365 }
367};
368
369class SeqExpr : public Expr {
370 public:
371 /* \brief Implicit conversion constructor
372 *
373 * Relax nodes that introduce a new scope (e.g. `relax::Function`)
374 * are required to be held as SeqExpr. This implicit conversion
375 * provides allows callsites to use these member variables when the
376 * C++ compile-time type is a `relax::Expr`. For example,
377 * a transform may use `func.CopyOnWrite()->body = expr;`.
378 *
379 * If the expression is already a `relax::SeqExpr`, the same
380 * underlying `relax::SeqExprNode` is used, and no copies are made.
381 */
382 TVM_DLL SeqExpr(Expr body); // NOLINT(*)
383
384 TVM_DLL explicit SeqExpr(ffi::Array<BindingBlock> blocks, Expr body, Span span = Span());
387};
388
400class IfNode : public ExprNode {
401 public:
408
409 static void RegisterReflection() {
410 namespace refl = tvm::ffi::reflection;
411 refl::ObjectDef<IfNode>()
412 .def_ro("cond", &IfNode::cond)
413 .def_ro("true_branch", &IfNode::true_branch)
414 .def_ro("false_branch", &IfNode::false_branch);
415 }
416
419};
420
421class If : public Expr {
422 public:
440 TVM_DLL If(Expr cond, Expr true_branch, Expr false_branch, Span span = Span());
441
444};
445
448 public:
450 ffi::Array<Var> params;
457
458 static void RegisterReflection() {
459 namespace refl = tvm::ffi::reflection;
460 refl::ObjectDef<FunctionNode>()
461 .def_ro("params", &FunctionNode::params, refl::AttachFieldFlag::SEqHashDefRecursive())
462 .def_ro("body", &FunctionNode::body)
463 .def_ro("ret_ty", &FunctionNode::ret_ty)
464 .def_ro("is_pure", &FunctionNode::is_pure);
465 }
466
469};
470
471class Function : public BaseFunc {
472 public:
494 TVM_DLL explicit Function(ffi::Array<Var> params, Expr body, ffi::Optional<Type> ret_ty,
495 bool is_pure = true, DictAttrs attrs = DictAttrs(), Span span = Span());
496
501 TVM_DLL static Function CreateEmpty(ffi::Array<Var> params, Type ret_ty, bool is_pure = true,
502 DictAttrs attrs = DictAttrs(), Span span = Span());
503
506};
507
508// TODO(@sunggg): Investigate the exact usage of kComposite, kPartitionedFromPattern, and
509// kPrimitive.
510namespace attr {
512constexpr const char* kPrimitive = "Primitive";
517constexpr const char* kCodegen = "Codegen";
519constexpr const char* kComposite = "Composite";
521constexpr const char* kPartitionedFromPattern = "PartitionedFromPattern";
523constexpr const char* kWorkspaceSize = "WorkspaceSize";
524
525// Note: in the future, we prefer snake_case instead of CamelCase for attributes.
526// Past ones will be kept for backwards compatibility.
529constexpr const char* kForcePure = "relax.force_pure";
530
536constexpr const char* kNumInput = "num_input";
537} // namespace attr
538
541 public:
543 ffi::String global_symbol;
544
545 static void RegisterReflection() {
546 namespace refl = tvm::ffi::reflection;
547 refl::ObjectDef<ExternFuncNode>().def_ro("global_symbol", &ExternFuncNode::global_symbol);
548 }
550};
551
552class ExternFunc : public BaseFunc {
553 public:
554 TVM_DLL ExternFunc(ffi::String global_symbol, Span span = Span());
555 TVM_DLL ExternFunc(ffi::String global_symbol, Type ty, Span span = Span());
556
559};
560
573
574} // namespace relax
575} // namespace tvm
576
577#endif // TVM_RELAX_EXPR_H_
Base node of all functions.
Definition function.h:156
Managed reference to BaseFuncNode.
Definition function.h:250
Managed reference to DictAttrsNode.
Definition attrs.h:102
Base type of all the expressions.
Definition base_expr.h:300
Type ty
The deduced or annotated type of the expression.
Definition base_expr.h:314
Managed reference to ExprNode.
Definition base_expr.h:335
Definition source_map.h:111
Managed reference to TypeNode.
Definition base_expr.h:77
static Type Missing()
Sentinel for a type that has not been populated yet.
A local variable in the IR.
Definition expr.h:355
Managed reference to VarNode.
Definition expr.h:372
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Definition expr.h:290
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition expr.h:303
ffi::Array< Binding > bindings
Definition expr.h:292
Span span
Definition expr.h:293
static void RegisterReflection()
Definition expr.h:295
TVM_FFI_DECLARE_OBJECT_INFO("relax.expr.BindingBlock", BindingBlockNode, ffi::Object)
Definition expr.h:307
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(BindingBlock, ffi::ObjectRef, BindingBlockNode)
BindingBlock(ffi::Array< Binding > bindings, Span span=Span())
BindingBlockNode * CopyOnWrite()
The base class of a variable binding in Relax.
Definition expr.h:192
Var var
The return variable to bound to.
Definition expr.h:196
static void RegisterReflection()
Definition expr.h:198
Span span
Definition expr.h:194
TVM_FFI_DECLARE_OBJECT_INFO("relax.expr.Binding", BindingNode, ffi::Object)
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition expr.h:206
Definition expr.h:211
Binding(const Binding &)=default
const BindingNode * operator->() const
Definition expr.h:222
Binding(Binding &&)=default
Binding & operator=(Binding &&)=default
const BindingNode * get() const
Definition expr.h:223
Binding(ffi::ObjectPtr< BindingNode > n)
Definition expr.h:216
Binding(ffi::UnsafeInit tag)
Definition expr.h:217
Binding & operator=(const Binding &)=default
Constant tensor.
Definition expr.h:93
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.Constant", ConstantNode, ExprNode)
static void RegisterReflection()
Definition expr.h:104
bool is_scalar() const
Definition expr.h:102
runtime::Tensor data
The data of the tensor.
Definition expr.h:96
TensorType tensor_type() const
Definition expr.h:111
TVM_DEFINE_OBJECT_REF_COW_METHOD(ConstantNode)
Constant(runtime::Tensor data, ffi::Optional< Type > ty_annotation=std::nullopt, Span span=Span())
The constructor.
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Constant, Expr, ConstantNode)
Represent a data type constant.
Definition expr.h:162
DLDataType value
The data value.
Definition expr.h:165
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.DataTypeImm", DataTypeImmNode, ExprNode)
static void RegisterReflection()
Definition expr.h:167
Managed reference to DataTypeImm.
Definition expr.h:178
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(DataTypeImm, Expr, DataTypeImmNode)
DataTypeImm(DLDataType value, Span span=Span())
The constructor.
TVM_DEFINE_OBJECT_REF_COW_METHOD(DataTypeImmNode)
Definition expr.h:315
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.DataflowBlock", DataflowBlockNode, BindingBlockNode)
static void RegisterReflection()
Definition expr.h:317
Definition expr.h:325
DataflowBlock(ffi::Array< Binding > bindings, Span span=Span())
TVM_DEFINE_OBJECT_REF_COW_METHOD(DataflowBlockNode)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(DataflowBlock, BindingBlock, DataflowBlockNode)
A sub-type of the variable node used to mark dataflow variables from normal visible "function local" ...
Definition expr.h:69
static void RegisterReflection()
Definition expr.h:71
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.DataflowVar", DataflowVarNode, VarNode)
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition expr.h:76
Definition expr.h:80
DataflowVar(ffi::String name, ffi::Optional< Type > ty_annotation, Span span=Span())
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(DataflowVar, Var, DataflowVarNode)
The extern function, which can represent packed function.
Definition expr.h:540
static void RegisterReflection()
Definition expr.h:545
ffi::String global_symbol
The name of global symbol.
Definition expr.h:543
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.ExternFunc", ExternFuncNode, BaseFuncNode)
Definition expr.h:552
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(ExternFunc, BaseFunc, ExternFuncNode)
ExternFunc(ffi::String global_symbol, Type ty, Span span=Span())
TVM_DEFINE_OBJECT_REF_COW_METHOD(ExternFuncNode)
ExternFunc(ffi::String global_symbol, Span span=Span())
A Relax function.
Definition expr.h:447
static void RegisterReflection()
Definition expr.h:458
SeqExpr body
The body of the function.
Definition expr.h:452
ffi::Array< Var > params
The parameters to the function.
Definition expr.h:450
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.Function", FunctionNode, BaseFuncNode)
Type ret_ty
The return type of the function.
Definition expr.h:454
bool is_pure
Whether the function is annotated as pure or not.
Definition expr.h:456
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition expr.h:467
Definition expr.h:471
static Function CreateEmpty(ffi::Array< Var > params, Type ret_ty, bool is_pure=true, DictAttrs attrs=DictAttrs(), Span span=Span())
Mimics the constructor but without body Expr.
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Function, BaseFunc, FunctionNode)
Function(ffi::Array< Var > params, Expr body, ffi::Optional< Type > ret_ty, bool is_pure=true, DictAttrs attrs=DictAttrs(), Span span=Span())
Construct a Relax Function.
TVM_DEFINE_OBJECT_REF_COW_METHOD(FunctionNode)
Condition expression.
Definition expr.h:400
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition expr.h:417
static void RegisterReflection()
Definition expr.h:409
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.If", IfNode, ExprNode)
SeqExpr true_branch
The expression evaluated when condition is true.
Definition expr.h:405
Expr cond
The condition.
Definition expr.h:403
SeqExpr false_branch
The expression evaluated when condition is false.
Definition expr.h:407
Definition expr.h:421
TVM_DEFINE_OBJECT_REF_COW_METHOD(IfNode)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(If, Expr, IfNode)
If(Expr cond, Expr true_branch, Expr false_branch, Span span=Span())
The constructor.
Runtime-match the value to the type.
Definition expr.h:234
Expr value
The input value to match cast.
Definition expr.h:237
Type ty
The type pattern to match to.
Definition expr.h:239
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.MatchCast", MatchCastNode, BindingNode)
static void RegisterReflection()
Definition expr.h:241
Managed reference to MatchCastNode.
Definition expr.h:255
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(MatchCast, Binding, MatchCastNode)
MatchCast(Var var, Expr value, Type ty, Span span=Span())
TVM_DEFINE_OBJECT_REF_COW_METHOD(MatchCastNode)
A sequence of blocks followed by an expression.
Definition expr.h:336
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.SeqExpr", SeqExprNode, ExprNode)
Expr body
Definition expr.h:339
bool SEqual(const SeqExprNode *other, ffi::TypedFunction< bool(AnyView, AnyView, bool, AnyView)> equal) const
Definition expr.h:351
int64_t SHash(int64_t init_hash, ffi::TypedFunction< int64_t(AnyView, int64_t, bool)> hash) const
Definition expr.h:359
static void RegisterReflection()
Definition expr.h:341
ffi::Array< BindingBlock > blocks
Definition expr.h:338
Definition expr.h:369
SeqExpr(ffi::Array< BindingBlock > blocks, Expr body, Span span=Span())
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(SeqExpr, Expr, SeqExprNode)
TVM_DEFINE_OBJECT_REF_COW_METHOD(SeqExprNode)
A shape expression which allows users to construct a shape containing PrimExpr.
Definition expr.h:47
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.ShapeExpr", ShapeExprNode, ExprNode)
ffi::Array< PrimExpr > values
Definition expr.h:50
static void RegisterReflection()
Definition expr.h:52
Definition expr.h:59
ShapeExpr(ffi::Array< PrimExpr > values, Span span=Span())
TVM_DEFINE_OBJECT_REF_COW_METHOD(ShapeExprNode)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(ShapeExpr, Expr, ShapeExprNode)
Represent a string literal constant.
Definition expr.h:130
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.StringImm", StringImmNode, ExprNode)
ffi::String value
The data value.
Definition expr.h:133
static void RegisterReflection()
Definition expr.h:135
Managed reference to StringImm.
Definition expr.h:146
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(StringImm, Expr, StringImmNode)
TVM_DEFINE_OBJECT_REF_COW_METHOD(StringImmNode)
StringImm(ffi::String value, Span span=Span())
The constructor.
Managed reference to TensorTypeNode.
Definition type.h:220
Definition expr.h:263
static void RegisterReflection()
Definition expr.h:268
Expr value
The binding value.
Definition expr.h:266
int64_t SHash(int64_t init_hash, ffi::TypedFunction< int64_t(AnyView, int64_t, bool)> hash) const
bool SEqual(const VarBindingNode *other, ffi::TypedFunction< bool(AnyView, AnyView, bool, AnyView)> equal) const
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.expr.VarBinding", VarBindingNode, BindingNode)
Definition expr.h:283
TVM_DEFINE_OBJECT_REF_COW_METHOD(VarBindingNode)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(VarBinding, Binding, VarBindingNode)
VarBinding(Var var, Expr value, Span span=Span())
Managed Tensor. The array is backed by reference counted blocks.
Definition tensor.h:49
Copy-on-write helper macro for IR ffi::ObjectRef types.
Base expr nodes in TVM.
Function nodes.
TIR expressions.
constexpr const char * kForcePure
Override checking purity for this function and treat as pure (is_pure must be set to true)
Definition expr.h:529
constexpr const char * kWorkspaceSize
The required workspace for an external function.
Definition expr.h:523
constexpr const char * kNumInput
The number of inputs of a function. If a function has the num_input attribute, the last func->params....
Definition expr.h:536
constexpr const char * kComposite
Treat the function as a composite operator.
Definition expr.h:519
constexpr const char * kCodegen
Indicate the codegen that should be used for building this function. When this is unset or set to "de...
Definition expr.h:517
constexpr const char * kPrimitive
Mark the function as a primitive function.
Definition expr.h:512
constexpr const char * kPartitionedFromPattern
Indicate the function was created by the Pattern Partitioning Pass.
Definition expr.h:521
Expr GetShapeOf(const Expr &expr)
Get the shape of Expr.
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
PrimExpr equal(PrimExpr a, PrimExpr b, Span span=Span())
equal
Relax types, including the richer dependent Relax type nodes.
A device-independent managed Tensor abstraction.
A map from source names to source code.
Common operators defined for Expr.