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/te/schedule.h>
29 #include <tvm/te/tensor.h>
30 #include <tvm/tir/buffer.h>
31 #include <tvm/tir/expr.h>
32 #include <tvm/tir/op.h>
33 
34 #include <string>
35 #include <unordered_map>
36 #include <vector>
37 
38 namespace tvm {
40 namespace te {
41 
46 struct TensorDom {
47  // constructor
48  explicit TensorDom(int ndim) : data(ndim) {}
50  std::vector<std::vector<IntSet> > data;
51 };
52 
56 class TVM_DLL OperationNode : public Object {
57  public:
59  std::string name;
61  std::string tag;
64  // virtual destructor.
65  virtual ~OperationNode() {}
67  virtual int num_outputs() const = 0;
72  virtual Array<IterVar> root_iter_vars() const = 0;
78  virtual DataType output_dtype(size_t i) const = 0;
84  virtual Array<PrimExpr> output_shape(size_t i) const = 0;
89  virtual Array<Tensor> InputTensors() const = 0;
97  virtual Operation ReplaceInputs(const Operation& self,
98  const std::unordered_map<Tensor, Tensor>& rmap) const = 0;
108  virtual void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
109  const std::unordered_map<const VarNode*, IntSet>& dom_map,
110  std::unordered_map<Tensor, TensorDom>* out_dom_map) const = 0;
119  virtual void GatherBound(const Operation& self,
120  const std::unordered_map<Tensor, TensorDom>& tensor_dom,
121  std::unordered_map<IterVar, Range>* out_dom_map) const = 0;
131  virtual Stmt BuildRealize(const Stage& stage,
132  const std::unordered_map<IterVar, Range>& realize_map, const Stmt& body,
133  String storage_scope = "") const = 0;
141  virtual Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
142  bool debug_keep_trivial_loop) const = 0;
143 
144  static constexpr const char* _type_key = "Operation";
145 
147 };
148 
153  public:
158  // override behavior.
159  int num_outputs() const final;
160  Array<IterVar> root_iter_vars() const final;
161  DataType output_dtype(size_t i) const final;
162  Array<PrimExpr> output_shape(size_t i) const final;
163  Array<Tensor> InputTensors() const final;
164  Operation ReplaceInputs(const Operation& self,
165  const std::unordered_map<Tensor, Tensor>& rmap) const final;
166  void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
167  const std::unordered_map<const VarNode*, IntSet>& dom_map,
168  std::unordered_map<Tensor, TensorDom>* out_dom_map) const final;
169  void GatherBound(const Operation& self, const std::unordered_map<Tensor, TensorDom>& tensor_dom,
170  std::unordered_map<IterVar, Range>* out_dom_map) const final;
171  Stmt BuildRealize(const Stage& stage, const std::unordered_map<IterVar, Range>& realize_map,
172  const Stmt& body, String storage_scope = "") const final;
173  Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
174  bool debug_keep_trivial_loop) const final;
175 
176  void VisitAttrs(AttrVisitor* v) {
177  v->Visit("name", &name);
178  v->Visit("tag", &tag);
179  v->Visit("attrs", &attrs);
180  v->Visit("shape", &shape);
181  v->Visit("dtype", &dtype);
182  }
183 
184  static constexpr const char* _type_key = "PlaceholderOp";
186 };
187 
192 class PlaceholderOp : public Operation {
193  public:
194  TVM_DLL PlaceholderOp(std::string name, Array<PrimExpr> shape, DataType dtype);
195 
197 };
198 
204 class TVM_DLL BaseComputeOpNode : public OperationNode {
205  public:
210  // override functions
211  Array<IterVar> root_iter_vars() const final;
212  Array<PrimExpr> output_shape(size_t idx) const final;
213  void GatherBound(const Operation& self, const std::unordered_map<Tensor, TensorDom>& tensor_dom,
214  std::unordered_map<IterVar, Range>* out_dom_map) const final;
215  Stmt BuildRealize(const Stage& stage, const std::unordered_map<IterVar, Range>& realize_map,
216  const Stmt& body, String storage_scope = "") const final;
217  virtual size_t num_schedulable_dims() const = 0;
218 
219  static constexpr const char* _type_key = "BaseComputeOp";
221 };
222 
226 class TVM_DLL ComputeOpNode : public BaseComputeOpNode {
227  public:
232  // override functions
233  int num_outputs() const final;
234  DataType output_dtype(size_t i) const final;
235  Array<Tensor> InputTensors() const final;
236  Operation ReplaceInputs(const Operation& self,
237  const std::unordered_map<Tensor, Tensor>& rmap) const final;
238  void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
239  const std::unordered_map<const VarNode*, IntSet>& dom_map,
240  std::unordered_map<Tensor, TensorDom>* out_dom_map) const final;
241  Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
242  bool debug_keep_trivial_loop) const final;
243  size_t num_schedulable_dims() const final;
244 
246  v->Visit("name", &name);
247  v->Visit("tag", &tag);
248  v->Visit("attrs", &attrs);
249  v->Visit("axis", &axis);
250  v->Visit("reduce_axis", &reduce_axis);
251  v->Visit("body", &body);
252  }
253 
254  static constexpr const char* _type_key = "ComputeOp";
255  TVM_DECLARE_FINAL_OBJECT_INFO(ComputeOpNode, BaseComputeOpNode);
256 };
257 
262 class ComputeOp : public Operation {
263  public:
264  TVM_DLL ComputeOp(std::string name, std::string tag, Map<String, ObjectRef> attrs,
265  Array<IterVar> axis, Array<PrimExpr> body);
266 
268 };
269 
274  public:
287  // override functions
288  int num_outputs() const final;
289  DataType output_dtype(size_t i) const final;
290  Array<Tensor> InputTensors() const final;
291  Operation ReplaceInputs(const Operation& self,
292  const std::unordered_map<Tensor, Tensor>& rmap) const final;
293  void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
294  const std::unordered_map<const VarNode*, IntSet>& dom_map,
295  std::unordered_map<Tensor, TensorDom>* out_dom_map) const final;
296  Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
297  bool debug_keep_trivial_loop) const final;
298  size_t num_schedulable_dims() const final;
299 
301  v->Visit("name", &name);
302  v->Visit("tag", &tag);
303  v->Visit("axis", &axis);
304  v->Visit("reduce_axis", &reduce_axis);
305  v->Visit("schedulable_ndim", &schedulable_ndim);
306  v->Visit("intrin", &intrin);
307  v->Visit("inputs", &inputs);
308  v->Visit("input_regions", &input_regions);
309  v->Visit("scalar_inputs", &scalar_inputs);
310  }
311 
312  static constexpr const char* _type_key = "TensorComputeOp";
314 };
315 
320 class TensorComputeOp : public Operation {
321  public:
322  TVM_DLL TensorComputeOp(std::string name, std::string tag, Array<IterVar> axis,
323  Array<IterVar> reduce_axis, int schedulable_ndim, TensorIntrin intrin,
324  Array<Tensor> tensors, Array<Region> regions,
325  Array<PrimExpr> scalar_inputs);
326 
328 };
329 
333 class ScanOpNode : public OperationNode {
334  public:
360  // override behavior.
361  int num_outputs() const final;
362  Array<IterVar> root_iter_vars() const final;
363  DataType output_dtype(size_t i) const final;
364  Array<PrimExpr> output_shape(size_t i) const final;
365  Array<Tensor> InputTensors() const final;
366  Operation ReplaceInputs(const Operation& self,
367  const std::unordered_map<Tensor, Tensor>& rmap) const final;
368  void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
369  const std::unordered_map<const VarNode*, IntSet>& dom_map,
370  std::unordered_map<Tensor, TensorDom>* out_dom_map) const final;
371  void GatherBound(const Operation& self, const std::unordered_map<Tensor, TensorDom>& tensor_dom,
372  std::unordered_map<IterVar, Range>* out_dom_map) const final;
373  Stmt BuildRealize(const Stage& stage, const std::unordered_map<IterVar, Range>& realize_map,
374  const Stmt& body, String storage_scope = "") const final;
375  Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
376  bool debug_keep_trivial_loop) const final;
377 
379  v->Visit("name", &name);
380  v->Visit("tag", &tag);
381  v->Visit("attrs", &attrs);
382  v->Visit("scan_axis", &scan_axis);
383  v->Visit("init", &init);
384  v->Visit("update", &update);
385  v->Visit("state_placeholder", &state_placeholder);
386  v->Visit("inputs", &inputs);
387  v->Visit("spatial_axis_", &spatial_axis_);
388  }
389 
390  static constexpr const char* _type_key = "ScanOp";
392 };
393 
398 class ScanOp : public Operation {
399  public:
400  TVM_DLL ScanOp(std::string name, std::string tag, Map<String, ObjectRef> attrs, IterVar axis,
401  Array<Tensor> init, Array<Tensor> update, Array<Tensor> state_placeholder,
402  Array<Tensor> input);
403 
405 };
406 
410 class ExternOpNode : public OperationNode {
411  public:
420 
423  // override functions
424  int num_outputs() const final;
425  Array<IterVar> root_iter_vars() const final;
426  DataType output_dtype(size_t i) const final;
427  Array<PrimExpr> output_shape(size_t i) const final;
428  Array<Tensor> InputTensors() const final;
429  Operation ReplaceInputs(const Operation& self,
430  const std::unordered_map<Tensor, Tensor>& rmap) const final;
431  void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
432  const std::unordered_map<const VarNode*, IntSet>& dom_map,
433  std::unordered_map<Tensor, TensorDom>* out_dom_map) const final;
434  void GatherBound(const Operation& self, const std::unordered_map<Tensor, TensorDom>& tensor_dom,
435  std::unordered_map<IterVar, Range>* out_dom_map) const final;
436  Stmt BuildRealize(const Stage& stage, const std::unordered_map<IterVar, Range>& realize_map,
437  const Stmt& body, String storage_scope = "") const final;
438  Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
439  bool debug_keep_trivial_loop) const final;
440 
442  v->Visit("name", &name);
443  v->Visit("tag", &tag);
444  v->Visit("attrs", &attrs);
445  v->Visit("inputs", &inputs);
446  v->Visit("input_placeholders", &input_placeholders);
447  v->Visit("output_placeholders", &output_placeholders);
448  v->Visit("body", &body);
449  }
450 
451  static constexpr const char* _type_key = "ExternOp";
453 };
454 
459 class ExternOp : public Operation {
460  public:
461  TVM_DLL ExternOp(std::string name, std::string tag, Map<String, ObjectRef> attrs,
462  Array<Tensor> inputs, Array<Buffer> input_placeholders,
463  Array<Buffer> output_placeholders, Stmt body);
464 
466 };
467 
471 class HybridOpNode : public OperationNode {
472  public:
485 
488  // override functions
489  int num_outputs() const final;
490  Array<IterVar> root_iter_vars() const final;
491  DataType output_dtype(size_t i) const final;
492  Array<PrimExpr> output_shape(size_t i) const final;
493  Array<Tensor> InputTensors() const final;
494  Operation ReplaceInputs(const Operation& self,
495  const std::unordered_map<Tensor, Tensor>& rmap) const final;
496  void PropBoundToInputs(const Operation& self, arith::Analyzer* analyzer,
497  const std::unordered_map<const VarNode*, IntSet>& dom_map,
498  std::unordered_map<Tensor, TensorDom>* out_dom_map) const final;
499  void GatherBound(const Operation& self, const std::unordered_map<Tensor, TensorDom>& tensor_dom,
500  std::unordered_map<IterVar, Range>* out_dom_map) const final;
501  Stmt BuildRealize(const Stage& stage, const std::unordered_map<IterVar, Range>& realize_map,
502  const Stmt& body, String storage_scope = "") const final;
503  Stmt BuildProvide(const Stage& stage, const std::unordered_map<IterVar, Range>& dom_map,
504  bool debug_keep_trivial_loop) const final;
505 
507  v->Visit("name", &name);
508  v->Visit("tag", &tag);
509  v->Visit("attrs", &attrs);
510  v->Visit("inputs", &inputs);
511  v->Visit("outputs", &outputs);
512  v->Visit("axis", &axis);
513  v->Visit("body", &body);
514  }
515 
516  static constexpr const char* _type_key = "HybridOp";
518 };
519 
524 class HybridOp : public Operation {
525  public:
526  TVM_DLL HybridOp(std::string name, std::string tag, Map<String, ObjectRef> attrs,
527  Array<Tensor> inputs, Array<Tensor> outputs, Stmt body);
528 
530 };
531 
537 TVM_DLL Var var(std::string name_hint, DataType t = DataType::Int(32));
538 
545 TVM_DLL IterVar thread_axis(Range dom, std::string tag);
546 
553 TVM_DLL IterVar reduce_axis(Range dom, std::string name = "rv");
554 
556 using FCompute = std::function<PrimExpr(const Array<Var>& i)>;
557 
559 using FBatchCompute = std::function<Array<PrimExpr>(const Array<Var>& i)>;
560 
568  std::string name = "placeholder");
569 
579 TVM_DLL Tensor compute(Array<PrimExpr> shape, FCompute fcompute, std::string name = "tensor",
580  std::string tag = "", Map<String, ObjectRef> attrs = {});
581 
591 TVM_DLL Array<Tensor> compute(Array<PrimExpr> shape, FBatchCompute fcompute,
592  std::string name = "tensor", std::string tag = "",
593  Map<String, ObjectRef> attrs = {});
594 
607 TVM_DLL Array<Tensor> scan(Array<Tensor> init, Array<Tensor> update,
608  Array<Tensor> state_placeholder, Array<Tensor> inputs = Array<Tensor>(),
609  std::string name = "scan", std::string tag = "",
610  Map<String, ObjectRef> attrs = {});
611 
612 // same as compute, specialized for different fcompute function
613 inline Tensor compute(Array<PrimExpr> shape, std::function<PrimExpr(Var)> f,
614  std::string name = "tensor", std::string tag = "",
615  Map<String, ObjectRef> attrs = {}) {
616  FCompute fc = [f](const Array<Var>& i) { return f(i[0]); };
617  return compute(shape, fc, name, tag, attrs);
618 }
619 inline Tensor compute(Array<PrimExpr> shape, std::function<PrimExpr(Var, Var)> f,
620  std::string name = "tensor", std::string tag = "",
621  Map<String, ObjectRef> attrs = {}) {
622  FCompute fc = [f](const Array<Var>& i) { return f(i[0], i[1]); };
623  return compute(shape, fc, name, tag, attrs);
624 }
625 inline Tensor compute(Array<PrimExpr> shape, std::function<PrimExpr(Var, Var, Var)> f,
626  std::string name = "tensor", std::string tag = "",
627  Map<String, ObjectRef> attrs = {}) {
628  FCompute fc = [f](const Array<Var>& i) { return f(i[0], i[1], i[2]); };
629  return compute(shape, fc, name, tag, attrs);
630 }
631 inline Tensor compute(Array<PrimExpr> shape, std::function<PrimExpr(Var, Var, Var, Var)> f,
632  std::string name = "tensor", std::string tag = "",
633  Map<String, ObjectRef> attrs = {}) {
634  FCompute fc = [f](const Array<Var>& i) { return f(i[0], i[1], i[2], i[3]); };
635  return compute(shape, fc, name, tag, attrs);
636 }
637 
638 // inline function.
639 inline const OperationNode* Operation::operator->() const {
640  return static_cast<const OperationNode*>(get());
641 }
642 } // namespace te
643 } // namespace tvm
644 #endif // TVM_TE_OPERATION_H_
IterVar thread_axis(Range dom, std::string tag)
Create a new IterVar that represents an axis in thread.
Array< Tensor > outputs
Symbolic placeholder representation of outputs.
Definition: operation.h:476
ComputeOpNode()
constructor
Definition: operation.h:231
Stmt body
the statement that generates the computation. This is slightly different from the body in ExternOpNod...
Definition: operation.h:484
std::string name
optional name of the operation
Definition: operation.h:59
Tensor placeholder(Array< PrimExpr > shape, DataType dtype=DataType::Float(32), std::string name="placeholder")
create a place holder tensor.
Managed reference to TensorComputeOpNode.
Definition: operation.h:320
Base class of all operation nodes.
Definition: operation.h:56
Managed reference to PlaceholderOpNode.
Definition: operation.h:192
int schedulable_ndim
number of axes that can be scheduled
Definition: operation.h:276
External computation that cannot be splitted.
Definition: operation.h:410
A computation operator that generated by hybrid script.
Definition: operation.h:471
std::string tag
optional tag of the operation
Definition: operation.h:61
IterVar scan_axis
IterVar to scan over.
Definition: operation.h:336
Stmt body
the statement that generates the computation.
Definition: operation.h:419
Performance counters for profiling via the PAPI library.
Definition: analyzer.h:36
Array< IterVar > axis
The axis of iterations.
Definition: operation.h:478
A Compute op that compute a tensor on certain domain. This is the base class for ComputeOp (operating...
Definition: operation.h:204
Operation that produces tensors.
Definition: tensor.h:47
a named variable in TIR
Definition: var.h:88
Algebra expression simplifications.
HybridOpNode()
constructor
Definition: operation.h:487
Iteration Variable, represents an iteration over an integer interval.
Definition: var.h:297
A placeholder op represents an input placeholder.
Definition: operation.h:152
Definition: loop_state.h:456
A variable node in the IR.
Definition: var.h:47
Stage, contains scheduling for a stage of computation.
Definition: schedule.h:57
DataType dtype
The data type of the input.
Definition: operation.h:157
Symbolic scan.
Definition: operation.h:333
base class of all object containers.
Definition: object.h:165
Common operators defined for Expr.
ExternOpNode()
constructor
Definition: operation.h:422
Map< String, ObjectRef > attrs
additional attributes of the operation
Definition: operation.h:63
Array< Buffer > output_placeholders
Symbolic placeholder representation of outputs.
Definition: operation.h:417
std::function< PrimExpr(const Array< Var > &i)> FCompute
The compute function to specify the input source of a Tensor.
Definition: operation.h:556
Array< Tensor > inputs
The input tensors.
Definition: operation.h:474
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
Dataflow tensor object.
Range constainer.
Definition: expr.h:449
void VisitAttrs(AttrVisitor *v)
Definition: operation.h:506
Managed reference to TensorIntrinNode.
Definition: tensor_intrin.h:93
TensorComputeOpNode()
constructor
Definition: operation.h:286
Runtime primitive data type.
Definition: data_type.h:41
std::vector< std::vector< IntSet > > data
The domain data.
Definition: operation.h:50
TIR expressions.
static DataType Float(int bits, int lanes=1)
Construct an float type.
Definition: data_type.h:168
Managed reference to IntSetNode.
Definition: int_set.h:68
Array, container representing a contiguous sequence of ObjectRefs.
Definition: array.h:270
void VisitAttrs(AttrVisitor *v)
Definition: operation.h:378
std::function< Array< PrimExpr >(const Array< Var > &i)> FBatchCompute
The compute function to specify the inputs source of Tensors.
Definition: operation.h:559
Container of all statements.
Definition: stmt.h:57
A Compute op that compute a tensor on certain domain.
Definition: operation.h:226
Array< IterVar > axis
IterVar on each axis.
Definition: operation.h:207
Managed reference to ExternOpNode.
Definition: operation.h:459
Reference to string objects.
Definition: string.h:129
Array< Tensor > inputs
input tensors of intrin
Definition: operation.h:280
Tensor shape(const Tensor &src, DataType dtype, const std::string name="T_shape", const std::string tag=kInjective)
Get the shape of input tensor.
Definition: transform.h:1608
#define TVM_DEFINE_OBJECT_REF_METHODS(TypeName, ParentType, ObjectName)
Definition: object.h:706
Managed reference to ScanOpNode.
Definition: operation.h:398
ScanOpNode()
constructor
Definition: operation.h:359
Array< Tensor > state_placeholder
The placeholder to refer as states in update.
Definition: operation.h:342
A TenorCompute op that compute a tensor with an tensor intrinsic.
Definition: operation.h:273
virtual ~OperationNode()
Definition: operation.h:65
IterVar reduce_axis(Range dom, std::string name="rv")
Create a new IterVar for reduction operations.
void VisitAttrs(AttrVisitor *v)
Definition: operation.h:245
Var var(std::string name_hint, DataType t=DataType::Int(32))
Construct a new Var expression.
Tensor structure representing a possible input, or intermediate computation result.
Definition: tensor.h:102
void VisitAttrs(AttrVisitor *v)
Definition: operation.h:300
Array< IterVar > spatial_axis_
Spatial axis to indicate spatial dimension of each output. They corresponds to flattened spatial axis...
Definition: operation.h:357
#define TVM_DECLARE_FINAL_OBJECT_INFO(TypeName, ParentType)
helper macro to declare type information in a final class.
Definition: object.h:664
Symbolic n-dimensional array, to represent a memory buffer.
Array< Tensor > init
the initialization tensors
Definition: operation.h:338
Array< Region > input_regions
region of input tensors
Definition: operation.h:282
Array< Tensor > inputs
The input tensors.
Definition: operation.h:413
Array< Buffer > input_placeholders
Symbolic placeholder representation of inputs.
Definition: operation.h:415
Map container of NodeRef->NodeRef in DSL graph. Map implements copy on write semantics, which means map is mutable but copy will happen when array is referenced in more than two places.
Definition: map.h:1235
Array< Tensor > update
the update function represented by tensor
Definition: operation.h:340
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:347
Array< PrimExpr > shape
The shape of the input.
Definition: operation.h:155
Managed reference to HybridOpNode.
Definition: operation.h:524
Array< Tensor > scan(Array< Tensor > init, Array< Tensor > update, Array< Tensor > state_placeholder, Array< Tensor > inputs=Array< Tensor >(), std::string name="scan", std::string tag="", Map< String, ObjectRef > attrs={})
Construct new tensors by scan.
Tensor compute(Array< PrimExpr > shape, FCompute fcompute, std::string name="tensor", std::string tag="", Map< String, ObjectRef > attrs={})
Construct a new tensor by computing over shape, using the computation rule: result_tensor[axis] = fco...
Managed reference to ComputeOpNode.
Definition: operation.h:262
const OperationNode * operator->() const
access the internal node container
Definition: operation.h:639
TensorIntrin intrin
TensorIntrin used to compute.
Definition: operation.h:278
Reference to PrimExprNode.
Definition: expr.h:109
Array< PrimExpr > scalar_inputs
scalar expression inputs
Definition: operation.h:284
Temporary data structure to store union of bounds of each axis of Tensor.
Definition: operation.h:46
void VisitAttrs(AttrVisitor *v)
Definition: operation.h:441
TensorDom(int ndim)
Definition: operation.h:48
#define TVM_DECLARE_BASE_OBJECT_INFO(TypeName, ParentType)
helper macro to declare a base object type that can be inherited.
Definition: object.h:641
Define a schedule.
Array< IterVar > reduce_axis
IterVar on each reduction axis, if the body is a Reduce.
Definition: operation.h:209
Array< PrimExpr > body
the compute expression
Definition: operation.h:229
Analyzer that contains bunch of sub-analyzers.
Definition: analyzer.h:387
static DataType Int(int bits, int lanes=1)
Construct an int type.
Definition: data_type.h:154