summaryrefslogtreecommitdiff
path: root/compiler/nnc/backends/soft_backend/code_snippets/cpp_resize.def
diff options
context:
space:
mode:
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.def61
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;
+ }
+}