| 3320 | } |
| 3321 | |
| 3322 | Status AlgebraicSimplifierVisitor::HandleSlice(HloInstruction* slice) { |
| 3323 | // Delete no-op slices, i.e. where shape = operand shape. |
| 3324 | if (ReplaceInstructionIfSameShape(slice, slice->mutable_operand(0))) { |
| 3325 | return Status::OK(); |
| 3326 | } |
| 3327 | |
| 3328 | HloInstruction* pad; |
| 3329 | HloInstruction* pad_operand; |
| 3330 | if (Match(slice, m::Slice(m::Pad(&pad, m::Op(&pad_operand), m::Op())))) { |
| 3331 | // Is the result of the slice the pad operand. |
| 3332 | bool slice_undoes_pad = true; |
| 3333 | // Can the slice be moved to the pad_operand without any padding being read. |
| 3334 | bool slice_inside_pad = true; |
| 3335 | // Does this slice slice out pading only. |
| 3336 | bool slice_in_padding = false; |
| 3337 | std::vector<int64> new_starts = slice->slice_starts(); |
| 3338 | std::vector<int64> new_limits = slice->slice_limits(); |
| 3339 | for (int64 i = 0; i < slice->shape().rank(); ++i) { |
| 3340 | const int64 start = slice->slice_starts(i); |
| 3341 | const int64 stride = slice->slice_strides(i); |
| 3342 | const int64 limit = slice->slice_limits(i); |
| 3343 | const int64 size = pad->shape().dimensions(i); |
| 3344 | |
| 3345 | const auto& dim = pad->padding_config().dimensions(i); |
| 3346 | const int64 low = dim.edge_padding_low(); |
| 3347 | const int64 high = dim.edge_padding_high(); |
| 3348 | const int64 interior = dim.interior_padding(); |
| 3349 | const int64 edge = size - high; |
| 3350 | |
| 3351 | if (limit <= low || start >= edge) { |
| 3352 | slice_in_padding = true; |
| 3353 | break; |
| 3354 | } |
| 3355 | |
| 3356 | if (start != low || stride - 1 != interior) { |
| 3357 | slice_undoes_pad = false; |
| 3358 | } |
| 3359 | |
| 3360 | if (start < low || limit > edge || interior != 0 || stride != 1) { |
| 3361 | slice_inside_pad = false; |
| 3362 | } |
| 3363 | new_starts[i] -= low; |
| 3364 | new_limits[i] -= low; |
| 3365 | } |
| 3366 | if (slice_in_padding) { |
| 3367 | return ReplaceInstruction( |
| 3368 | slice, MakeBroadcastHlo(pad->mutable_operand(1), {}, slice->shape())); |
| 3369 | } |
| 3370 | if (slice_undoes_pad && ReplaceInstructionIfSameShape(slice, pad_operand)) { |
| 3371 | return Status::OK(); |
| 3372 | } |
| 3373 | if (slice_inside_pad) { |
| 3374 | TF_ASSIGN_OR_RETURN(HloInstruction * new_slice, |
| 3375 | MakeSliceHlo(pad_operand, new_starts, new_limits, |
| 3376 | slice->slice_strides())); |
| 3377 | return ReplaceInstruction(slice, new_slice); |
| 3378 | } |
| 3379 | } |
nothing calls this directly
no test coverage detected