tvm
Loading...
Searching...
No Matches
reduction.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_TOPI_REDUCTION_H_
25#define TVM_TOPI_REDUCTION_H_
26
27#include <tvm/te/operation.h>
28#include <tvm/topi/broadcast.h>
31#include <tvm/topi/elemwise.h>
32#include <tvm/topi/tags.h>
33#include <tvm/topi/transform.h>
34
35#include <algorithm>
36#include <iterator>
37#include <string>
38#include <vector>
39
40namespace tvm {
41namespace topi {
42
43using namespace tvm::te;
44
46using FReduce = std::function<PrimExpr(PrimExpr source, const ffi::Array<IterVar>& axis,
47 ffi::Array<PrimExpr> init, Span span)>;
48
50using FCommReduce = std::function<ffi::Array<PrimExpr>(
51 ffi::Array<PrimExpr> exprs, const ffi::Array<IterVar>& axis, PrimExpr* condition)>;
52
65inline std::vector<int> GetRealAxis(int ndim, const ffi::Optional<ffi::Array<int64_t>>& axis) {
66 std::vector<int> real_axis;
67 if (!axis.has_value()) {
68 for (int i = 0; i < ndim; ++i) {
69 real_axis.push_back(i);
70 }
71 } else {
72 // Use a set so duplicates are removed and the dims are sorted
73 for (int64_t elem : axis.value()) {
75 if (val < 0) {
76 val += ndim;
77 }
78 TVM_FFI_ICHECK_LT(val, ndim) << " exceeds the maximum dimension " << ndim;
80 real_axis.push_back(static_cast<int>(val));
81 }
82 std::sort(real_axis.begin(), real_axis.end());
83 real_axis.resize(std::unique(real_axis.begin(), real_axis.end()) - real_axis.begin());
84 }
85 return real_axis;
86}
87
89inline ffi::Array<IterVar> MakeReduceAxes(const std::vector<int>& real_axis, const Tensor& data) {
90 ffi::Array<IterVar> reduce_axes;
91 for (auto i : real_axis) {
92 std::string name = "k" + std::to_string(i);
93 reduce_axes.push_back(tvm::te::reduce_axis(Range(0, data->shape[i]), name));
94 }
95 return reduce_axes;
96}
97
99inline ffi::Array<PrimExpr> MakeReduceTargetShape(const std::vector<int>& real_axis,
100 const Tensor& data, bool keepdims,
101 bool atleast1d) {
102 auto ndim = data->shape.size();
103 ffi::Array<PrimExpr> target_shape;
104 if (keepdims) {
105 for (size_t i = 0; i < ndim; ++i) {
106 if (std::find(real_axis.begin(), real_axis.end(), i) != real_axis.end()) {
107 // real_axis contains i
108 target_shape.push_back(1);
109 } else {
110 target_shape.push_back(data->shape[i]);
111 }
112 }
113 } else {
114 for (size_t i = 0; i < ndim; ++i) {
115 if (std::find(real_axis.begin(), real_axis.end(), i) == real_axis.end()) {
116 // real_axis does not contain i
117 target_shape.push_back(data->shape[i]);
118 }
119 }
120 }
121 if (target_shape.size() == 0 && atleast1d) {
122 target_shape.push_back(1);
123 }
124 return target_shape;
125}
126
140inline Tensor DoCommReduce(const Tensor& data, FReduce func,
141 const ffi::Array<PrimExpr>& target_shape,
142 const std::vector<int>& reduce_axes,
143 const std::vector<int>& squeeze_axes, Span span = Span()) {
144 auto r_axes = MakeReduceAxes(reduce_axes, data);
145 auto compute = [&](const ffi::Array<PrimVar>& indices) {
146 ffi::Array<PrimExpr> eval_range;
147 ffi::Array<PrimVar> eval_indices;
148 int arg_counter = 0;
149 int red_counter = 0;
150
151 for (size_t i = 0; i < data->shape.size(); ++i) {
152 bool squeeze_i = std::find(squeeze_axes.begin(), squeeze_axes.end(), i) != squeeze_axes.end();
153 if (std::find(reduce_axes.begin(), reduce_axes.end(), i) != reduce_axes.end()) {
154 // real_axis contains i
155 eval_range.push_back(r_axes[red_counter]);
156 eval_indices.push_back(r_axes[red_counter]->var);
157 red_counter++;
159 continue;
160 }
161 eval_range.push_back(indices[arg_counter]);
162 arg_counter++;
163 }
164
165 return func(data(eval_range), r_axes, {}, span);
166 };
167
168 return tvm::te::compute(target_shape, compute, data->op->name + "_red", kCommReduce);
169}
170
184inline Tensor CommReduce(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
185 FReduce func, bool keepdims, bool atleast1d) {
186 auto ndim = data->shape.size();
187 if (ndim == 0) {
188 auto identity = topi::identity(data, data->op->name + "_red", kCommReduce);
190 }
191 auto real_axis = GetRealAxis(static_cast<int>(ndim), axis);
192 auto target_shape = MakeReduceTargetShape(real_axis, data, keepdims, atleast1d);
193 return DoCommReduce(data, func, target_shape, real_axis,
194 keepdims ? std::vector<int>() : real_axis);
195}
196
210inline Tensor CommReduceIdx(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
211 FCommReduce func, bool keepdims, bool atleast1d) {
212 auto ndim = data->shape.size();
213 TVM_FFI_ICHECK_NE(ndim, 0) << "Cannot reduce a 0 dim Tensor";
214 auto real_axis = GetRealAxis(static_cast<int>(ndim), axis);
216 auto target_shape = MakeReduceTargetShape(real_axis, data, keepdims, atleast1d);
217
218 auto compute = [ndim, keepdims, &real_axis, &reduce_axes, &func,
219 &data](const ffi::Array<PrimVar>& indices) {
220 ffi::Array<PrimExpr> eval_range;
221 ffi::Array<PrimExpr> eval_indices;
222 int arg_counter = 0;
223 int red_counter = 0;
224
225 for (size_t i = 0; i < ndim; ++i) {
226 if (std::find(real_axis.begin(), real_axis.end(), i) != real_axis.end()) {
227 // real_axis contains i
230 red_counter++;
231 } else {
232 if (!keepdims) {
233 eval_range.push_back(indices[arg_counter]);
234 arg_counter++;
235 } else {
236 eval_range.push_back(indices[i]);
237 }
238 }
239 }
240
241 ffi::Array<PrimExpr> ravel_shape;
242 for (auto i : real_axis) {
243 ravel_shape.push_back(data->shape[i]);
244 }
245 auto idx = detail::RavelIndex(eval_indices, ravel_shape);
246 return func({idx, data(eval_range)}, reduce_axes, nullptr);
247 };
248
249 auto temp_idx_val =
250 tvm::te::compute(target_shape, compute, data->op->name + "_red_temp", kCommReduceIdx);
251 auto temp_idx = temp_idx_val[0];
252 auto temp_val = temp_idx_val[1];
253 return tvm::te::compute(
254 target_shape, [&temp_idx](const ffi::Array<PrimVar>& indices) { return temp_idx(indices); },
255 data->op->name + "_red", kCommReduceIdx);
256}
257
259using FCombine =
260 std::function<ffi::Array<PrimExpr>(ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs)>;
261
263using FIdentity = std::function<ffi::Array<PrimExpr>(std::vector<PrimType> types)>;
264
275 std::string name = "reduce") {
276 return [fcombine, fidentity, name](ffi::Array<PrimExpr> exprs, const ffi::Array<IterVar>& axis,
277 PrimExpr* condition) {
278 ffi::Array<PrimVar> lhs, rhs;
279 ffi::Array<PrimVar> callback_lhs, callback_rhs;
280 std::vector<PrimType> dtypes;
281
282 for (size_t i = 0; i < exprs.size(); ++i) {
283 PrimType dtype = exprs[i].ty();
284 dtypes.push_back(dtype);
285 PrimVar lhs_var(name + "_lhs_" + std::to_string(i), dtype);
286 PrimVar rhs_var(name + "_rhs_" + std::to_string(i), dtype);
287 lhs.push_back(lhs_var);
288 rhs.push_back(rhs_var);
289 callback_lhs.push_back(lhs_var);
290 callback_rhs.push_back(rhs_var);
291 }
292
293 auto result = fcombine(callback_lhs, callback_rhs);
294 auto id_elem = fidentity(dtypes);
295 auto cond = condition != nullptr ? *condition : IntImm::Bool(true);
296
297 auto combiner = tvm::te::CommReducer(lhs, rhs, result, id_elem);
298 ffi::Array<PrimExpr> outputs;
299 for (size_t i = 0; i < exprs.size(); ++i) {
300 outputs.push_back(tvm::te::Reduce(combiner, exprs, axis, cond, static_cast<int>(i), {}));
301 }
302 return outputs;
303 };
304}
305
307inline PrimExpr MinOp(PrimExpr source, ffi::Array<IterVar> axis, ffi::Array<PrimExpr> init = {},
308 Span span = Span()) {
309 return tvm::min(source, axis, init, span);
310}
311
313inline PrimExpr MaxOp(PrimExpr source, ffi::Array<IterVar> axis, ffi::Array<PrimExpr> init = {},
314 Span span = Span()) {
315 return tvm::max(source, axis, init, span); // NOLINT(*)
316}
317
319inline PrimExpr ProdOp(PrimExpr source, ffi::Array<IterVar> axis, ffi::Array<PrimExpr> init = {},
320 Span span = Span()) {
321 return tvm::prod(source, axis, init, span); // NOLINT(*)
322}
323
337inline Tensor sum(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
338 bool keepdims = false, bool atleast1d = false) {
339 // Reduction dispatch only depends on boolean element kind; lane encoding is irrelevant here.
340 if (data->dtype.code() == DLDataTypeCode::kDLBool) {
341 return CommReduce(data, axis, tvm::any, keepdims, atleast1d);
342 } else {
343 return CommReduce(data, axis, tvm::sum, keepdims, atleast1d);
344 }
345}
346
347inline Tensor collapse_sum(const Tensor& data, ffi::Array<PrimExpr> target_shape) {
348 const auto& ishape = data->shape;
349 const auto& oshape = target_shape;
350 int isize = data->shape.size();
351 int osize = target_shape.size();
352
354 << "Invalid collapse: input dimensionality smaller than output dimensionality.\ninput shape: "
355 << data->shape << "\nvs\noutput shape: " << target_shape;
356
357 std::vector<int> reduce_axes;
358 std::vector<int> squeeze_axes;
360
361 for (int i_ax = isize - 1, o_ax = osize - 1; i_ax >= 0; --i_ax) {
362 if (o_ax >= 0 && topi::detail::EqualCheck(ishape[i_ax], oshape[o_ax])) {
363 --o_ax;
364 continue;
365 }
366 reduce_axes.push_back(i_ax);
367 if (o_ax < 0) { // squeeze o_ax if was added during expansion
368 squeeze_axes.push_back(i_ax);
369 } else if (topi::detail::EqualCheck(one, oshape[o_ax])) {
370 --o_ax;
371 }
372 }
373
374 if (reduce_axes.size() == 0) return topi::identity(data, "tensor", kCommReduce);
375
376 std::reverse(reduce_axes.begin(), reduce_axes.end());
377 std::reverse(squeeze_axes.begin(), squeeze_axes.end());
379}
380
395inline Tensor all(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
396 bool keepdims = false, bool atleast1d = false) {
397 return CommReduce(data, axis, tvm::all, keepdims, atleast1d);
398}
399
414inline Tensor any(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
415 bool keepdims = false, bool atleast1d = false) {
416 return CommReduce(data, axis, tvm::any, keepdims, atleast1d);
417}
418
433inline Tensor min(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
434 bool keepdims = false, bool atleast1d = false) {
435 return CommReduce(data, axis, MinOp, keepdims, atleast1d);
436}
437
452inline Tensor max(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
453 bool keepdims = false, bool atleast1d = false) {
454 return CommReduce(data, axis, MaxOp, keepdims, atleast1d);
455}
456
458 // Create a Commutative Reducer with a comparison operation, and method to get the initial value.
459 auto fcombine = [=](ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs) {
460 ffi::Array<PrimExpr> result;
461
462 // Casting to avoid operator ambiguity
463 PrimExpr lhs_idx = static_cast<PrimExpr>(lhs[0]);
464 PrimExpr rhs_idx = static_cast<PrimExpr>(rhs[0]);
465 PrimExpr lhs_val = static_cast<PrimExpr>(lhs[1]);
466 PrimExpr rhs_val = static_cast<PrimExpr>(rhs[1]);
467
468 // These variables compare the actual values of the array
469 auto is_smaller = lhs_val < rhs_val;
470 auto is_same = lhs_val == rhs_val;
471
472 // This checks if the indices are correct for the reduction. E.g. for select_last_index
473 // it gives precedence for later indices of the same element and precedence for sooner
474 // indices if not select_last_index;
476 if (select_last_index) {
478 } else {
480 }
481
483 result.push_back(tvm::prim::Select(update_index, lhs[0], rhs[0])); // idx
484 result.push_back(tvm::prim::Select(is_smaller, lhs[1], rhs[1])); // val
485 return result;
486 };
487 auto fidentity = [&](std::vector<PrimType> types) {
488 ffi::Array<PrimExpr> result;
489 result.push_back(tvm::tirx::MakeConst(types[0], -1)); // idx
490 result.push_back(tvm::max_value(types[1])); // val
491 return result;
492 };
493 return MakeCommReducer(fcombine, fidentity, "argmin");
494}
495
512inline Tensor argmin(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
513 bool keepdims = false, bool atleast1d = false,
514 bool select_last_index = false) {
516 return CommReduceIdx(data, axis, reducer, keepdims, atleast1d);
517}
518
520 // Create a Commutative Reducer with a comparison operation, and method to get the initial value.
521 auto fcombine = [=](ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs) {
522 ffi::Array<PrimExpr> result;
523
524 // Casting to avoid operator ambiguity
525 PrimExpr lhs_idx = static_cast<PrimExpr>(lhs[0]);
526 PrimExpr rhs_idx = static_cast<PrimExpr>(rhs[0]);
527 PrimExpr lhs_val = static_cast<PrimExpr>(lhs[1]);
528 PrimExpr rhs_val = static_cast<PrimExpr>(rhs[1]);
529
530 // These variables compare the actual values of the array
531 auto is_bigger = lhs_val > rhs_val;
532 auto is_same = lhs_val == rhs_val;
533
534 // This checks if the indices are correct for the reduction. E.g. for select_last_index
535 // it gives precedence for later indices of the same element and precedence for sooner
536 // indices if not select_last_index;
538 if (select_last_index) {
540 } else {
542 }
543
545 result.push_back(tvm::prim::Select(update_index, lhs[0], rhs[0])); // idx
546 result.push_back(tvm::prim::Select(is_bigger, lhs[1], rhs[1])); // val
547 return result;
548 };
549 auto fidentity = [&](std::vector<PrimType> types) {
550 ffi::Array<PrimExpr> result;
551 result.push_back(tvm::tirx::MakeConst(types[0], -1)); // idx
552 result.push_back(tvm::min_value(types[1])); // val
553 return result;
554 };
555 return MakeCommReducer(fcombine, fidentity, "argmax");
556}
557
573inline Tensor argmax(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
574 bool keepdims = false, bool atleast1d = false,
575 bool select_last_index = false) {
577 return CommReduceIdx(data, axis, reducer, keepdims, atleast1d);
578}
579
593inline Tensor prod(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
594 bool keepdims = false, bool atleast1d = false) {
595 return CommReduce(data, axis, ProdOp, keepdims, atleast1d);
596}
597
602 auto fcombine = [](ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs) {
603 ffi::Array<PrimExpr> result;
604 TVM_FFI_ICHECK_EQ(lhs.size(), rhs.size());
605 result.reserve(lhs.size());
606 for (size_t i = 0; i < lhs.size(); ++i) {
607 result.push_back(lhs[i] + rhs[i]);
608 }
609 return result;
610 };
611 auto fidentity = [](std::vector<PrimType> types) {
612 ffi::Array<PrimExpr> result;
613 for (size_t i = 0; i < types.size(); ++i) {
614 result.push_back(tvm::tirx::MakeConst(types[i], 0));
615 }
616 return result;
617 };
618 return MakeCommReducer(fcombine, fidentity, "tuple_sum");
619}
620
621} // namespace topi
622} // namespace tvm
623#endif // TVM_TOPI_REDUCTION_H_
Broadcast op constructions.
static IntImm Bool(bool value, Span span=Span())
Construct a scalar boolean constant.
Definition expr.h:519
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
Definition base_expr.h:137
Range container
Definition expr.h:610
Definition source_map.h:111
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Managed reference to SelectNode.
Definition expr.h:525
Managed Tensor. The array is backed by reference counted blocks.
Definition tensor.h:49
Managed reference to CommReducerNode.
Definition operation.h:89
Managed reference to ReduceNode.
Definition operation.h:133
Checked scalar view over a VarNode.
Definition var.h:46
Utility functions for handling constants in TVM expressions.
Elementwise op constructions.
Tensor expression language DSL.
Definition extracted_task.h:33
PrimVar var(std::string name_hint, PrimType t=PrimType::Int(32))
Construct a new Var expression.
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...
const Op & max()
@ kCommReduce
Communicative reduction. Cannot be directly parallelized.
Definition var.h:104
const Op & min()
PrimExpr MakeConst(PrimType dtype, ValueType value, Span span=Span())
Make a const value with certain data type.
Definition op.h:1002
const Op & sum()
Tensor DoCommReduce(const Tensor &data, FReduce func, const ffi::Array< PrimExpr > &target_shape, const std::vector< int > &reduce_axes, const std::vector< int > &squeeze_axes, Span span=Span())
Create a reduction operation.
Definition reduction.h:140
Tensor collapse_sum(const Tensor &data, ffi::Array< PrimExpr > target_shape)
Definition reduction.h:347
ffi::Array< PrimExpr > MakeReduceTargetShape(const std::vector< int > &real_axis, const Tensor &data, bool keepdims, bool atleast1d)
Calculate the target shape for a reduce op.
Definition reduction.h:99
std::function< ffi::Array< PrimExpr >(ffi::Array< PrimVar > lhs, ffi::Array< PrimVar > rhs)> FCombine
A combiner function for a reduction.
Definition reduction.h:260
ffi::Array< IterVar > MakeReduceAxes(const std::vector< int > &real_axis, const Tensor &data)
Enumerate the axes for a reduce op.
Definition reduction.h:89
FCommReduce MakeTupleSumReducer()
Create communitive reducer summing over tuples.
Definition reduction.h:601
std::vector< int > GetRealAxis(int ndim, const ffi::Optional< ffi::Array< int64_t > > &axis)
Convert a reduction axis which could be empty or have negative elements into a real axis with valid d...
Definition reduction.h:65
FCommReduce MakeCommReducer(FCombine fcombine, FIdentity fidentity, std::string name="reduce")
Create a commutative reducer for a reduction.
Definition reduction.h:274
std::function< ffi::Array< PrimExpr >(std::vector< PrimType > types)> FIdentity
An initializer function for a reduction.
Definition reduction.h:263
std::function< ffi::Array< PrimExpr >(ffi::Array< PrimExpr > exprs, const ffi::Array< IterVar > &axis, PrimExpr *condition)> FCommReduce
The operation to use for CommReduceIdx.
Definition reduction.h:51
FCommReduce MakeArgmaxReducer(bool select_last_index=false)
Definition reduction.h:519
PrimExpr MaxOp(PrimExpr source, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
Wrap tvm::max to ensure we get the correct overload.
Definition reduction.h:313
std::function< PrimExpr(PrimExpr source, const ffi::Array< IterVar > &axis, ffi::Array< PrimExpr > init, Span span)> FReduce
The operation to use for CommReduce.
Definition reduction.h:47
Tensor expand_dims(const Tensor &x, int axis, int num_newaxis=1, std::string name="T_expand_dims", std::string tag=kBroadcast)
Creates an operation to insert new dimensions of length 1.
Definition transform.h:156
Tensor prod(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false)
Creates product operation over given axis.
Definition reduction.h:593
Tensor any(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false)
Creates an operation that computes the logical OR of elements over a given axis.
Definition reduction.h:414
Tensor argmin(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false, bool select_last_index=false)
Creates an operation that finds the indices of the minimum values over a given axis.
Definition reduction.h:512
constexpr auto kCommReduceIdx
Definition tags.h:35
PrimExpr MinOp(PrimExpr source, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
Wrap tvm::min to ensure we get the correct overload.
Definition reduction.h:307
FCommReduce MakeArgminReducer(bool select_last_index=false)
Definition reduction.h:457
Tensor identity(const Tensor &x, std::string name="T_identity", std::string tag=kElementWise)
Creates an operation that returns identity of a given tensor.
Definition elemwise.h:154
PrimExpr ProdOp(PrimExpr source, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
Wrap tvm::prod to ensure we get the correct overload.
Definition reduction.h:319
Tensor CommReduceIdx(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, FCommReduce func, bool keepdims, bool atleast1d)
Create an index reduction operation.
Definition reduction.h:210
Tensor CommReduce(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, FReduce func, bool keepdims, bool atleast1d)
Create a reduction operation.
Definition reduction.h:184
Tensor argmax(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false, bool select_last_index=false)
Creates an operation that finds the indices of the maximum values over a given axis.
Definition reduction.h:573
Tensor all(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false)
Creates an operation that computes the logical AND of elements over a given axis.
Definition reduction.h:395
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
PrimExpr max_value(PrimType dtype, Span span=Span())
PrimExpr any(PrimExpr source, ffi::Array< tirx::IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
logical Or of source expression over axis
PrimExpr min_value(PrimType dtype, Span span=Span())
PrimExpr all(PrimExpr source, ffi::Array< tirx::IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
logical And of source expression over axis
PrimExpr prod(PrimExpr source, ffi::Array< tirx::IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
product of source expression over axis
PrimExpr min(PrimExpr a, PrimExpr b, Span span=Span())
take minimum of two values
PrimExpr sum(PrimExpr source, ffi::Array< tirx::IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
sum of source expression over axis
Operation node can generate one or multiple Tensors.
Index ravel and unraval operations.
Tag definitions.
Transform op constructors.