tvm
operation.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 
24 #ifndef TVM_TE_OPERATION_H_
25 #define TVM_TE_OPERATION_H_
26 
27 #include <tvm/arith/analyzer.h>
28 #include <tvm/ffi/reflection/registry.h>
29 #include <tvm/ir/cow.h>
30 #include <tvm/te/tensor.h>
31 #include <tvm/tirx/buffer.h>
32 #include <tvm/tirx/expr.h>
33 #include <tvm/tirx/op.h>
34 
35 #include <string>
36 #include <unordered_map>
37 #include <utility>
38 #include <vector>
39 
40 namespace tvm {
42 namespace te {
43 
48 struct TensorDom {
49  // constructor
50  explicit TensorDom(int ndim) : data(ndim) {}
52  std::vector<std::vector<IntSet>> data;
53 };
54 
58 class TVM_DLL OperationNode : public ffi::Object {
59  public:
61  std::string name;
63  std::string tag;
65  ffi::Map<ffi::String, ffi::Any> attrs;
66  // virtual destructor.
67  virtual ~OperationNode() {}
69  virtual int num_outputs() const = 0;
75  virtual PrimType output_dtype(size_t i) const = 0;
81  virtual ffi::Array<PrimExpr> output_shape(size_t i) const = 0;
86  virtual ffi::Array<Tensor> InputTensors() const = 0;
87 
88  static void RegisterReflection() {
89  namespace refl = tvm::ffi::reflection;
90  refl::ObjectDef<OperationNode>()
91  .def_ro("name", &OperationNode::name)
92  .def_ro("tag", &OperationNode::tag)
93  .def_ro("attrs", &OperationNode::attrs);
94  }
95  TVM_FFI_DECLARE_OBJECT_INFO("te.Operation", OperationNode, ffi::Object);
96 };
97 
102  public:
104  ffi::Array<PrimExpr> shape;
107  // override behavior.
108  int num_outputs() const final;
109  PrimType output_dtype(size_t i) const final;
110  ffi::Array<PrimExpr> output_shape(size_t i) const final;
111  ffi::Array<Tensor> InputTensors() const final;
112 
113  static void RegisterReflection() {
114  namespace refl = tvm::ffi::reflection;
115  refl::ObjectDef<PlaceholderOpNode>()
116  .def_ro("shape", &PlaceholderOpNode::shape)
117  .def_ro("dtype", &PlaceholderOpNode::dtype);
118  }
120 };
121 
126 class PlaceholderOp : public Operation {
127  public:
128  TVM_DLL PlaceholderOp(std::string name, ffi::Array<PrimExpr> shape, PrimType dtype);
129 
131 };
132 
137 class TVM_DLL BaseComputeOpNode : public OperationNode {
138  public:
140  ffi::Array<IterVar> axis;
142  ffi::Array<IterVar> reduce_axis;
143  // override functions
144  ffi::Array<PrimExpr> output_shape(size_t idx) const final;
145 
146  static void RegisterReflection() {
147  namespace refl = tvm::ffi::reflection;
148  refl::ObjectDef<BaseComputeOpNode>()
149  .def_ro("axis", &BaseComputeOpNode::axis)
150  .def_ro("reduce_axis", &BaseComputeOpNode::reduce_axis);
151  }
153 };
154 
158 class TVM_DLL ComputeOpNode : public BaseComputeOpNode {
159  public:
161  ffi::Array<PrimExpr> body;
164  // override functions
165  int num_outputs() const final;
166  PrimType output_dtype(size_t i) const final;
167  ffi::Array<Tensor> InputTensors() const final;
168 
169  static void RegisterReflection() {
170  namespace refl = tvm::ffi::reflection;
171  refl::ObjectDef<ComputeOpNode>().def_ro("body", &ComputeOpNode::body);
172  }
174 };
175 
180 class ComputeOp : public Operation {
181  public:
182  TVM_DLL ComputeOp(std::string name, std::string tag, ffi::Map<ffi::String, ffi::Any> attrs,
183  ffi::Array<IterVar> axis, ffi::Array<PrimExpr> body);
184 
187 };
188 
192 class ScanOpNode : public OperationNode {
193  public:
197  ffi::Array<Tensor> init;
199  ffi::Array<Tensor> update;
201  ffi::Array<Tensor> state_placeholder;
206  ffi::Array<Tensor> inputs;
216  ffi::Array<IterVar> spatial_axis_;
219  // override behavior.
220  int num_outputs() const final;
221  PrimType output_dtype(size_t i) const final;
222  ffi::Array<PrimExpr> output_shape(size_t i) const final;
223  ffi::Array<Tensor> InputTensors() const final;
224 
225  static void RegisterReflection() {
226  namespace refl = tvm::ffi::reflection;
227  refl::ObjectDef<ScanOpNode>()
228  .def_ro("scan_axis", &ScanOpNode::scan_axis)
229  .def_ro("init", &ScanOpNode::init)
230  .def_ro("update", &ScanOpNode::update)
231  .def_ro("state_placeholder", &ScanOpNode::state_placeholder)
232  .def_ro("inputs", &ScanOpNode::inputs)
233  .def_ro("spatial_axis_", &ScanOpNode::spatial_axis_);
234  }
236 };
237 
242 class ScanOp : public Operation {
243  public:
244  TVM_DLL ScanOp(std::string name, std::string tag,
245  ffi::Optional<ffi::Map<ffi::String, ffi::Any>> attrs, IterVar axis,
246  ffi::Array<Tensor> init, ffi::Array<Tensor> update,
247  ffi::Array<Tensor> state_placeholder, ffi::Array<Tensor> input);
248 
250 };
251 
255 class ExternOpNode : public OperationNode {
256  public:
258  ffi::Array<Tensor> inputs;
260  ffi::Array<Buffer> input_placeholders;
262  ffi::Array<Buffer> output_placeholders;
265 
268  // override functions
269  int num_outputs() const final;
270  PrimType output_dtype(size_t i) const final;
271  ffi::Array<PrimExpr> output_shape(size_t i) const final;
272  ffi::Array<Tensor> InputTensors() const final;
273 
274  static void RegisterReflection() {
275  namespace refl = tvm::ffi::reflection;
276  refl::ObjectDef<ExternOpNode>()
277  .def_ro("inputs", &ExternOpNode::inputs)
278  .def_ro("input_placeholders", &ExternOpNode::input_placeholders)
279  .def_ro("output_placeholders", &ExternOpNode::output_placeholders)
280  .def_ro("body", &ExternOpNode::body);
281  }
283 };
284 
289 class ExternOp : public Operation {
290  public:
291  TVM_DLL ExternOp(std::string name, std::string tag, ffi::Map<ffi::String, ffi::Any> attrs,
292  ffi::Array<Tensor> inputs, ffi::Array<Buffer> input_placeholders,
293  ffi::Array<Buffer> output_placeholders, Stmt body);
294 
296 };
297 
303 TVM_DLL PrimVar var(std::string name_hint, PrimType t = PrimType::Int(32));
304 
311 TVM_DLL IterVar thread_axis(Range dom, std::string tag);
312 
319 TVM_DLL IterVar reduce_axis(Range dom, std::string name = "rv");
320 
322 using FCompute = std::function<PrimExpr(const ffi::Array<PrimVar>& i)>;
323 
325 using FBatchCompute = std::function<ffi::Array<PrimExpr>(const ffi::Array<PrimVar>& i)>;
326 
333 TVM_DLL Tensor placeholder(ffi::Array<PrimExpr> shape, PrimType dtype = PrimType::Float(32),
334  std::string name = "placeholder");
335 
345 TVM_DLL Tensor compute(ffi::Array<PrimExpr> shape, FCompute fcompute, std::string name = "tensor",
346  std::string tag = "", ffi::Map<ffi::String, ffi::Any> attrs = {});
347 
357 TVM_DLL ffi::Array<Tensor> compute(ffi::Array<PrimExpr> shape, FBatchCompute fcompute,
358  std::string name = "tensor", std::string tag = "",
359  ffi::Map<ffi::String, ffi::Any> attrs = {});
360 
373 TVM_DLL ffi::Array<Tensor> scan(ffi::Array<Tensor> init, ffi::Array<Tensor> update,
374  ffi::Array<Tensor> state_placeholder,
375  ffi::Array<Tensor> inputs = ffi::Array<Tensor>(),
376  std::string name = "scan", std::string tag = "",
377  ffi::Map<ffi::String, ffi::Any> attrs = {});
378 
379 // same as compute, specialized for different fcompute function
380 inline Tensor compute(ffi::Array<PrimExpr> shape, std::function<PrimExpr(PrimVar)> f,
381  std::string name = "tensor", std::string tag = "",
382  ffi::Map<ffi::String, ffi::Any> attrs = {}) {
383  FCompute fc = [f](const ffi::Array<PrimVar>& i) { return f(i[0]); };
384  return compute(shape, fc, name, tag, attrs);
385 }
386 inline Tensor compute(ffi::Array<PrimExpr> shape, std::function<PrimExpr(PrimVar, PrimVar)> f,
387  std::string name = "tensor", std::string tag = "",
388  ffi::Map<ffi::String, ffi::Any> attrs = {}) {
389  FCompute fc = [f](const ffi::Array<PrimVar>& i) { return f(i[0], i[1]); };
390  return compute(shape, fc, name, tag, attrs);
391 }
392 inline Tensor compute(ffi::Array<PrimExpr> shape,
393  std::function<PrimExpr(PrimVar, PrimVar, PrimVar)> f,
394  std::string name = "tensor", std::string tag = "",
395  ffi::Map<ffi::String, ffi::Any> attrs = {}) {
396  FCompute fc = [f](const ffi::Array<PrimVar>& i) { return f(i[0], i[1], i[2]); };
397  return compute(shape, fc, name, tag, attrs);
398 }
399 inline Tensor compute(ffi::Array<PrimExpr> shape,
400  std::function<PrimExpr(PrimVar, PrimVar, PrimVar, PrimVar)> f,
401  std::string name = "tensor", std::string tag = "",
402  ffi::Map<ffi::String, ffi::Any> attrs = {}) {
403  FCompute fc = [f](const ffi::Array<PrimVar>& i) { return f(i[0], i[1], i[2], i[3]); };
404  return compute(shape, fc, name, tag, attrs);
405 }
406 
407 // inline function.
408 inline const OperationNode* Operation::operator->() const {
409  return static_cast<const OperationNode*>(get());
410 }
411 } // namespace te
412 } // namespace tvm
413 #endif // TVM_TE_OPERATION_H_
Algebra expression simplifications.
Symbolic n-dimensional array, to represent a memory buffer.
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition: base_expr.h:354
Definition: base_expr.h:113
static PrimType Float(int bits, int lanes=1)
Construct a floating-point type with fixed lanes.
static PrimType Void()
Construct the void sentinel type, encoded as handle(0, 0).
static PrimType Int(int bits, int lanes=1)
Construct a signed integer type with fixed lanes.
Range container
Definition: expr.h:484
A Compute op that compute a tensor on certain domain. This is the base class for ComputeOp (operating...
Definition: operation.h:137
ffi::Array< IterVar > reduce_axis
IterVar on each reduction axis, if the body is a Reduce.
Definition: operation.h:142
static void RegisterReflection()
Definition: operation.h:146
ffi::Array< PrimExpr > output_shape(size_t idx) const final
Get shape of i-th output tensor.
TVM_FFI_DECLARE_OBJECT_INFO("te.BaseComputeOp", BaseComputeOpNode, OperationNode)
ffi::Array< IterVar > axis
IterVar on each axis.
Definition: operation.h:140
A Compute op that compute a tensor on certain domain.
Definition: operation.h:158
ComputeOpNode()
constructor
Definition: operation.h:163
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("te.ComputeOp", ComputeOpNode, BaseComputeOpNode)
int num_outputs() const final
ffi::Array< PrimExpr > body
the compute expression
Definition: operation.h:161
Managed reference to ComputeOpNode.
Definition: operation.h:180
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(ComputeOp, Operation, ComputeOpNode)
ComputeOp(std::string name, std::string tag, ffi::Map< ffi::String, ffi::Any > attrs, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > body)
TVM_DEFINE_OBJECT_REF_COW_METHOD(ComputeOpNode)
External computation that cannot be splitted.
Definition: operation.h:255
int num_outputs() const final
ffi::Array< Tensor > inputs
The input tensors.
Definition: operation.h:258
PrimType output_dtype(size_t i) const final
Get the primitive element type of the i-th output tensor.
static void RegisterReflection()
Definition: operation.h:274
ffi::Array< PrimExpr > output_shape(size_t i) const final
Get shape of i-th output tensor.
ffi::Array< Buffer > input_placeholders
Symbolic placeholder representation of inputs.
Definition: operation.h:260
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("te.ExternOp", ExternOpNode, OperationNode)
ffi::Array< Tensor > InputTensors() const final
List all the input Tensors.
Stmt body
the statement that generates the computation.
Definition: operation.h:264
ExternOpNode()
constructor
Definition: operation.h:267
ffi::Array< Buffer > output_placeholders
Symbolic placeholder representation of outputs.
Definition: operation.h:262
Managed reference to ExternOpNode.
Definition: operation.h:289
ExternOp(std::string name, std::string tag, ffi::Map< ffi::String, ffi::Any > attrs, ffi::Array< Tensor > inputs, ffi::Array< Buffer > input_placeholders, ffi::Array< Buffer > output_placeholders, Stmt body)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(ExternOp, Operation, ExternOpNode)
Base class of all operation nodes.
Definition: operation.h:58
TVM_FFI_DECLARE_OBJECT_INFO("te.Operation", OperationNode, ffi::Object)
virtual ~OperationNode()
Definition: operation.h:67
virtual ffi::Array< PrimExpr > output_shape(size_t i) const =0
Get shape of i-th output tensor.
static void RegisterReflection()
Definition: operation.h:88
virtual ffi::Array< Tensor > InputTensors() const =0
List all the input Tensors.
virtual PrimType output_dtype(size_t i) const =0
Get the primitive element type of the i-th output tensor.
virtual int num_outputs() const =0
ffi::Map< ffi::String, ffi::Any > attrs
additional attributes of the operation
Definition: operation.h:65
std::string name
optional name of the operation
Definition: operation.h:61
std::string tag
optional tag of the operation
Definition: operation.h:63
Operation that produces tensors.
Definition: tensor.h:48
const OperationNode * operator->() const
access the internal node container
Definition: operation.h:408
A placeholder op represents an input placeholder.
Definition: operation.h:101
TVM_FFI_DECLARE_OBJECT_INFO("te.PlaceholderOp", PlaceholderOpNode, OperationNode)
static void RegisterReflection()
Definition: operation.h:113
ffi::Array< PrimExpr > shape
The shape of the input.
Definition: operation.h:104
int num_outputs() const final
ffi::Array< Tensor > InputTensors() const final
List all the input Tensors.
ffi::Array< PrimExpr > output_shape(size_t i) const final
Get shape of i-th output tensor.
PrimType dtype
The dtype of the input.
Definition: operation.h:106
PrimType output_dtype(size_t i) const final
Get the primitive element type of the i-th output tensor.
Managed reference to PlaceholderOpNode.
Definition: operation.h:126
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PlaceholderOp, Operation, PlaceholderOpNode)
PlaceholderOp(std::string name, ffi::Array< PrimExpr > shape, PrimType dtype)
Symbolic scan.
Definition: operation.h:192
ffi::Array< Tensor > state_placeholder
The placeholder to refer as states in update.
Definition: operation.h:201
ScanOpNode()
constructor
Definition: operation.h:218
int num_outputs() const final
ffi::Array< Tensor > init
the initialization tensors
Definition: operation.h:197
ffi::Array< Tensor > update
the update function represented by tensor
Definition: operation.h:199
ffi::Array< PrimExpr > output_shape(size_t i) const final
Get shape of i-th output tensor.
ffi::Array< Tensor > inputs
the inputs to the scan, these are optionally provided But they can be helpful to provide hints to spe...
Definition: operation.h:206
ffi::Array< Tensor > InputTensors() const final
List all the input Tensors.
static void RegisterReflection()
Definition: operation.h:225
IterVar scan_axis
IterVar to scan over.
Definition: operation.h:195
PrimType output_dtype(size_t i) const final
Get the primitive element type of the i-th output tensor.
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("te.ScanOp", ScanOpNode, OperationNode)
ffi::Array< IterVar > spatial_axis_
Spatial axis to indicate spatial dimension of each output. They corresponds to flattened spatial axis...
Definition: operation.h:216
Managed reference to ScanOpNode.
Definition: operation.h:242
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(ScanOp, Operation, ScanOpNode)
ScanOp(std::string name, std::string tag, ffi::Optional< ffi::Map< ffi::String, ffi::Any >> attrs, IterVar axis, ffi::Array< Tensor > init, ffi::Array< Tensor > update, ffi::Array< Tensor > state_placeholder, ffi::Array< Tensor > input)
Tensor structure representing a possible input, or intermediate computation result.
Definition: tensor.h:100
Iteration Variable, represents an iteration over an integer interval.
Definition: var.h:274
Checked scalar view over a VarNode.
Definition: var.h:127
Container of all statements.
Definition: stmt.h:64
Copy-on-write helper macro for IR ffi::ObjectRef types.
PrimVar var(std::string name_hint, PrimType t=PrimType::Int(32))
Construct a new Var expression.
Tensor placeholder(ffi::Array< PrimExpr > shape, PrimType dtype=PrimType::Float(32), std::string name="placeholder")
create a place holder tensor.
std::function< ffi::Array< PrimExpr >(const ffi::Array< PrimVar > &i)> FBatchCompute
The compute function to specify the inputs source of Tensors.
Definition: operation.h:325
ffi::Array< Tensor > scan(ffi::Array< Tensor > init, ffi::Array< Tensor > update, ffi::Array< Tensor > state_placeholder, ffi::Array< Tensor > inputs=ffi::Array< Tensor >(), std::string name="scan", std::string tag="", ffi::Map< ffi::String, ffi::Any > attrs={})
Construct new tensors by scan.
std::function< PrimExpr(const ffi::Array< PrimVar > &i)> FCompute
The compute function to specify the input source of a Tensor.
Definition: operation.h:322
IterVar thread_axis(Range dom, std::string tag)
Create a new IterVar that represents an axis in thread.
IterVar reduce_axis(Range dom, std::string name="rv")
Create a new IterVar for reduction operations.
Tensor compute(ffi::Array< PrimExpr > shape, FCompute fcompute, std::string name="tensor", std::string tag="", ffi::Map< ffi::String, ffi::Any > attrs={})
Construct a new tensor by computing over shape, using the computation rule: result_tensor[axis] = fco...
Tensor shape(const Tensor &src, PrimType dtype, const std::string name="T_shape", const std::string tag=kInjective)
Get the shape of input tensor.
Definition: transform.h:2010
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition: analyzer.h:40
Temporary data structure to store union of bounds of each axis of Tensor.
Definition: operation.h:48
TensorDom(int ndim)
Definition: operation.h:50
std::vector< std::vector< IntSet > > data
The domain data.
Definition: operation.h:52
Dataflow tensor object.
TIR expressions.
Common operators defined for Expr.