diff options
Diffstat (limited to 'compiler/nnc/backends/soft_backend/code_snippets/cpp_resize.def')
-rw-r--r-- | compiler/nnc/backends/soft_backend/code_snippets/cpp_resize.def | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/compiler/nnc/backends/soft_backend/code_snippets/cpp_resize.def b/compiler/nnc/backends/soft_backend/code_snippets/cpp_resize.def new file mode 100644 index 000000000..68dde5670 --- /dev/null +++ b/compiler/nnc/backends/soft_backend/code_snippets/cpp_resize.def @@ -0,0 +1,61 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +template <typename T> +inline void ResizeNearestNeighbor( + const RuntimeShape& unextended_input_shape, const T* input_data, + const int32 output_height, const int32 output_width, + const RuntimeShape& unextended_output_shape, T* output_data) { + // Align corners = true is not supported. + TFLITE_DCHECK_LE(unextended_input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 4); + + const RuntimeShape input_shape = + RuntimeShape::ExtendedShape(4, unextended_input_shape); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + + int32 batches = MatchingDim(input_shape, 0, output_shape, 0); + int32 input_height = input_shape.Dims(1); + int32 input_width = input_shape.Dims(2); + int32 depth = MatchingDim(input_shape, 3, output_shape, 3); + + + // We use float to ensure agreement with the Tensorflow implementation. + const float height_scale = static_cast<float>(input_height) / output_height; + const float width_scale = static_cast<float>(input_width) / output_width; + + const int col_offset = input_shape.Dims(3); + const int row_offset = input_shape.Dims(2) * col_offset; + const int batch_offset = input_shape.Dims(1) * row_offset; + + const T* input_ptr = input_data; + T* output_ptr = output_data; + for (int b = 0; b < batches; ++b) { + for (int y = 0; y < output_height; ++y) { + int32 in_y = std::min(static_cast<int32>(std::floor(y * height_scale)), + input_height - 1); + const T* y_input_ptr = input_ptr + in_y * row_offset; + for (int x = 0; x < output_width; ++x) { + int32 in_x = std::min(static_cast<int32>(std::floor(x * width_scale)), + input_width - 1); + const T* x_input_ptr = y_input_ptr + in_x * col_offset; + memcpy(output_ptr, x_input_ptr, depth * sizeof(T)); + output_ptr += depth; + } + } + input_ptr += batch_offset; + } +} |