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 {
42using namespace tvm::te;
43
45using FReduce = std::function<PrimExpr(PrimExpr source, const ffi::Array<IterVar>& axis,
46 ffi::Array<PrimExpr> init, Location loc)>;
47
49using FCommReduce = std::function<ffi::Array<PrimExpr>(
50 ffi::Array<PrimExpr> exprs, const ffi::Array<IterVar>& axis, PrimExpr* condition)>;
51
64inline std::vector<int> GetRealAxis(int ndim, const ffi::Optional<ffi::Array<int64_t>>& axis) {
65 std::vector<int> real_axis;
66 if (!axis.has_value()) {
67 for (int i = 0; i < ndim; ++i) {
68 real_axis.push_back(i);
69 }
70 } else {
71 // Use a set so duplicates are removed and the dims are sorted
72 for (int64_t elem : axis.value()) {
73 int64_t val = elem;
74 if (val < 0) {
75 val += ndim;
76 }
77 TVM_FFI_ICHECK_LT(val, ndim) << " exceeds the maximum dimension " << ndim;
78 TVM_FFI_ICHECK_GE(val, 0);
79 real_axis.push_back(static_cast<int>(val));
80 }
81 std::sort(real_axis.begin(), real_axis.end());
82 real_axis.resize(std::unique(real_axis.begin(), real_axis.end()) - real_axis.begin());
83 }
84 return real_axis;
85}
86
88inline ffi::Array<IterVar> MakeReduceAxes(const std::vector<int>& real_axis, const Tensor& data) {
89 ffi::Array<IterVar> reduce_axes;
90 for (auto i : real_axis) {
91 std::string name = "k" + std::to_string(i);
92 reduce_axes.push_back(tvm::te::reduce_axis(Range(0, data->shape[i]), name));
93 }
94 return reduce_axes;
95}
96
98inline ffi::Array<PrimExpr> MakeReduceTargetShape(const std::vector<int>& real_axis,
99 const Tensor& data, bool keepdims,
100 bool atleast1d) {
101 auto ndim = data->shape.size();
102 ffi::Array<PrimExpr> target_shape;
103 if (keepdims) {
104 for (size_t i = 0; i < ndim; ++i) {
105 if (std::find(real_axis.begin(), real_axis.end(), i) != real_axis.end()) {
106 // real_axis contains i
107 target_shape.push_back(1);
108 } else {
109 target_shape.push_back(data->shape[i]);
110 }
111 }
112 } else {
113 for (size_t i = 0; i < ndim; ++i) {
114 if (std::find(real_axis.begin(), real_axis.end(), i) == real_axis.end()) {
115 // real_axis does not contain i
116 target_shape.push_back(data->shape[i]);
117 }
118 }
119 }
120 if (target_shape.size() == 0 && atleast1d) {
121 target_shape.push_back(1);
122 }
123 return target_shape;
124}
125
139inline Tensor DoCommReduce(const Tensor& data, FReduce func,
140 const ffi::Array<PrimExpr>& target_shape,
141 const std::vector<int>& reduce_axes,
142 const std::vector<int>& squeeze_axes, Location loc = UnknownLoc()) {
143 auto r_axes = MakeReduceAxes(reduce_axes, data);
144 auto compute = [&](const ffi::Array<PrimVar>& indices) {
145 ffi::Array<PrimExpr> eval_range;
146 ffi::Array<PrimVar> eval_indices;
147 int arg_counter = 0;
148 int red_counter = 0;
149
150 for (size_t i = 0; i < data->shape.size(); ++i) {
151 bool squeeze_i = std::find(squeeze_axes.begin(), squeeze_axes.end(), i) != squeeze_axes.end();
152 if (std::find(reduce_axes.begin(), reduce_axes.end(), i) != reduce_axes.end()) {
153 // real_axis contains i
154 eval_range.push_back(r_axes[red_counter]);
155 eval_indices.push_back(r_axes[red_counter]->var);
156 red_counter++;
157 arg_counter += !squeeze_i;
158 continue;
159 }
160 eval_range.push_back(indices[arg_counter]);
161 arg_counter++;
162 }
163
164 return func(data(eval_range), r_axes, {}, loc);
165 };
166
167 return tvm::te::compute(target_shape, compute, data->op.value()->name + "_red", kCommReduce);
168}
169
183inline Tensor CommReduce(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
184 FReduce func, bool keepdims, bool atleast1d) {
185 auto ndim = data->shape.size();
186 if (ndim == 0) {
187 auto identity = topi::identity(data, data->op.value()->name + "_red", kCommReduce);
188 return atleast1d ? topi::expand_dims(identity, 0, 1) : identity;
189 }
190 auto real_axis = GetRealAxis(static_cast<int>(ndim), axis);
191 auto target_shape = MakeReduceTargetShape(real_axis, data, keepdims, atleast1d);
192 return DoCommReduce(data, func, target_shape, real_axis,
193 keepdims ? std::vector<int>() : real_axis);
194}
195
209inline Tensor CommReduceIdx(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
210 FCommReduce func, bool keepdims, bool atleast1d) {
211 auto ndim = data->shape.size();
212 TVM_FFI_ICHECK_NE(ndim, 0) << "Cannot reduce a 0 dim Tensor";
213 auto real_axis = GetRealAxis(static_cast<int>(ndim), axis);
214 auto reduce_axes = MakeReduceAxes(real_axis, data);
215 auto target_shape = MakeReduceTargetShape(real_axis, data, keepdims, atleast1d);
216
217 auto compute = [ndim, keepdims, &real_axis, &reduce_axes, &func,
218 &data](const ffi::Array<PrimVar>& indices) {
219 ffi::Array<PrimExpr> eval_range;
220 ffi::Array<PrimExpr> eval_indices;
221 int arg_counter = 0;
222 int red_counter = 0;
223
224 for (size_t i = 0; i < ndim; ++i) {
225 if (std::find(real_axis.begin(), real_axis.end(), i) != real_axis.end()) {
226 // real_axis contains i
227 eval_range.push_back(reduce_axes[red_counter]);
228 eval_indices.push_back(reduce_axes[red_counter]->var);
229 red_counter++;
230 } else {
231 if (!keepdims) {
232 eval_range.push_back(indices[arg_counter]);
233 arg_counter++;
234 } else {
235 eval_range.push_back(indices[i]);
236 }
237 }
238 }
239
240 ffi::Array<PrimExpr> ravel_shape;
241 for (auto i : real_axis) {
242 ravel_shape.push_back(data->shape[i]);
243 }
244 auto idx = detail::RavelIndex(eval_indices, ravel_shape);
245 return func({idx, data(eval_range)}, reduce_axes, nullptr);
246 };
247
248 auto temp_idx_val =
249 tvm::te::compute(target_shape, compute, data->op.value()->name + "_red_temp", kCommReduceIdx);
250 auto temp_idx = temp_idx_val[0];
251 auto temp_val = temp_idx_val[1];
252 return tvm::te::compute(
253 target_shape, [&temp_idx](const ffi::Array<PrimVar>& indices) { return temp_idx(indices); },
254 data->op.value()->name + "_red", kCommReduceIdx);
255}
256
258using FCombine =
259 std::function<ffi::Array<PrimExpr>(ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs)>;
260
262using FIdentity = std::function<ffi::Array<PrimExpr>(std::vector<PrimType> types)>;
263
274 std::string name = "reduce") {
275 return [fcombine, fidentity, name](ffi::Array<PrimExpr> exprs, const ffi::Array<IterVar>& axis,
276 PrimExpr* condition) {
277 ffi::Array<PrimVar> lhs, rhs;
278 ffi::Array<PrimVar> callback_lhs, callback_rhs;
279 std::vector<PrimType> dtypes;
280
281 for (size_t i = 0; i < exprs.size(); ++i) {
282 PrimType dtype = exprs[i].ty();
283 dtypes.push_back(dtype);
284 PrimVar lhs_var(name + "_lhs_" + std::to_string(i), dtype);
285 PrimVar rhs_var(name + "_rhs_" + std::to_string(i), dtype);
286 lhs.push_back(lhs_var);
287 rhs.push_back(rhs_var);
288 callback_lhs.push_back(lhs_var);
289 callback_rhs.push_back(rhs_var);
290 }
291
292 auto result = fcombine(callback_lhs, callback_rhs);
293 auto id_elem = fidentity(dtypes);
294 auto cond = condition != nullptr ? *condition : IntImm::Bool(true);
295
296 auto combiner = tvm::te::CommReducer(lhs, rhs, result, id_elem);
297 ffi::Array<PrimExpr> outputs;
298 for (size_t i = 0; i < exprs.size(); ++i) {
299 outputs.push_back(tvm::te::Reduce(combiner, exprs, axis, cond, static_cast<int>(i), {}));
300 }
301 return outputs;
302 };
303}
304
306inline PrimExpr MinOp(PrimExpr source, ffi::Array<IterVar> axis, ffi::Array<PrimExpr> init = {},
307 Location loc = UnknownLoc()) {
308 return tvm::min(source, axis, init, loc);
309}
310
312inline PrimExpr MaxOp(PrimExpr source, ffi::Array<IterVar> axis, ffi::Array<PrimExpr> init = {},
313 Location loc = UnknownLoc()) {
314 return tvm::max(source, axis, init, loc); // NOLINT(*)
315}
316
318inline PrimExpr ProdOp(PrimExpr source, ffi::Array<IterVar> axis, ffi::Array<PrimExpr> init = {},
319 Location loc = UnknownLoc()) {
320 return tvm::prim::prod(source, axis, init, loc); // NOLINT(*)
321}
322
336inline Tensor sum(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
337 bool keepdims = false, bool atleast1d = false) {
338 // Reduction dispatch only depends on boolean element kind; lane encoding is irrelevant here.
339 if (data->dtype.code() == DLDataTypeCode::kDLBool) {
340 return CommReduce(data, axis, tvm::prim::any, keepdims, atleast1d);
341 } else {
342 return CommReduce(data, axis, tvm::prim::sum, keepdims, atleast1d);
343 }
344}
345
346inline Tensor collapse_sum(const Tensor& data, ffi::Array<PrimExpr> target_shape) {
347 const auto& ishape = data->shape;
348 const auto& oshape = target_shape;
349 int isize = data->shape.size();
350 int osize = target_shape.size();
351
352 TVM_FFI_ICHECK_GE(isize, osize)
353 << "Invalid collapse: input dimensionality smaller than output dimensionality.\ninput shape: "
354 << data->shape << "\nvs\noutput shape: " << target_shape;
355
356 std::vector<int> reduce_axes;
357 std::vector<int> squeeze_axes;
358 tvm::PrimExpr one(1);
359
360 for (int i_ax = isize - 1, o_ax = osize - 1; i_ax >= 0; --i_ax) {
361 if (o_ax >= 0 && topi::detail::EqualCheck(ishape[i_ax], oshape[o_ax])) {
362 --o_ax;
363 continue;
364 }
365 reduce_axes.push_back(i_ax);
366 if (o_ax < 0) { // squeeze o_ax if was added during expansion
367 squeeze_axes.push_back(i_ax);
368 } else if (topi::detail::EqualCheck(one, oshape[o_ax])) {
369 --o_ax;
370 }
371 }
372
373 if (reduce_axes.size() == 0) return topi::identity(data, "tensor", kCommReduce);
374
375 std::reverse(reduce_axes.begin(), reduce_axes.end());
376 std::reverse(squeeze_axes.begin(), squeeze_axes.end());
377 return DoCommReduce(data, tvm::prim::sum, target_shape, reduce_axes, squeeze_axes);
378}
379
394inline Tensor all(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
395 bool keepdims = false, bool atleast1d = false) {
396 return CommReduce(data, axis, tvm::prim::all, keepdims, atleast1d);
397}
398
413inline Tensor any(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
414 bool keepdims = false, bool atleast1d = false) {
415 return CommReduce(data, axis, tvm::prim::any, keepdims, atleast1d);
416}
417
432inline Tensor min(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
433 bool keepdims = false, bool atleast1d = false) {
434 return CommReduce(data, axis, MinOp, keepdims, atleast1d);
435}
436
451inline Tensor max(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
452 bool keepdims = false, bool atleast1d = false) {
453 return CommReduce(data, axis, MaxOp, keepdims, atleast1d);
454}
455
456inline FCommReduce MakeArgminReducer(bool select_last_index = false) {
457 // Create a Commutative Reducer with a comparison operation, and method to get the initial value.
458 auto fcombine = [=](ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs) {
459 ffi::Array<PrimExpr> result;
460
461 // Casting to avoid operator ambiguity
462 PrimExpr lhs_idx = static_cast<PrimExpr>(lhs[0]);
463 PrimExpr rhs_idx = static_cast<PrimExpr>(rhs[0]);
464 PrimExpr lhs_val = static_cast<PrimExpr>(lhs[1]);
465 PrimExpr rhs_val = static_cast<PrimExpr>(rhs[1]);
466
467 // These variables compare the actual values of the array
468 auto is_smaller = lhs_val < rhs_val;
469 auto is_same = lhs_val == rhs_val;
470
471 // This checks if the indices are correct for the reduction. E.g. for select_last_index
472 // it gives precedence for later indices of the same element and precedence for sooner
473 // indices if not select_last_index;
474 PrimExpr proper_index = select_last_index ? lhs_idx > rhs_idx : lhs_idx < rhs_idx;
475
476 PrimExpr update_index = is_smaller || (is_same && proper_index);
477 result.push_back(tvm::prim::Select(update_index, lhs[0], rhs[0])); // idx
478 result.push_back(tvm::prim::Select(is_smaller, lhs[1], rhs[1])); // val
479 return result;
480 };
481 auto fidentity = [&](std::vector<PrimType> types) {
482 ffi::Array<PrimExpr> result;
483 result.push_back(tvm::prim::MakeConst(types[0], -1)); // idx
484 result.push_back(tvm::prim::max_value(types[1])); // val
485 return result;
486 };
487 return MakeCommReducer(fcombine, fidentity, "argmin");
488}
489
506inline Tensor argmin(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
507 bool keepdims = false, bool atleast1d = false,
508 bool select_last_index = false) {
509 auto reducer = MakeArgminReducer(select_last_index);
510 return CommReduceIdx(data, axis, reducer, keepdims, atleast1d);
511}
512
513inline FCommReduce MakeArgmaxReducer(bool select_last_index = false) {
514 // Create a Commutative Reducer with a comparison operation, and method to get the initial value.
515 auto fcombine = [=](ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs) {
516 ffi::Array<PrimExpr> result;
517
518 // Casting to avoid operator ambiguity
519 PrimExpr lhs_idx = static_cast<PrimExpr>(lhs[0]);
520 PrimExpr rhs_idx = static_cast<PrimExpr>(rhs[0]);
521 PrimExpr lhs_val = static_cast<PrimExpr>(lhs[1]);
522 PrimExpr rhs_val = static_cast<PrimExpr>(rhs[1]);
523
524 // These variables compare the actual values of the array
525 auto is_bigger = lhs_val > rhs_val;
526 auto is_same = lhs_val == rhs_val;
527
528 // This checks if the indices are correct for the reduction. E.g. for select_last_index
529 // it gives precedence for later indices of the same element and precedence for sooner
530 // indices if not select_last_index;
531 PrimExpr proper_index = select_last_index ? lhs_idx > rhs_idx : lhs_idx < rhs_idx;
532
533 PrimExpr update_index = is_bigger || (is_same && proper_index);
534 result.push_back(tvm::prim::Select(update_index, lhs[0], rhs[0])); // idx
535 result.push_back(tvm::prim::Select(is_bigger, lhs[1], rhs[1])); // val
536 return result;
537 };
538 auto fidentity = [&](std::vector<PrimType> types) {
539 ffi::Array<PrimExpr> result;
540 result.push_back(tvm::prim::MakeConst(types[0], -1)); // idx
541 result.push_back(tvm::prim::min_value(types[1])); // val
542 return result;
543 };
544 return MakeCommReducer(fcombine, fidentity, "argmax");
545}
546
562inline Tensor argmax(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
563 bool keepdims = false, bool atleast1d = false,
564 bool select_last_index = false) {
565 auto reducer = MakeArgmaxReducer(select_last_index);
566 return CommReduceIdx(data, axis, reducer, keepdims, atleast1d);
567}
568
582inline Tensor prod(const Tensor& data, const ffi::Optional<ffi::Array<int64_t>>& axis,
583 bool keepdims = false, bool atleast1d = false) {
584 return CommReduce(data, axis, ProdOp, keepdims, atleast1d);
585}
586
591 auto fcombine = [](ffi::Array<PrimVar> lhs, ffi::Array<PrimVar> rhs) {
592 ffi::Array<PrimExpr> result;
593 TVM_FFI_ICHECK_EQ(lhs.size(), rhs.size());
594 result.reserve(lhs.size());
595 for (size_t i = 0; i < lhs.size(); ++i) {
596 result.push_back(lhs[i] + rhs[i]);
597 }
598 return result;
599 };
600 auto fidentity = [](std::vector<PrimType> types) {
601 ffi::Array<PrimExpr> result;
602 for (size_t i = 0; i < types.size(); ++i) {
603 result.push_back(tvm::prim::MakeConst(types[i], 0));
604 }
605 return result;
606 };
607 return MakeCommReducer(fcombine, fidentity, "tuple_sum");
608}
609
610} // namespace topi
611} // namespace tvm
612#endif // TVM_TOPI_REDUCTION_H_
Broadcast op constructions.
static IntImm Bool(bool value, Location loc=UnknownLoc())
Construct a scalar boolean constant.
Definition expr.h:172
Non-nullable source-location metadata.
Definition location.h:91
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:447
Definition base_expr.h:161
Checked scalar view over a VarNode.
Definition expr.h:742
Range container
Definition expr.h:1025
Reference to the shared immutable unknown location.
Definition location.h:105
Managed reference to SelectNode.
Definition expr.h:712
Managed reference to CommReducerNode.
Definition operation.h:91
Managed reference to ReduceNode.
Definition operation.h:139
Tensor structure representing a possible input, or intermediate computation result.
Definition tensor.h:111
Utility functions for handling constants in TVM expressions.
Elementwise op constructions.
TVM_TIRX_DLL PrimExpr min_value(PrimType dtype, Location loc=UnknownLoc())
PrimExpr all(PrimExpr source, ffi::Array< s_tir::IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
logical And of source expression over axis
PrimExpr prod(PrimExpr source, ffi::Array< s_tir::IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
product of source expression over axis
TVM_TIRX_DLL PrimExpr max_value(PrimType dtype, Location loc=UnknownLoc())
PrimExpr sum(PrimExpr source, ffi::Array< s_tir::IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
sum of source expression over axis
PrimExpr MakeConst(PrimType dtype, ValueType value, Location loc=UnknownLoc())
Make a const value with certain data type.
Definition op.h:553
PrimExpr any(PrimExpr source, ffi::Array< s_tir::IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
logical Or of source expression over axis
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...
Tensor collapse_sum(const Tensor &data, ffi::Array< PrimExpr > target_shape)
Definition reduction.h:346
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:98
std::function< ffi::Array< PrimExpr >(ffi::Array< PrimVar > lhs, ffi::Array< PrimVar > rhs)> FCombine
A combiner function for a reduction.
Definition reduction.h:259
ffi::Array< IterVar > MakeReduceAxes(const std::vector< int > &real_axis, const Tensor &data)
Enumerate the axes for a reduce op.
Definition reduction.h:88
FCommReduce MakeTupleSumReducer()
Create communitive reducer summing over tuples.
Definition reduction.h:590
PrimExpr MinOp(PrimExpr source, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
Wrap tvm::min to ensure we get the correct overload.
Definition reduction.h:306
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:64
FCommReduce MakeCommReducer(FCombine fcombine, FIdentity fidentity, std::string name="reduce")
Create a commutative reducer for a reduction.
Definition reduction.h:273
std::function< ffi::Array< PrimExpr >(std::vector< PrimType > types)> FIdentity
An initializer function for a reduction.
Definition reduction.h:262
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:50
Tensor sum(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false)
Creates an operation that sums array elements over a given axis.
Definition reduction.h:336
Tensor min(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false)
Creates an operation that finds the minimum of elements over a given axis.
Definition reduction.h:432
std::function< PrimExpr(PrimExpr source, const ffi::Array< IterVar > &axis, ffi::Array< PrimExpr > init, Location loc)> FReduce
The operation to use for CommReduce.
Definition reduction.h:46
FCommReduce MakeArgmaxReducer(bool select_last_index=false)
Definition reduction.h:513
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, Location loc=UnknownLoc())
Create a reduction operation.
Definition reduction.h:139
PrimExpr ProdOp(PrimExpr source, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
Wrap tvm::prim::prod to ensure we get the correct overload.
Definition reduction.h:318
Tensor max(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false)
Creates an operation that finds the maximum of elements over a given axis.
Definition reduction.h:451
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:155
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:582
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:413
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:506
constexpr auto kCommReduceIdx
Definition tags.h:35
FCommReduce MakeArgminReducer(bool select_last_index=false)
Definition reduction.h:456
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
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:209
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:183
PrimExpr MaxOp(PrimExpr source, ffi::Array< IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
Wrap tvm::max to ensure we get the correct overload.
Definition reduction.h:312
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:562
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:394
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition attr.h:23
TVM_TIRX_DLL PrimExpr max(PrimExpr a, PrimExpr b, Location loc=UnknownLoc())
take maximum of two values
TVM_TIRX_DLL PrimExpr min(PrimExpr a, PrimExpr b, Location loc=UnknownLoc())
take minimum of two values
Operation node can generate one or multiple Tensors.
Index ravel and unraval operations.
Tag definitions.
Transform op constructors.