Refactor Depth To Space NCHW2NHWC operator test

- Unify test cases with other operators
- Add test cases for operation with strides

PiperOrigin-RevId: 344197422
diff --git a/BUILD.bazel b/BUILD.bazel
index 5b4802b..553dc7c 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -6506,9 +6506,9 @@
 )
 
 xnnpack_unit_test(
-    name = "depth_to_space_test",
+    name = "depth_to_space_nchw2nhwc_test",
     srcs = [
-        "test/depth-to-space.cc",
+        "test/depth-to-space-nchw2nhwc.cc",
         "test/depth-to-space-operator-tester.h",
     ] + OPERATOR_TEST_PARAMS_HDRS,
     deps = OPERATOR_TEST_DEPS,
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 205b4ad..dbb8711 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2920,14 +2920,14 @@
   TARGET_LINK_LIBRARIES(deconvolution-nhwc-test PRIVATE XNNPACK gtest gtest_main)
   ADD_TEST(deconvolution-nhwc-test deconvolution-nhwc-test)
 
-  ADD_EXECUTABLE(depth-to-space-test test/depth-to-space.cc)
-  SET_TARGET_PROPERTIES(depth-to-space-test PROPERTIES
+  ADD_EXECUTABLE(depth-to-space-nchw2nhwc-test test/depth-to-space-nchw2nhwc.cc)
+  SET_TARGET_PROPERTIES(depth-to-space-nchw2nhwc-test PROPERTIES
     CXX_STANDARD 11
     CXX_STANDARD_REQUIRED YES
     CXX_EXTENSIONS NO)
-  TARGET_INCLUDE_DIRECTORIES(depth-to-space-test PRIVATE src test)
-  TARGET_LINK_LIBRARIES(depth-to-space-test PRIVATE XNNPACK gtest gtest_main)
-  ADD_TEST(depth-to-space-test depth-to-space-test)
+  TARGET_INCLUDE_DIRECTORIES(depth-to-space-nchw2nhwc-test PRIVATE src test)
+  TARGET_LINK_LIBRARIES(depth-to-space-nchw2nhwc-test PRIVATE XNNPACK gtest gtest_main)
+  ADD_TEST(depth-to-space-nchw2nhwc-test depth-to-space-nchw2nhwc-test)
 
   ADD_EXECUTABLE(divide-nd-test test/divide-nd.cc)
   SET_TARGET_PROPERTIES(divide-nd-test PROPERTIES
diff --git a/src/operators/depth-to-space-nchw2nhwc.c b/src/operators/depth-to-space-nchw2nhwc.c
index 55c830f..856047f 100644
--- a/src/operators/depth-to-space-nchw2nhwc.c
+++ b/src/operators/depth-to-space-nchw2nhwc.c
@@ -140,7 +140,7 @@
     .output_batch_stride = depth_to_space_op->output_pixel_stride * output_height * output_width * sizeof(float),
     .input_channel_stride = input_height * input_width * sizeof(float),
     .input_height_stride = input_width * sizeof(float),
-    .output_height_stride = output_width * depth_to_space_op->output_pixel_stride * sizeof(float),
+    .output_height_stride = depth_to_space_op->output_pixel_stride * output_width * sizeof(float),
     .output_width_stride = depth_to_space_op->output_pixel_stride * sizeof(float),
     .ukernel = xnn_params.x32.depthtospace2d_chw2hwc.ukernel,
   };
diff --git a/test/depth-to-space-nchw2nhwc.cc b/test/depth-to-space-nchw2nhwc.cc
new file mode 100644
index 0000000..0e0ba1a
--- /dev/null
+++ b/test/depth-to-space-nchw2nhwc.cc
@@ -0,0 +1,94 @@
+// Copyright 2020 Google LLC
+//
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree.
+
+#include "depth-to-space-operator-tester.h"
+
+#include <gtest/gtest.h>
+
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, one_column) {
+  for (size_t input_height = 1; input_height <= 7; input_height++) {
+    DepthToSpaceOperatorTester()
+      .input_size(input_height, 1)
+      .block_size(3)
+      .output_channels(17)
+      .iterations(3)
+      .TestNCHW2NHWCxF32();
+  }
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, one_row) {
+  for (size_t input_width = 1; input_width <= 7; input_width++) {
+    DepthToSpaceOperatorTester()
+      .input_size(1, input_width)
+      .block_size(3)
+      .output_channels(17)
+      .iterations(3)
+      .TestNCHW2NHWCxF32();
+  }
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, varying_input_size) {
+  for (size_t input_height = 1; input_height <= 5; input_height++) {
+    for (size_t input_width = 1; input_width <= 5; input_width++) {
+      DepthToSpaceOperatorTester()
+        .input_size(input_height, input_width)
+        .block_size(3)
+        .output_channels(17)
+        .TestNCHW2NHWCxF32();
+    }
+  }
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, varying_block_size) {
+  for (uint32_t block_size = 2; block_size <= 5; block_size++) {
+    DepthToSpaceOperatorTester()
+      .input_size(7, 5)
+      .block_size(block_size)
+      .output_channels(17)
+      .TestNCHW2NHWCxF32();
+  }
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, varying_output_channels) {
+  for (size_t output_channels = 1; output_channels <= 15; output_channels++) {
+    DepthToSpaceOperatorTester()
+      .input_size(7, 5)
+      .block_size(3)
+      .output_channels(output_channels)
+      .TestNCHW2NHWCxF32();
+  }
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, varying_batch_size) {
+  for (size_t batch_size = 2; batch_size <= 3; batch_size++) {
+    DepthToSpaceOperatorTester()
+      .batch_size(batch_size)
+      .input_size(7, 5)
+      .block_size(3)
+      .output_channels(17)
+      .TestNCHW2NHWCxF32();
+  }
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, input_channels_stride) {
+  DepthToSpaceOperatorTester()
+    .batch_size(2)
+    .input_size(7, 5)
+    .block_size(3)
+    .input_channels_stride(157)
+    .output_channels(17)
+    .TestNCHW2NHWCxF32();
+}
+
+TEST(DEPTH_TO_SPACE_NCHW2NHWC_X32, output_channels_stride) {
+  DepthToSpaceOperatorTester()
+    .batch_size(2)
+    .input_size(7, 5)
+    .block_size(3)
+    .output_channels_stride(19)
+    .output_channels(17)
+    .TestNCHW2NHWCxF32();
+}
diff --git a/test/depth-to-space-operator-tester.h b/test/depth-to-space-operator-tester.h
index b660b54..036201a 100644
--- a/test/depth-to-space-operator-tester.h
+++ b/test/depth-to-space-operator-tester.h
@@ -91,12 +91,34 @@
     return this->batch_size_;
   }
 
