24#ifndef TVM_TOPI_TRANSFORM_H_
25#define TVM_TOPI_TRANSFORM_H_
44#include <unordered_set>
48#include "tvm/ffi/dtype.h"
57using namespace topi::detail;
77 ffi::Array<int64_t> strides, std::string name =
"T_sliding_window",
78 std::string tag =
"") {
83 <<
"There must be a window shape for every dimension of x "
84 <<
"over which we are sliding the window.";
86 <<
"Windows and strides should be the same length.";
117 [&](
const ffi::Array<PrimVar>& indices) {
119 ffi::Array<PrimExpr>
idx;
122 for (
size_t i = 0;
i <
_axis; ++
i) {
123 idx.push_back(indices[
i]);
157 std::string name =
"T_expand_dims", std::string tag =
kBroadcast) {
158 int ndim =
static_cast<int>(
x->shape.size());
160 <<
"expand_dims only accepts `axis` in [-data.ndim - 1, data.ndim]"
161 <<
", but got axis = " << axis <<
", and data.ndim = " << ndim;
166 axis = ndim + axis + 1;
175 for (
size_t i = axis;
i <
x->shape.size(); ++
i) {
181 [&](
const ffi::Array<PrimVar>& indices) {
182 ffi::Array<PrimExpr>
idx;
184 idx.push_back(indices[
i]);
187 idx.push_back(indices[
i]);
206 std::string name =
"T_transpose", std::string tag =
kInjective) {
207 ffi::Array<int64_t> axes =
opt_axes.value_or({});
208 if (axes.size() == 0) {
209 for (
int i =
static_cast<int>(
x->shape.size()) - 1;
i >= 0; --
i) {
215 for (
size_t i = 0;
i < axes.size(); ++
i) {
216 int axis =
static_cast<int>(axes[
i]);
219 new_axis =
static_cast<int>(
x->shape.size()) + axis;
223 <<
"axis=" << axis <<
" is invalid for the " <<
static_cast<int>(
x->shape.size())
224 <<
"-dimensional input tensor";
226 for (
size_t j = 0;
j < axes.size(); ++
j) {
236 [&](
const ffi::Array<PrimVar>& indices) {
237 std::vector<PrimExpr>
idx;
238 for (
size_t i = 0;
i < axes.size(); ++
i) {
241 for (
size_t i = 0;
i < axes.size(); ++
i) {
242 int axis =
static_cast<int>(axes[
i]);
243 idx[axis] = indices[
i];
265 int batch_axis = 0, std::string name =
"T_reverse_sequence",
273 if (batch_axis < 0) {
274 batch_axis =
static_cast<int>(
x->shape.size()) + batch_axis;
280 <<
"For reverse_sequnece seq_lengths size should match with dimension of batch axis"
281 <<
", but got dimension of batch_axis = " << GetConstInt(
x->shape[batch_axis])
282 <<
", and seq_length size = " << GetConstInt(
seq_lengths->shape[0]);
284 TVM_FFI_ICHECK((0 <= batch_axis) && (batch_axis <
static_cast<int>(
x->shape.size())))
286 <<
static_cast<int>(
x->shape.size()) <<
"-dimensional input tensor";
290 seq_axis =
static_cast<int>(
x->shape.size()) + seq_axis;
292 TVM_FFI_ICHECK((0 <= seq_axis) && (seq_axis <
static_cast<int>(
x->shape.size())))
293 <<
"seq_axis=" <<
seq_axis_inp <<
" is invalid for the " <<
static_cast<int>(
x->shape.size())
294 <<
"-dimensional input tensor";
296 auto func = [&](
const ffi::Array<PrimVar>& indices) {
299 if (
i ==
static_cast<size_t>(seq_axis)) {
303 len <= 1 ||
len <= indices[
i], indices[
i],
316 return compute(
x->shape, func, name, tag);
330 std::string name =
"T_reshape", std::string tag =
kInjective) {
339 if (is_empty_shape(
target_shape) || is_empty_shape(
x->shape)) {
342 [&](
const ffi::Array<PrimVar>& indices) {
return tvm::cast(
PrimType(
x->dtype), 0); }, name,
347 [&](
const ffi::Array<PrimVar>& indices) {
372 ffi::Array<PrimExpr>
oshape;
378 auto func = [&](
const ffi::Array<PrimVar>& indices) {
416 bool atleast1d =
false, std::string name =
"T_squeeze",
418 auto ndim =
x->shape.size();
421 for (
size_t i = 0;
i < ndim; ++
i) {
422 if (IsConstInt(
x->shape[
i]) && GetConstInt(
x->shape[
i]) == 1) {
427 ffi::Array<int64_t> axis = *std::move(
opt_axes);
428 for (
size_t i = 0;
i < axis.size(); ++
i) {
431 val +=
static_cast<int>(
x->shape.size());
444 for (
size_t i = 0;
i < ndim; ++
i) {
445 if (
axis_set.count(
static_cast<int>(
i)) == 0) {
455 [&](
const ffi::Array<PrimVar>& indices) {
458 for (
size_t i = 0;
i < ndim; ++
i) {
459 if (
axis_set.count(
static_cast<int>(
i)) == 0) {
460 real_indices.push_back(indices[i - flag]);
462 real_indices.push_back(0);
482 std::string name =
"T_concat", std::string tag =
kInjective) {
483 int ndim =
static_cast<int>(inputs[0]->shape.size());
485 <<
"concatenate only accepts `axis` in [-ndim, ndim)"
486 <<
", but got axis = " << axis <<
", and ndim = " << ndim;
493 for (
auto t : inputs) {
503 for (
size_t i = 0;
i < inputs[0]->shape.size(); ++
i) {
509 [&](
const ffi::Array<PrimVar>& indices) {
510 auto ret = inputs[0](indices);
512 for (
size_t i = 0;
i < inputs.size() - 1; ++
i) {
515 ffi::Array<PrimExpr>
idx;
517 idx.push_back(indices[
i]);
520 for (
size_t i = axis + 1;
i < indices.size(); ++
i) {
521 idx.push_back(indices[
i]);
541inline Tensor stack(
const ffi::Array<Tensor>& inputs,
int axis = 0, std::string name =
"T_stack",
543 int ndim =
static_cast<int>(inputs[0]->shape.size());
545 <<
"stack only accepts `axis` in [-ndim, ndim)"
546 <<
", but got axis = " << axis <<
", and ndim = " << ndim;
552 const int stack_size =
static_cast<int>(inputs.size());
561 [&](
const ffi::Array<PrimVar>& indices) {
562 ffi::Array<PrimExpr>
idx;
563 for (
size_t i = 0;
i < indices.size(); ++
i)
564 if (
i !=
static_cast<size_t>(axis))
idx.push_back(indices[
i]);
565 auto ind = indices[axis];
566 auto ret = inputs[0](
idx);
588 int axis, std::string name =
"T_split",
591 axis +=
static_cast<int>(
x->shape.size());
617 ffi::Array<PrimExpr>
shape;
622 for (
size_t i = axis + 1;
i <
x->shape.size(); ++
i) {
629 ffi::Array<Tensor> result;
633 [&](
const ffi::Array<PrimVar>& indices) {
640 for (
size_t j = axis + 1;
j < indices.size(); ++
j) {
663 if (!(index->IsInstance<
tvm::IntImmNode>() && GetConstInt(index) >= 0)) {
690 bool assume_inbound =
true) {
691 if (assume_inbound) {
694 begin = CanonicalizeIndex(
begin, extent, stride);
695 end = CanonicalizeIndex(
end, extent, stride);
718 const ffi::Array<PrimExpr>& strides,
const ffi::Array<int64_t>& axes,
719 bool assume_inbound =
true, std::string name =
"T_dynamic_strided_slice_with_axes",
728 int axis =
static_cast<int>(
axis_imm);
735 for (
size_t i = 0;
i <
begin.size();
i++) {
736 int axis =
static_cast<int>(axes[
i]);
744 [&](
const ffi::Array<tvm::tirx::PrimVar>& indices) {
748 for (
size_t i = 0;
i <
begin.size();
i++) {
749 int axis =
static_cast<int>(axes[
i]);
774 const ffi::Array<PrimExpr>&
end,
775 const ffi::Array<PrimExpr>& strides,
bool assume_inbound =
true,
776 std::string name =
"T_dynamic_strided_slice",
805 [&](
const ffi::Array<tvm::tirx::PrimVar>& indices) {
835 bool assume_inbound =
true,
836 std::string name =
"T_strided_slice_dynamic",
867inline ffi::Array<PrimExpr> StridedSliceOutputShape(
const ffi::Array<PrimExpr>&
ishape,
868 const ffi::Array<ffi::Optional<IntImm>>&
begin,
869 const ffi::Array<ffi::Optional<IntImm>>&
end,
870 const ffi::Array<IntImm>& strides,
871 const ffi::Array<int64_t>& axes,
874 axes.size() == strides.size());
902 const Tensor&
x,
const ffi::Array<ffi::Optional<IntImm>>&
begin,
903 const ffi::Array<ffi::Optional<IntImm>>&
end,
const ffi::Array<IntImm>& strides,
904 const ffi::Array<int64_t>& axes, std::string
slice_mode =
"end",
905 std::string name =
"T_strided_slice_with_axes", std::string tag =
kInjective) {
909 axes.size() == strides.size());
913 for (
size_t i = 0;
i < axes.size(); ++
i) {
919 <<
"Axis " << axes[
i] <<
" is out of bounds for tensor with " <<
src_tensor_dim
936 [&](
const ffi::Array<tirx::PrimVar>& indices) {
965 const ffi::Array<ffi::Optional<IntImm>>&
end,
966 const ffi::Array<IntImm>& strides, std::string
slice_mode =
"end",
967 std::string name =
"T_strided_slice", std::string tag =
kInjective) {
969 ffi::Array<int64_t> axes;
1008 std::string name =
"T_split_sections",
1011 axis +=
static_cast<int>(
x->shape.size());
1044 std::string mode =
"fast", std::string name =
"T_take",
1046 ffi::Array<PrimExpr>
a_shape = a->shape;
1047 ffi::Array<PrimExpr>
out_shape = indices->shape;
1049 for (
size_t i = 0;
i <
a_shape.size(); ++
i) {
1053 if (mode ==
"clip") {
1056 [&](
const ffi::Array<PrimVar>&
out_index) {
1061 }
else if (mode ==
"fast") {
1062 LOG(
WARNING) <<
"Fast mode segfaults when there are out-of-bounds indices. "
1063 "Make sure input indices are in bound";
1066 [&](
const ffi::Array<PrimVar>&
out_index) {
1070 }
else if (mode ==
"nan") {
1073 [&](
const ffi::Array<PrimVar>&
out_index) {
1084 [&](
const ffi::Array<PrimVar>&
out_index) {
1105 int axis, std::string name =
"T_sequence_mask",
1107 TVM_FFI_ICHECK(axis == 0 || axis == 1) <<
"axis must be either 0 or 1";
1109 <<
"valid_length must have ndim=1, i.e., (batch_size,).";
1112 ffi::Array<PrimExpr>
out_shape = data->shape;
1115 [&](
const ffi::Array<PrimVar>&
out_index) {
1144 int axis, std::string mode =
"fast", std::string name =
"T_take",
1147 axis +=
static_cast<int>(a->shape.size());
1153 if (
auto tensor = indices.as<
TensorNode>()) {
1154 return tensor->shape;
1174 auto addr1 = a->shape[
i];
1196 for (
size_t i = axis + 1;
i < a->shape.size(); ++
i) {
1201 if (
auto tensor = indices.as<
Tensor>()) {
1203 }
else if (
auto prim = indices.as<
PrimExpr>()) {
1205 return prim.value();
1211 if (mode ==
"clip") {
1215 [&](
const ffi::Array<PrimVar>&
out_index) {
1235 [&](
const ffi::Array<PrimVar>&
out_index) {
1256 }
else if (mode ==
"fast") {
1257 LOG(
WARNING) <<
"Fast mode segfaults when there are out-of-bounds indices. "
1258 "Make sure input indices are in bound";
1261 [&](
const ffi::Array<PrimVar>&
out_index) {
1277 }
else if (mode ==
"nan") {
1280 [&](
const ffi::Array<PrimVar>&
out_index) {
1303 [&](
const ffi::Array<PrimVar>&
out_index) {
1335 std::string name =
"T_where", std::string tag =
kBroadcast) {
1337 <<
"x and y must have the same dtype: " <<
x->dtype <<
" vs " <<
y->dtype;
1339 auto bh1 = detail::BroadcastShape(
x->shape,
y->shape);
1348 auto c_bh = detail::BroadcastShape(condition->shape,
oshape);
1349 auto x_bh = detail::BroadcastShape(
x->shape,
oshape);
1350 auto y_bh = detail::BroadcastShape(
y->shape,
oshape);
1352 auto select = [&](tvm::ffi::Array<tvm::tirx::PrimVar>
ovars) {
1353 auto c = condition(InputIndexFromBroadcast(
ovars, condition,
c_bh.vars1,
c_bh.all_vars));
1376 int ndim =
static_cast<int>(
x->shape.size());
1378 <<
"repeat only accepts `axis` in [-data.ndim - 1, data.ndim]"
1379 <<
", but got axis = " << axis <<
", and data.ndim = " << ndim;
1380 TVM_FFI_ICHECK(repeats >= 1) <<
"repeat only accepts `repeats >= 1`"
1381 <<
", but got repeats = " << repeats;
1390 new_shape.push_back(repeats *
x->shape[axis]);
1391 for (
size_t i = axis + 1;
i <
x->shape.size(); ++
i) {
1397 [&](
const ffi::Array<PrimVar>& indices) {
1398 ffi::Array<PrimExpr>
idx;
1400 idx.push_back(indices[
i]);
1403 for (
size_t i = axis + 1;
i < indices.size(); ++
i) {
1404 idx.push_back(indices[
i]);
1423 size_t ndim =
x->shape.size();
1430 for (
size_t i = 0;
i < ndim; ++
i) {
1434 }
else if (ndim >
rdim) {
1448 [&](
const ffi::Array<PrimVar>& indices) {
return tvm::cast(
PrimType(
x->dtype), 0); }, name,
1453 [&](
const ffi::Array<PrimVar>& indices) {
1454 ffi::Array<PrimExpr>
idx;
1456 for (
size_t i = 0;
i < ndim; ++
i)
idx.push_back(
indexmod(indices[
i],
x->shape[
i]));
1458 for (
size_t i = 0;
i < ndim; ++
i)
1479 std::string name =
"T_tile", std::string tag =
kBroadcast) {
1480 size_t ndim =
x->shape.size();
1484 [&](
const ffi::Array<PrimVar>& indices) {
return tvm::cast(
PrimType(
x->dtype), 0); }, name,
1489 [&](
const ffi::Array<PrimVar>& indices) {
1490 ffi::Array<PrimExpr>
idx;
1492 for (
size_t i = 0;
i < ndim; ++
i) {
1496 for (
size_t i = 0;
i < ndim; ++
i) {
1518 std::string name =
"T_gather", std::string tag =
kInjective) {
1519 size_t ndim_d = data->shape.size();
1520 size_t ndim_i = indices->shape.size();
1529 size_t indices_dim_i =
static_cast<size_t>(GetConstInt(indices->shape[axis]));
1543 [&](
const ffi::Array<PrimVar>&
out_index) {
1550 if (
i ==
static_cast<size_t>(axis)) {
1573 std::string name =
"T_gather_nd", std::string tag =
kInjective) {
1574 size_t ndim_d = data->shape.size();
1575 size_t ndim_i = indices->shape.size();
1577 size_t indices_dim0 =
static_cast<size_t>(GetConstInt(indices->shape[0]));
1579 <<
"than dimensions of data tensor";
1589 [&](
const ffi::Array<PrimVar>&
out_index) {
1592 for (
size_t i = 0;
i <
ndim_i - 1; ++
i) {
1604 if (
indices_ty.MatchesCode(DLDataTypeCode::kDLInt, DLDataTypeCode::kDLUInt)) {
1638 std::string name =
"T_matmul", std::string tag =
kMatMul) {
1639 tvm::ffi::Array<tvm::PrimExpr> output_shape{A->shape[
trans_a ? 1 : 0],
B->shape[
trans_b ? 0 : 1]};
1659 std::string name =
"T_tensordot", std::string tag =
kMatMul) {
1663 ffi::Array<PrimExpr> output_shape(A->shape.begin(), A->shape.end() + (-axes));
1664 for (
auto it =
B->shape.begin() + axes;
it !=
B->shape.end(); ++
it) output_shape.push_back(*
it);
1666 ffi::Array<IterVar> iter_vars;
1667 for (
int i = 0;
i < axes; ++
i)
1670 auto func = [&A, &
B, &iter_vars, axes](
const ffi::Array<PrimVar>&
input_indices) {
1687 if (iter_vars.empty()) {
1694 return compute(output_shape, func, name, tag);
1710 ffi::Array<PrimExpr>
B_axes, std::string name =
"T_tensordot",
1717 ffi::Array<PrimExpr> output_shape;
1718 for (
unsigned i = 0;
i < A->shape.size(); ++
i)
1720 output_shape.push_back(A->shape[
i]);
1721 for (
unsigned i = 0;
i <
B->shape.size(); ++
i)
1723 output_shape.push_back(
B->shape[
i]);
1725 ffi::Array<IterVar> iter_vars;
1733 for (
unsigned i = 0;
i < A->shape.size(); ++
i) {
1743 for (
unsigned i = 0;
i <
B->shape.size(); ++
i) {
1753 return compute(output_shape, func, name, tag);
1764 stop_ty.code() == DLDataTypeCode::kDLInt &&
1765 step_ty.code() == DLDataTypeCode::kDLInt;
1781 [&](
const ffi::Array<PrimVar>& indices) {
1782 return tvm::cast(dtype, start + step * indices[0]);
1797inline ffi::Array<Tensor>
meshgrid(
const ffi::Array<Tensor>& inputs,
const std::string& indexing,
1798 std::string name =
"T_meshgrid", std::string tag =
kInjective) {
1801 for (
size_t i = 0;
i < inputs.size(); ++
i) {
1805 ffi::Array<Tensor> result;
1806 for (
size_t i = 0;
i < inputs.size(); ++
i) {
1809 [&](
const ffi::Array<PrimVar>& indices) {
1811 auto ndim = inputs[
i]->GetShape().size();
1834 const std::string& dst_layout,
1836 const std::string name =
"T_layout_trans",
1846 <<
"cannot convert from/to undefined layout";
1850 <<
"cannot convert from " << src_layout <<
" to " << dst_layout;
1854 ffi::Map<ffi::String, ffi::Any> attrs = {{
"schedule_rule", ffi::String(
schedule_rule)},
1856 {
"src_layout", ffi::String(src_layout)},
1857 {
"dst_layout", ffi::String(dst_layout)},
1858 {
"input_shape", src->shape}};
1867 for (
size_t i = 0;
i < src.ndim(); ++
i) {
1878 std::vector<std::string>* axes) {
1880 std::string axis =
"";
1881 for (
char c : std::string(layout)) {
1882 if (
c >=
'A' &&
c <=
'z') {
1888 }
else if (
c >=
'0' &&
c <=
'9') {
1890 if (!axis.empty()) {
1891 axes->push_back(axis);
1898 if (!axis.empty()) {
1899 axes->push_back(axis);
1914 const Tensor& src,
const ffi::String& src_layout,
const ffi::String& dst_layout,
1915 const ffi::String name =
"T_auto_scheduler_layout_trans",
const ffi::String tag =
kInjective) {
1982 const ffi::String name =
"T_meta_schedule_layout_trans",
const ffi::String tag =
kInjective) {
1994 ffi::Array<PrimExpr> prim_indices =
1995 indices.Map([](const PrimVar& var) { return var.as_or_throw<PrimExpr>(); });
2010 const std::string tag = kInjective) {
2011 int ndim =
static_cast<int>(src->shape.size());
2015 [&](
const ffi::Array<PrimVar>& indices) {
2016 auto idx = indices[0];
2018 for (
int i = 0;
i < ndim; ++
i) {
2027 const std::string tag = kInjective) {
2040 const std::string& name =
"tensor_size",
2041 const std::string& tag = kInjective) {
2042 int ndim =
static_cast<int>(src->shape.size());
2046 [&](
const ffi::Array<PrimVar>& indices) {
2048 for (
int i = 0;
i < ndim; ++
i) {
2049 ret *= src->shape[
i];
2057 const std::string& name =
"tensor_size",
2058 const std::string& tag = kInjective) {
2077 int depth,
int axis,
PrimType dtype,
2078 ffi::Array<PrimExpr>
oshape = ffi::Array<PrimExpr>(),
2079 const std::string name =
"T_one_hot",
const std::string tag = kInjective) {
2080 int true_axis = (axis == -1) ? indices->shape.size() : axis;
2081 if (
oshape.size() == 0) {
2082 int ndim = indices->shape.size() + 1;
2084 for (
int i = 0;
i < ndim;
i++) {
2097 [&](
const ffi::Array<PrimVar>& iter_vars) {
2099 for (
size_t i = 0;
i < iter_vars.size();
i++) {
2116 ffi::Array<PrimExpr>
oshape = ffi::Array<PrimExpr>(),
2117 const std::string name =
"T_one_hot",
const std::string tag = kInjective) {
2135 const std::string name =
"T_sparse_to_dense",
2136 const std::string tag = kInjective) {
2139 <<
"sparse_indices only accepts integer values";
2141 <<
"sparse_indices tensor should be 0D, 1D, or 2D only";
2143 <<
"sparse_values tensor should be 0D or 1D only";
2146 ffi::Array<PrimExpr>
oshape;
2147 for (
auto l : output_shape) {
2152 [&](
const ffi::Array<PrimVar>& indices) {
2165 for (
int k = 0; k < GetConstInt(
sparse_indices->shape[1]); k++) {
2191 const std::string name =
"T_matrix_set_diag",
2192 const std::string tag = kInjective) {
2193 size_t ndim =
input->shape.size() - 1;
2199 [&](
const ffi::Array<PrimVar>& iter_vars) {
2200 auto get_diag = [&]() {
2201 ffi::Array<PrimExpr> diagonal_indices;
2202 PrimExpr k, offset = 0;
2203 for (size_t i = 0; i < ndim - 1; i++) {
2204 diagonal_indices.push_back(iter_vars[i]);
2206 if (only_one_diagonal) {
2210 k = iter_vars[ndim] - iter_vars[ndim - 1];
2211 diagonal_indices.push_back(k2 - k);
2214 auto get_offset = [&](PrimExpr M, PrimExpr N) {
2216 return diagonal->shape[diagonal->shape.size() - 1] - if_then_else(M < N, M, N);
2218 offset = if_then_else(
2220 super_diag_right_align ? get_offset(input->shape[ndim] - k, input->shape[ndim - 1])
2222 sub_diag_right_align ? get_offset(input->shape[ndim], input->shape[ndim - 1] + k)
2225 diagonal_indices.push_back(if_then_else(k >= 0, iter_vars[ndim - 1], iter_vars[ndim]) +
2227 return diagonal(diagonal_indices);
2246 const std::string name =
"advanced_index",
2247 const std::string tag = kInjective) {
2248 TVM_FFI_ICHECK_LE(indices.size(), data->shape.size()) <<
"too many indices for data!";
2249 ffi::Array<PrimExpr>
oshape;
2254 for (
size_t i = 1;
i < indices.size(); ++
i) {
2258 if (indices.size() == 1) {
2263 for (
size_t i = 0;
i < indices.size(); ++
i) {
2271 for (
size_t i = indices.size();
i < data->shape.size(); ++
i) {
2272 oshape.push_back(data->shape[
i]);
2277 [&](
const ffi::Array<PrimVar>& iter_var) {
2299 ffi::Array<PrimExpr> output_shape,
2300 std::string name =
"T_strided_slice_dynamic",
2301 std::string tag = kInjective) {
2318 [&](
const ffi::Array<tvm::tirx::PrimVar>& indices) {
2321 auto ind = IntImm::Int64(
i);
Algebra expression simplifications.
Broadcast op constructions.
Managed reference class to FloatImmNode.
Definition expr.h:567
Constant integer literals in the program.
Definition expr.h:487
int64_t value
the Internal value.
Definition expr.h:490
Managed reference class to IntImmNode.
Definition expr.h:504
static IntImm Int32(int64_t value, Span span=Span())
Construct a scalar int32 constant.
Definition expr.h:528
static IntImm Int64(int64_t value, Span span=Span())
Construct a scalar int64 constant.
Definition expr.h:537
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
Definition base_expr.h:137
static PrimType Float(int bits, int lanes=1)
Construct a floating-point type with fixed lanes.
static PrimType Int(int bits, int lanes=1)
Construct a signed integer type with fixed lanes.
Range container
Definition expr.h:610
static Range FromMinExtent(PrimExpr min, PrimExpr extent, Span span=Span())
construct a new range with min and extent The corresponding constructor is removed,...
ExpectedType ty() const
Definition base_expr.h:380
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Managed reference to AnalyzerObj.
Definition analyzer.h:931
Managed reference to SelectNode.
Definition expr.h:525
Managed Tensor. The array is backed by reference counted blocks.
Definition tensor.h:49
Opaque construction-time node that represents a tensor.
Definition tensor.h:70
Tensor structure representing a possible input, or intermediate computation result.
Definition tensor.h:98
size_t ndim() const
Definition tensor.h:220
Definition index_map.h:192
IndexMap Inverse(ffi::Array< Range > initial_ranges) const
Generate the inverse mapping using a fresh analyzer.
Checked scalar view over a VarNode.
Definition var.h:46
Bijective function mapping for data layout transformation. Given two SLayout, SBijectiveLayout build ...
Definition data_layout.h:386
Managed reference to SLayoutNode.
Definition data_layout.h:126
Utility functions for handling constants in TVM expressions.
SLayout expression to describe the data organization of a tensor. And SBijectiveLayout to mapping two...
Defines a remapping of buffer indices.
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.
bool IsTensorLoad(const Expr &expr)
Return whether an expression is a Call whose callee is a TE Tensor.
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...
DLDataType DefaultIndexType()
Definition buffer.h:52
PrimExpr MakeConst(PrimType dtype, ValueType value, Span span=Span())
Make a const value with certain data type.
Definition op.h:1002
PrimExpr GetLength(PrimExpr begin, PrimExpr end, PrimExpr stride, PrimExpr extent, bool assume_inbound=true)
Definition transform.h:689
Tensor sequence_mask(const Tensor &data, const Tensor &valid_length, double mask_value, int axis, std::string name="T_sequence_mask", std::string tag=kInjective)
Mask the out-of-boundary elements of each sequence.
Definition transform.h:1104
Tensor gather_nd(const Tensor &data, const Tensor &indices, int batch_dims=0, std::string name="T_gather_nd", std::string tag=kInjective)
Gather elements from a n-dimension array.
Definition transform.h:1572
int64_t StaticCanonicalizeIndex(int64_t index, int64_t extent, int64_t stride)
Definition transform.h:670
Tensor reshape(const Tensor &x, ffi::Array< PrimExpr > newshape, std::string name="T_reshape", std::string tag=kInjective)
Reshape a tensor.
Definition transform.h:329
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:2009
tvm::te::Tensor broadcast_to(const tvm::te::Tensor &t, const tvm::ffi::Array< tvm::PrimExpr > &output_shape, std::string name="T_broadcast_to", std::string tag=kBroadcast)
Creates an operation that broadcasts a tensor into a compatible shape according to numpy's rules.
Definition broadcast.h:48
constexpr auto kBroadcast
Definition tags.h:36
constexpr auto kInjective
Definition tags.h:33
Tensor stack(const ffi::Array< Tensor > &inputs, int axis=0, std::string name="T_stack", std::string tag=kInjective)
Join a sequence of tensors along a new axis.
Definition transform.h:541
Tensor arange(const PrimExpr &start, const PrimExpr &stop, const PrimExpr &step, PrimType dtype, std::string name="T_arange", std::string tag=kInjective)
Definition transform.h:1756
Tensor strided_slice(const Tensor &x, const ffi::Array< ffi::Optional< IntImm > > &begin, const ffi::Array< ffi::Optional< IntImm > > &end, const ffi::Array< IntImm > &strides, std::string slice_mode="end", std::string name="T_strided_slice", std::string tag=kInjective)
strided_slice of a tensor
Definition transform.h:964
Tensor auto_scheduler_layout_transform(const Tensor &src, const ffi::String &src_layout, const ffi::String &dst_layout, const ffi::String name="T_auto_scheduler_layout_trans", const ffi::String tag=kInjective)
Transform the auto-scheduler generated layout according to src_layout and dst_layout.
Definition transform.h:1913
Tensor squeeze(const Tensor &x, ffi::Optional< ffi::Array< int64_t > > opt_axes, bool atleast1d=false, std::string name="T_squeeze", std::string tag=kInjective)
Remove size 1 dimensions from the shape of a tensor. The removed dimensions must have a constant size...
Definition transform.h:415
ffi::Array< Tensor > meshgrid(const ffi::Array< Tensor > &inputs, const std::string &indexing, std::string name="T_meshgrid", std::string tag=kInjective)
Produce grids by expanding input over dimensions defined by other inputs.
Definition transform.h:1797
void parse_auto_scheduler_layout(const ffi::String &layout, ffi::Array< PrimExpr > *shape, std::vector< std::string > *axes)
Utility function for auto_scheduler_layout_transform.
Definition transform.h:1877
Tensor strided_slice_with_axes(const Tensor &x, const ffi::Array< ffi::Optional< IntImm > > &begin, const ffi::Array< ffi::Optional< IntImm > > &end, const ffi::Array< IntImm > &strides, const ffi::Array< int64_t > &axes, std::string slice_mode="end", std::string name="T_strided_slice_with_axes", std::string tag=kInjective)
strided_slice of a tensor
Definition transform.h:901
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 sparse_to_dense(const Tensor &sparse_indices, const ffi::Array< PrimExpr > &output_shape, const Tensor &sparse_values, const PrimExpr &default_value, const std::string name="T_sparse_to_dense", const std::string tag=kInjective)
Get a dense tensor.
Definition transform.h:2132
Tensor sliding_window(const Tensor &x, int axis, ffi::Array< int64_t > window_shape, ffi::Array< int64_t > strides, std::string name="T_sliding_window", std::string tag="")
Creates an operation to slide a window over the input x.
Definition transform.h:76
Tensor unravel_index(const Tensor &x, const Tensor &shape, std::string name="T_unravel", std::string tag=kInjective)
Converts a flat index or array of flat indices into a tuple of coordinate arrays.
Definition transform.h:367
Tensor layout_transform(const Tensor &src, const std::string &src_layout, const std::string &dst_layout, const std::string schedule_rule="None", const std::string name="T_layout_trans", const std::string tag=kInjective)
Transform the layout according to src_layout and dst_layout.
Definition transform.h:1833
Tensor adv_index(const Tensor &data, const ffi::Array< Tensor > &indices, const std::string name="advanced_index", const std::string tag=kInjective)
Numpy style advanced indexing with tensor.
Definition transform.h:2245
Tensor concatenate(const ffi::Array< Tensor > &inputs, int axis=0, std::string name="T_concat", std::string tag=kInjective)
Join a sequence of tensors along an existing axis.
Definition transform.h:481
constexpr auto kMatMul
Definition tags.h:37
ffi::Array< Tensor > split_n_sections(const Tensor &x, int num_sections, int axis, std::string name="T_split_sections", std::string tag=kInjective)
Split a tensor into a number of sub-tensors.
Definition transform.h:1007
Tensor dyn_tile(const Tensor &x, ffi::Array< PrimExpr > new_shape, size_t rdim, std::string name="T_tile", std::string tag=kBroadcast)
Creates an operation to tile elements of an array.
Definition transform.h:1478
te::Tensor tensor_size(const te::Tensor &src, PrimType dtype, const std::string &name="tensor_size", const std::string &tag=kInjective)
Get the size of input tensor.
Definition transform.h:2039
Tensor reverse_sequence(const Tensor &x, const Tensor &seq_lengths, int seq_axis=1, int batch_axis=0, std::string name="T_reverse_sequence", std::string tag=kInjective)
Reverse the tensor for variable length slices. Input is first sliced along batch axis and then elemen...
Definition transform.h:264
Tensor one_hot(const Tensor &indices, const PrimExpr on_value, const PrimExpr off_value, int depth, int axis, PrimType dtype, ffi::Array< PrimExpr > oshape=ffi::Array< PrimExpr >(), const std::string name="T_one_hot", const std::string tag=kInjective)
Returns a one-hot tensor where the locations repsented by indices take value on_value,...
Definition transform.h:2076
Tensor tensordot(const Tensor &A, const tvm::te::Tensor &B, int axes=2, std::string name="T_tensordot", std::string tag=kMatMul)
A generalization of matrix multiplication to tensors.
Definition transform.h:1658
Tensor meta_schedule_layout_transform(const Tensor &src, const tirx::IndexMap &index_map, const ffi::String name="T_meta_schedule_layout_trans", const ffi::String tag=kInjective)
Transform the meta-schedule generated layout according to TIR's IndexMap.
Definition transform.h:1980
te::Tensor dynamic_strided_slice_with_axes(const te::Tensor &x, const ffi::Array< PrimExpr > &begin, const ffi::Array< PrimExpr > &end, const ffi::Array< PrimExpr > &strides, const ffi::Array< int64_t > &axes, bool assume_inbound=true, std::string name="T_dynamic_strided_slice_with_axes", std::string tag=kInjective)
strided_slice of a tensor where begin/end/stride can be mixed static and dynamic
Definition transform.h:716
Tensor take(const Tensor &a, const Tensor &indices, int batch_dims, std::string mode="fast", std::string name="T_take", std::string tag=kInjective)
Take elements from an flattened input array when axis is None.
Definition transform.h:1043
PrimExpr DynamicCanonicalizeIndex(PrimExpr index, PrimExpr extent, PrimExpr stride)
Definition transform.h:652
tvm::te::Tensor matmul(const tvm::te::Tensor &A, const tvm::te::Tensor &B, bool trans_a=false, bool trans_b=false, std::string name="T_matmul", std::string tag=kMatMul)
Creates an operation that calculates a matrix multiplication (row-major notation): A(i,...
Definition transform.h:1636
Tensor transpose(const Tensor &x, ffi::Optional< ffi::Array< int64_t > > opt_axes, std::string name="T_transpose", std::string tag=kInjective)
Permute the dimensions of an array.
Definition transform.h:205
ffi::Array< Tensor > split_indices_array(const Tensor &x, ffi::Array< PrimExpr > split_indices, int axis, std::string name="T_split", std::string tag=kInjective)
Split a tensor into multiple sub-tensors.
Definition transform.h:587
Tensor dynamic_strided_slice(const Tensor &x, const ffi::Array< PrimExpr > &begin, const ffi::Array< PrimExpr > &end, const ffi::Array< PrimExpr > &strides, bool assume_inbound=true, std::string name="T_dynamic_strided_slice", std::string tag=kInjective)
strided_slice of a tensor where begin/end/stride can be mixed static and dynamic
Definition transform.h:773
Tensor matrix_set_diag(const Tensor &input, const Tensor &diagonal, int k1, int k2, bool super_diag_right_align, bool sub_diag_right_align, const std::string name="T_matrix_set_diag", const std::string tag=kInjective)
Returns a tensor with the diagonal of input tensor replaced with the provided diagonals.
Definition transform.h:2189
Tensor where(const Tensor &condition, const Tensor &x, const Tensor &y, std::string name="T_where", std::string tag=kBroadcast)
Return the elements, either from x or y, depending on the condition.
Definition transform.h:1334
Tensor gather(const Tensor &data, int axis, const Tensor &indices, std::string name="T_gather", std::string tag=kInjective)
Gather values along given axis from given indices.
Definition transform.h:1517
Tensor tile(const Tensor &x, ffi::Array< int64_t > reps, std::string name="T_tile", std::string tag=kBroadcast)
Creates an operation to tile elements of an array.
Definition transform.h:1421
Tensor repeat(const Tensor &x, int repeats, int axis, std::string name="T_repeat", std::string tag=kBroadcast)
Creates an operation to repeat elements of an array.
Definition transform.h:1374
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
PrimExpr ceildiv(PrimExpr a, PrimExpr b, Span span=Span())
compute ceil(a / b)
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
PrimExpr max_value(PrimType dtype, Span span=Span())
PrimExpr truncmod(PrimExpr a, PrimExpr b, Span span=Span())
compute the remainder of truncdiv
PrimExpr if_then_else(PrimExpr cond, PrimExpr true_value, PrimExpr false_value, Span span=Span())
Conditional expression.
PrimExpr ceil(PrimExpr x, Span span=Span())
Calculate ceil(x)
PrimExpr cast(PrimType t, PrimExpr value, Span span=Span())
cast value to type.
PrimExpr indexdiv(PrimExpr a, PrimExpr b, Span span=Span())
compute floor(a / b) where a and b are non-negative.
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
PrimExpr indexmod(PrimExpr a, PrimExpr b, Span span=Span())
compute the remainder floor(a / b) where a and b are non-negative.
PrimExpr floordiv(PrimExpr a, PrimExpr b, Span span=Span())
compute floor(a / b)
Operation node can generate one or multiple Tensors.
Index ravel and unraval operations.
Utility functions for strided_slice op.
Utility functions for handling tensor.
Common operators defined for Expr.