95 input = loco::must_cast<luci::CircleNode *>(node->
input());
96 begin = loco::must_cast<luci::CircleConst *>(node->
begin());
97 end = loco::must_cast<luci::CircleConst *>(node->
end());
115inline int Clamp(
const int32_t v,
const int32_t lo,
const int32_t hi)
115inline int Clamp(
const int32_t v,
const int32_t lo,
const int32_t hi) {
…}
133 const auto *strides = params.
strides;
134 const int64_t axis_size =
static_cast<int64_t
>(input_shape.
dim(axis).
value());
140 int64_t start = start_indices[axis];
143 if (begin_mask & (1LL << axis))
145 if (strides[axis] > 0)
150 start = std::numeric_limits<int32_t>::lowest();
155 start = std::numeric_limits<int32_t>::max();
166 if (strides[axis] > 0)
169 start =
Clamp(start, 0, axis_size);
174 start =
Clamp(start, -1, axis_size - 1);
186 int64_t axis, int64_t start_for_axis)
188 const auto end_mask = params.
end_mask;
191 const auto *strides = params.
strides;
192 const int64_t axis_size =
static_cast<int64_t
>(input_shape.
dim(axis).
value());
199 const bool shrink_axis = shrink_axis_mask & (1LL << axis);
200 int64_t stop = stop_indices[axis];
208 return start_for_axis + 1;
212 if (end_mask & (1LL << axis))
214 if (strides[axis] > 0)
218 stop = std::numeric_limits<int32_t>::max();
223 stop = std::numeric_limits<int32_t>::lowest();
236 if (strides[axis] > 0)
239 stop =
Clamp(stop, 0, axis_size);
244 stop =
Clamp(stop, -1, axis_size - 1);
265 int64_t num_add_axis = 0;
276 const int64_t effective_dims = op_context->
input_dims + num_add_axis;
283 int64_t effective_ellipsis_mask = 0, effective_new_axis_mask = 0;
284 int64_t ellipsis_start_idx = effective_dims, expanded_ellipsis = 0;
285 for (int64_t i = 0; i < effective_dims;)
289 ellipsis_start_idx = i;
290 int64_t ellipsis_end_idx =
293 expanded_ellipsis = ellipsis_end_idx - ellipsis_start_idx - 1;
296 for (; i < ellipsis_end_idx; ++i)
298 effective_ellipsis_mask |= (1LL << i);
305 effective_new_axis_mask |= (1LL << i);
312 int64_t added_ellipsis = 0, added_axises = 0;
314 assert(
static_cast<uint32_t
>(effective_dims) == effective_dims);
317 for (int64_t i = 0; i < effective_dims; ++i)
319 if ((1LL << i) & effective_ellipsis_mask)
322 added_ellipsis = std::max(int64_t(0), i - ellipsis_start_idx);
329 else if ((1LL << i) & effective_new_axis_mask)
351 const int64_t orig_idx = i - added_ellipsis;
375 assert(
static_cast<int8_t
>(effective_dims) ==
static_cast<int32_t
>(effective_dims));
390 auto begin_node = loco::must_cast<luci::CircleNode *>(node->
begin());
391 auto end_node = loco::must_cast<luci::CircleNode *>(node->
end());
392 auto strides_node = loco::must_cast<luci::CircleNode *>(node->
strides());
394 LUCI_ASSERT(begin_node->dtype() ==
S32,
"Only support S32 for begin_node");
395 LUCI_ASSERT(end_node->dtype() ==
S32,
"Only support S32 for end_node");
396 LUCI_ASSERT(strides_node->dtype() ==
S32,
"Only support S32 for strides_node");
398 LUCI_ASSERT(begin_node->rank() == 1,
"Only support rank 1 for begin_node");
399 LUCI_ASSERT(end_node->rank() == 1,
"Only support rank 1 for end_node");
400 LUCI_ASSERT(strides_node->rank() == 1,
"Only support rank 1 for strides_node");
406 if (strides_const ==
nullptr)
408 INTERNAL_EXN(
"StridedSlice strides node is not Constant");
410 if (begin_const ==
nullptr || end_const ==
nullptr)
419 assert(begin_const->size<
S32>() <= input_shape.
rank());
420 assert(end_const->size<
S32>() <= input_shape.
rank());
421 assert(strides_const->size<
S32>() <= input_shape.
rank());
426 std::vector<int64_t> output_shape_vector;
427 std::vector<bool> output_known_vector;
429 for (int32_t idx = effective_input_shape.rank() - 1; idx >= 0; --idx)
431 int32_t stride = op_params.strides[idx];
432 LUCI_ASSERT(stride != 0,
"stride value has to be non-zero");
441 const bool shrink_axis = op_params.shrink_axis_mask & (1 << idx);
448 int64_t dim_shape = std::ceil((end -
begin) /
static_cast<float>(stride));
449 dim_shape = dim_shape < 0 ? 0 : dim_shape;
452 output_shape_vector.push_back(dim_shape);
453 output_known_vector.push_back(effective_input_shape.dim(idx).known());
457 auto shape_size = output_shape_vector.size();
459 for (uint32_t idx = 0; idx < shape_size; ++idx)
461 bool known = output_known_vector[shape_size - 1u - idx];
464 int64_t dim = output_shape_vector.at(shape_size - 1u - idx);
465 LUCI_ASSERT(0 <= dim && dim < 0xfffffffL,
"Dimension size exceeds limit");
#define INTERNAL_EXN(msg)
@ brief throw internal exception with message
The value of one dimension in a tensor shape.
uint32_t value(void) const
Return the value.
const Dimension & dim(uint32_t axis) const
uint32_t rank(void) const
Class to build tensor data.
const loco::DataTypeImpl< DT >::Type & at(uint32_t n) const
loco::Node * input(void) const
int32_t begin_mask() const
int32_t shrink_axis_mask() const
loco::Node * begin(void) const
int32_t ellipsis_mask() const
int32_t new_axis_mask() const
loco::Node * strides(void) const
loco::Node * end(void) const
loco::TensorShape visit(const luci::CircleNode *node) final
Default fallback.
const luci_interpreter::RuntimeShape output_shape
#define LUCI_ASSERT(condition, msg)
DataType
"scalar" value type
int64_t StopForAxis(const StridedSliceParams ¶ms, const loco::TensorShape &input_shape, int64_t axis, int64_t start_for_axis)
int Clamp(const int32_t v, const int32_t lo, const int32_t hi)
loco::TensorShape circle_shape(const luci::CircleNode *node)
int64_t StartForAxis(const StridedSliceParams ¶ms, const loco::TensorShape &input_shape, int64_t axis)
StridedSliceParams BuildStridedSliceParams(StridedSliceContext *op_context)
CircleInput * input_node(loco::Graph *g, const loco::GraphInputIndex &index)
Find a Pull node with a given input index.
luci::CircleConst * strides
StridedSliceParams params
luci::CircleConst * begin
StridedSliceContext(const luci::CircleStridedSlice *node)
loco::TensorShape effective_input_shape
int32_t stop_indices[kMaxDim]
int32_t start_indices[kMaxDim]
int8_t start_indices_count
int8_t stop_indices_count