-  inline size_t input_channel_stride() const {
-    return this->input_height() * this->input_width();
+  inline DepthToSpaceOperatorTester& input_channels_stride(size_t input_channels_stride) {
+    assert(input_channels_stride >= 1);
+    this->input_channels_stride_ = input_channels_stride;
+    return *this;
   }
 
-  inline size_t input_height_stride() const {
-    return this->input_width();
+  inline size_t input_channels_stride() const {
+    if (this->input_channels_stride_ == 0) {
+      return input_channels();
+    } else {
+      assert(this->input_channels_stride_ >= input_channels());
+      return this->input_channels_stride_;
+    }
+  }
+
+  inline DepthToSpaceOperatorTester& output_channels_stride(size_t output_channels_stride) {
+    assert(output_channels_stride >= 1);
+    this->output_channels_stride_ = output_channels_stride;
+    return *this;
+  }
+
+  inline size_t output_channels_stride() const {
+    if (this->output_channels_stride_ == 0) {
+      return output_channels();
+    } else {
+      assert(this->output_channels_stride_ >= output_channels());
+      return this->output_channels_stride_;
+    }
   }
 
   inline DepthToSpaceOperatorTester& iterations(size_t iterations) {
@@ -113,11 +135,10 @@
     auto rng = std::mt19937(random_device());
     auto i32rng = std::bind(std::uniform_int_distribution<int32_t>(), rng);
 
-    size_t output_height_stride = output_width() * output_channels();
-    size_t output_width_stride = output_channels();
-
-    std::vector<int32_t> input(batch_size() * input_height() * input_width() * input_channels() + XNN_EXTRA_BYTES / sizeof(uint32_t));
-    std::vector<int32_t> output(batch_size() * output_height() * output_width() * output_channels());
+    std::vector<int32_t> input(XNN_EXTRA_BYTES / sizeof(uint32_t) +
+      ((batch_size() - 1) * input_channels_stride() + input_channels()) * input_height() * input_width());
+    std::vector<int32_t> output(
+      (batch_size() * output_height() * output_width() - 1) * output_channels_stride() + output_channels());
     for (size_t iteration = 0; iteration < iterations(); iteration++) {
       std::generate(input.begin(), input.end(), std::ref(i32rng));
       std::fill(output.begin(), output.end(), INT32_C(0xDEADBEAF));
@@ -128,7 +149,7 @@
 
       ASSERT_EQ(xnn_status_success,
                 xnn_create_depth_to_space_nchw2nhwc_x32(
-                    output_channels(), input_channels(), output_channels(),
+                    output_channels(), input_channels_stride(), output_channels_stride(),
                     block_size(), 0, &depth_to_space_op));
       ASSERT_NE(nullptr, depth_to_space_op);
 
@@ -151,20 +172,19 @@
             for (size_t ix = 0; ix < input_width(); ix++) {
               for (size_t bx = 0; bx < block_size(); bx++) {
                 for (size_t oc = 0; oc < output_channels(); oc++) {
-                  const size_t input_offset = i * input_height() * input_width() * input_channels() +
-                    (oc * block_size() * block_size() + by * block_size() + bx) * input_channel_stride() + iy * input_height_stride() + ix;
-                  ASSERT_LT(input_offset, input.size());
-
-                  const size_t output_offset = i * output_height() * output_width() * output_channels() + (iy * block_size() + by) * output_height_stride + (ix * block_size() + bx) * output_width_stride + oc;
-                  ASSERT_LT(output_offset, output.size());
-
+                  const size_t input_offset =
+                    i * input_channels_stride() * input_height() * input_width() +
+                    (((oc * block_size() + by) * block_size() + bx) * input_height() + iy) * input_width() + ix;
+                  const size_t output_offset =
+                    ((i * output_height() + iy * block_size() + by) * output_width() + ix * block_size() + bx) *
+                      output_channels_stride() + oc;
                   ASSERT_EQ(output[output_offset], input[input_offset])
-                    << "batch " << i << " / " << batch_size()
-                    << "input x " << ix << " / " << input_width()
-                    << ", input y " << iy << " / " << input_height()
-                    << ", block x " << bx << " / " << block_size()
-                    << ", block y " << by << " / " << block_size()
-                    << ", output channel " << oc << " / " << output_channels();
+                    << "batch: " << i << " / " << batch_size()
+                    << ", input x: " << ix << " / " << input_width()
+                    << ", input y: " << iy << " / " << input_height()
+                    << ", block x: " << bx << " / " << block_size()
+                    << ", block y: " << by << " / " << block_size()
+                    << ", output channel: " << oc << " / " << output_channels();
                 }
               }
             }
@@ -180,5 +200,7 @@
   size_t output_channels_{1};
   size_t block_size_{2};
   size_t batch_size_{1};
+  size_t input_channels_stride_{0};
+  size_t output_channels_stride_{0};
   size_t iterations_{1};
 };
diff --git a/test/depth-to-space.cc b/test/depth-to-space.cc
deleted file mode 100644
index c85255e..0000000
--- a/test/depth-to-space.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2020 Google LLC
-//
-// This source code is licensed under the BSD-style license found in the
-// LICENSE file in the root directory of this source tree.
-
-#include "depth-to-space-operator-tester.h"
-
-#include <gtest/gtest.h>
-
-TEST(RESIZE_DEPTH_TO_SPACE_NCHW2NHWC_X32, one_column) {
-    for (size_t input_height = 1; input_height <= 3; input_height++) {
-      for (size_t block_size = 2; block_size <= 5; block_size++) {
-        for (size_t output_channels = 1; output_channels <= 7; output_channels++) {
-          DepthToSpaceOperatorTester()
-            .input_size(input_height, 1)
-            .block_size(block_size)
-            .output_channels(output_channels)
-            .iterations(3)
-            .TestNCHW2NHWCxF32();
-        }
-      }
-    }
-}
-
-TEST(RESIZE_DEPTH_TO_SPACE_NCHW2NHWC_X32, one_row) {
-    for (size_t input_width = 1; input_width <= 3; input_width++) {
-      for (size_t block_size = 2; block_size <= 5; block_size++) {
-        for (size_t output_channels = 1; output_channels <= 3; output_channels++) {
-          DepthToSpaceOperatorTester()
-            .input_size(1, input_width)
-            .block_size(block_size)
-            .output_channels(output_channels)
-            .iterations(3)
-            .TestNCHW2NHWCxF32();
-        }
-      }
-    }
-}
-
-TEST(RESIZE_DEPTH_TO_SPACE_NCHW2NHWC_X32, varying_input_size) {
-    for (size_t input_height = 1; input_height <= 7; input_height++) {
-       for (size_t input_width = 1; input_width <= 7; input_width++) {
-         for (size_t block_size = 2; block_size <= 5; block_size++) {
-           for (size_t output_channels = 1; output_channels <= 3; output_channels++) {
-             DepthToSpaceOperatorTester()
-               .input_size(input_height, input_width)
-               .block_size(block_size)
-               .output_channels(output_channels)
-               .iterations(3)
-               .TestNCHW2NHWCxF32();
-           }
-         }
-       }
-    }
-}
-
-TEST(RESIZE_DEPTH_TO_SPACE_NCHW2NHWC_X32, varying_batch_size) {
-  for (size_t batch_size = 2; batch_size <= 3; batch_size++) {
-    for (size_t input_size = 2; input_size <= 6; input_size += 2) {
-      for (size_t block_size = 2; block_size <= 6; block_size += 2) {
-        for (size_t output_channels = 1; output_channels <= 3; output_channels++) {
-          DepthToSpaceOperatorTester()
-            .batch_size(batch_size)
-            .input_size(input_size, input_size)
-            .block_size(block_size)
-            .output_channels(output_channels)
-            .iterations(3)
-            .TestNCHW2NHWCxF32();
-        }
-      }
-    }
-  }
-}