tvm
Loading...
Searching...
No Matches
strided_slice.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_DETAIL_STRIDED_SLICE_H_
25#define TVM_TOPI_DETAIL_STRIDED_SLICE_H_
26
27#include <tvm/ir/prim/expr.h>
28
29#include <algorithm>
30#include <limits>
31#include <string>
32#include <tuple>
33#include <vector>
34
35#include "constant_utils.h"
36
37namespace tvm {
38namespace topi {
39namespace detail {
40
41using namespace tvm::te;
42
43inline int64_t CanonicalizeIndex(int64_t index, int64_t extent, int64_t stride) {
44 int64_t begin_range = stride < 0 ? -1 : 0;
45 int64_t end_range = stride < 0 ? extent - 1 : extent;
46 if (index < 0) {
47 index += extent;
48 }
49 return std::min(std::max(index, begin_range), end_range);
50}
51
52inline std::tuple<std::vector<int64_t>, std::vector<int64_t>, std::vector<int64_t>> ConvertToVec(
53 const ffi::Array<ffi::Optional<IntImm>>& begin, const ffi::Array<ffi::Optional<IntImm>>& end,
54 const ffi::Array<IntImm>& strides, std::string slice_mode) {
55 std::vector<int64_t> stride_vec(strides.size(), 1);
56 if (slice_mode == "end") {
57 for (size_t i = 0; i < strides.size(); ++i) {
58 stride_vec[i] = strides[i]->value;
59 }
60 }
61 const int64_t max_range = std::numeric_limits<int64_t>::max();
62 std::vector<int64_t> begin_vec;
63 for (size_t i = 0; i < begin.size(); ++i) {
64 if (!begin[i].has_value()) {
65 // value=None
66 begin_vec.push_back(stride_vec[i] > 0 ? 0 : max_range);
67 } else {
68 begin_vec.push_back(begin[i].value()->value);
69 }
70 }
71 std::vector<int64_t> end_vec;
72 for (size_t i = 0; i < end.size(); ++i) {
73 // allow end to be None
74 if (!end[i].has_value()) {
75 end_vec.push_back(stride_vec[i] < 0 ? 0 : max_range);
76 } else if (slice_mode == "size") {
77 int64_t end_val = end[i].value()->value;
78 if (end_val < 0) {
79 end_vec.push_back(stride_vec[i] < 0 ? 0 : max_range);
80 } else {
81 end_vec.push_back(begin_vec[i] + end_val);
82 }
83 } else {
84 end_vec.push_back(end[i].value()->value);
85 }
86 }
87 return std::make_tuple(begin_vec, end_vec, stride_vec);
88}
89
90inline ffi::Array<PrimExpr> StridedSliceCanonicalizeBegin(const ffi::Array<PrimExpr>& ishape,
91 const std::vector<int64_t>& begin,
92 const std::vector<int64_t>& strides,
93 const ffi::Array<int64_t>& axes,
94 PrimType dtype,
95 std::string slice_mode = "end") {
96 ffi::Array<PrimExpr> begin_expr;
97 for (size_t i = 0; i < axes.size(); ++i) {
98 int64_t ax = axes[i];
100 int64_t dim_i = GetConstInt(ishape[ax]);
101 int64_t begin_i = CanonicalizeIndex(begin[i], dim_i, strides[i]);
102 begin_expr.push_back(MakeConst(dtype, begin_i));
103 } else {
104 auto idim = ishape[ax];
105 auto b_expr = MakeConst(dtype, begin[i]);
106 PrimExpr b = begin[i] < 0 ? b_expr + idim : b_expr;
107 auto s = strides[i];
108 if (s < 0) {
109 b = tvm::min(b, idim - 1);
110 } else {
111 b = tvm::if_then_else(b < 0, 0, b);
112 }
113 begin_expr.push_back(b);
114 }
115 }
116 return begin_expr;
117}
118
119inline ffi::Array<PrimExpr> StridedSliceOutputShape(
120 const ffi::Array<PrimExpr>& ishape, const std::vector<int64_t>& begin,
121 const std::vector<int64_t>& end, const std::vector<int64_t>& strides,
122 const ffi::Array<int64_t>& axes, std::string slice_mode,
123 const ffi::Array<PrimExpr>& begin_canonicalized, bool use_any = false) {
124 TVM_FFI_ICHECK(!use_any) << "StridedSliceOutputShape does not legacy use_any";
125 const size_t src_tensor_dim = ishape.size();
126 ffi::Array<PrimExpr> out_shape;
127 for (size_t i = 0; i < src_tensor_dim; ++i) {
128 out_shape.push_back(ishape[i]);
129 }
130
131 for (size_t i = 0; i < axes.size(); ++i) {
132 int64_t ax = axes[i];
134 const int64_t dim_i = GetConstInt(ishape[ax]);
136 int64_t begin_i = GetConstInt(begin_canonicalized[i]);
137 int64_t end_i = CanonicalizeIndex(end[i], dim_i, strides[i]);
138 int interval = std::abs(end_i - begin_i);
139 int slice_size =
140 static_cast<int>((interval + std::abs(strides[i]) - 1) / std::abs(strides[i]));
141 TVM_FFI_ICHECK(strides[i] < 0 ? (end_i <= begin_i) : (begin_i <= end_i))
142 << ": Input [Begin=" << begin[i] << ", End=" << end[i] << "] is invalid for axis=" << i;
144 } else {
145 out_shape.Set(ax, tvm::tirx::PrimVar("dim", out_shape[i].ty()));
146 }
147 }
148
149 return out_shape;
150}
151
152} // namespace detail
153} // namespace topi
154} // namespace tvm
155#endif // TVM_TOPI_DETAIL_STRIDED_SLICE_H_
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
Definition base_expr.h:137
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Checked scalar view over a VarNode.
Definition var.h:46
Utility functions for handling constants in TVM expressions.
TIR expressions.
Tensor expression language DSL.
Definition extracted_task.h:33
const Op & cast()
See pesudo code below:
PrimExpr MakeConst(PrimType dtype, ValueType value, Span span=Span())
Make a const value with certain data type.
Definition op.h:1002
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
PrimExpr if_then_else(PrimExpr cond, PrimExpr true_value, PrimExpr false_value, Span span=Span())
Conditional expression.
PrimExpr min(PrimExpr a, PrimExpr b, Span span=Span())
take minimum of two values