aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm_compute/core/NEON/NEKernels.h1
-rw-r--r--arm_compute/core/NEON/kernels/NETileKernel.h76
-rw-r--r--arm_compute/runtime/NEON/NEFunctions.h3
-rw-r--r--arm_compute/runtime/NEON/functions/NETile.h57
-rw-r--r--src/core/NEON/kernels/NETileKernel.cpp117
-rw-r--r--src/runtime/NEON/functions/NETile.cpp42
-rw-r--r--tests/validation/NEON/Tile.cpp141
7 files changed, 436 insertions, 1 deletions
diff --git a/arm_compute/core/NEON/NEKernels.h b/arm_compute/core/NEON/NEKernels.h
index 0cfde722d9..49bba3a750 100644
--- a/arm_compute/core/NEON/NEKernels.h
+++ b/arm_compute/core/NEON/NEKernels.h
@@ -114,6 +114,7 @@
#include "arm_compute/core/NEON/kernels/NESoftmaxLayerKernel.h"
#include "arm_compute/core/NEON/kernels/NETableLookupKernel.h"
#include "arm_compute/core/NEON/kernels/NEThresholdKernel.h"
+#include "arm_compute/core/NEON/kernels/NETileKernel.h"
#include "arm_compute/core/NEON/kernels/NETransposeKernel.h"
#include "arm_compute/core/NEON/kernels/NEUpsampleLayerKernel.h"
#include "arm_compute/core/NEON/kernels/NEWarpKernel.h"
diff --git a/arm_compute/core/NEON/kernels/NETileKernel.h b/arm_compute/core/NEON/kernels/NETileKernel.h
new file mode 100644
index 0000000000..f842bff7db
--- /dev/null
+++ b/arm_compute/core/NEON/kernels/NETileKernel.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_NETILEKERNEL_H__
+#define __ARM_COMPUTE_NETILEKERNEL_H__
+
+#include "arm_compute/core/NEON/INEKernel.h"
+
+namespace arm_compute
+{
+class ITensor;
+
+/** NEON kernel to perform a tile operation */
+class NETileKernel : public INEKernel
+{
+public:
+ /** Default constructor */
+ NETileKernel();
+ /** Prevent instances of this class from being copied (As this class contains pointers). */
+ NETileKernel(const NETileKernel &) = delete;
+ /** Prevent instances of this class from being copied (As this class contains pointers). */
+ NETileKernel &operator=(const NETileKernel &) = delete;
+ /** Allow instances of this class to be moved */
+ NETileKernel(NETileKernel &&) = default;
+ /** Allow instances of this class to be moved */
+ NETileKernel &operator=(NETileKernel &&) = default;
+ const char *name() const override
+ {
+ return "NETileKernel";
+ }
+ /** Set the source, destination of the kernel
+ *
+ * @param[in] input Source tensor. Data type supported: U8/S8/QASYMM8/U16/S16/F16/U32/S32/F32.
+ * @param[out] output Destination tensor. Same as @p input
+ * @param[in] multiples Contains the number of times the input tensor should be replicated on the given dimension.
+ */
+ void configure(const ITensor *input, ITensor *output, const Multiples &multiples);
+ /** Static function to check if given info will lead to a valid configuration of @ref NETileKernel
+ *
+ * @param[in] input Source tensor info. Data type supported: U8/S8/QASYMM8/U16/S16/F16/U32/S32/F32.
+ * @param[in] output Destination tensor info. Same as @p input
+ * @param[in] multiples Contains the number of times the input tensor should be replicated on the given dimension.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input, const ITensorInfo *output, const Multiples &multiples);
+
+ // Inherited methods overridden:
+ void run(const Window &window, const ThreadInfo &info) override;
+
+private:
+ const ITensor *_input;
+ ITensor *_output;
+};
+} // namespace arm_compute
+#endif /*__ARM_COMPUTE_NETILEKERNEL_H__ */
diff --git a/arm_compute/runtime/NEON/NEFunctions.h b/arm_compute/runtime/NEON/NEFunctions.h
index d9c8355178..8873110982 100644
--- a/arm_compute/runtime/NEON/NEFunctions.h
+++ b/arm_compute/runtime/NEON/NEFunctions.h
@@ -117,6 +117,7 @@
#include "arm_compute/runtime/NEON/functions/NESoftmaxLayer.h"
#include "arm_compute/runtime/NEON/functions/NETableLookup.h"
#include "arm_compute/runtime/NEON/functions/NEThreshold.h"
+#include "arm_compute/runtime/NEON/functions/NETile.h"
#include "arm_compute/runtime/NEON/functions/NETranspose.h"
#include "arm_compute/runtime/NEON/functions/NEUpsampleLayer.h"
#include "arm_compute/runtime/NEON/functions/NEWarpAffine.h"
@@ -125,4 +126,4 @@
#include "arm_compute/runtime/NEON/functions/NEWinogradConvolutionLayer.h"
#include "arm_compute/runtime/NEON/functions/NEYOLOLayer.h"
-#endif /* __ARM_COMPUTE_NEFUNCTIONS_H__ */ \ No newline at end of file
+#endif /* __ARM_COMPUTE_NEFUNCTIONS_H__ */
diff --git a/arm_compute/runtime/NEON/functions/NETile.h b/arm_compute/runtime/NEON/functions/NETile.h
new file mode 100644
index 0000000000..f637d17aee
--- /dev/null
+++ b/arm_compute/runtime/NEON/functions/NETile.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_NETILE_H__
+#define __ARM_COMPUTE_NETILE_H__
+
+#include "arm_compute/runtime/NEON/INESimpleFunctionNoBorder.h"
+
+#include "arm_compute/core/Types.h"
+
+namespace arm_compute
+{
+class ITensor;
+
+/** Basic function to run @ref NETileKernel */
+class NETile : public INESimpleFunctionNoBorder
+{
+public:
+ /** Set the source, destination of the kernel
+ *
+ * @param[in] input Source tensor. Data type supported: U8/S8/QASYMM8/U16/S16/F16/U32/S32/F32.
+ * @param[out] output Destination tensor. Same as @p input
+ * @param[in] multiples Contains the number of times the input tensor should be replicated on the given dimension.
+ */
+ void configure(const ITensor *input, ITensor *output, const Multiples &multiples);
+ /** Static function to check if given info will lead to a valid configuration of @ref NETile
+ *
+ * @param[in] input Source tensor info. Data type supported: U8/S8/QASYMM8/U16/S16/F16/U32/S32/F32.
+ * @param[in] output Destination tensor info. Same as @p input
+ * @param[in] multiples Contains the number of times the input tensor should be replicated on the given dimension.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input, const ITensorInfo *output, const Multiples &multiples);
+};
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_NETILE_H__ */
diff --git a/src/core/NEON/kernels/NETileKernel.cpp b/src/core/NEON/kernels/NETileKernel.cpp
new file mode 100644
index 0000000000..dbeacfad94
--- /dev/null
+++ b/src/core/NEON/kernels/NETileKernel.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/NEON/kernels/NETileKernel.h"
+
+#include "arm_compute/core/Error.h"
+#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/ITensor.h"
+#include "arm_compute/core/TensorInfo.h"
+#include "arm_compute/core/Validate.h"
+#include "arm_compute/core/Window.h"
+#include "arm_compute/core/utils/misc/ShapeCalculator.h"
+
+namespace arm_compute
+{
+namespace
+{
+Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, const Multiples &multiples)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output);
+ ARM_COMPUTE_RETURN_ERROR_ON(multiples.size() > 4);
+ ARM_COMPUTE_RETURN_ERROR_ON(multiples.empty());
+ ARM_COMPUTE_RETURN_ERROR_ON(std::any_of(multiples.begin(), multiples.end(), [](uint32_t e)
+ {
+ return e == 0;
+ }));
+
+ // Validate output if initialized
+ if(output->total_size() != 0)
+ {
+ ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(misc::shape_calculator::compute_tiled_shape(input->tensor_shape(), multiples), output->tensor_shape());
+ ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
+ }
+
+ return Status{};
+}
+} // namespace
+
+NETileKernel::NETileKernel()
+ : _input(nullptr), _output(nullptr)
+{
+}
+
+void NETileKernel::configure(const ITensor *input, ITensor *output, const Multiples &multiples)
+{
+ ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
+
+ // Auto initialize output
+ TensorShape tiled_shape = misc::shape_calculator::compute_tiled_shape(input->info()->tensor_shape(), multiples);
+ auto_init_if_empty(*output->info(), tiled_shape, 1, input->info()->data_type());
+
+ // Validate
+ ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), multiples));
+
+ _input = input;
+ _output = output;
+
+ // Configure window without padding
+ Window win = calculate_max_window(*output->info());
+ INEKernel::configure(win);
+}
+
+Status NETileKernel::validate(const ITensorInfo *input, const ITensorInfo *output, const Multiples &multiples)
+{
+ ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, multiples));
+ return Status{};
+}
+
+void NETileKernel::run(const Window &window, const ThreadInfo &info)
+{
+ ARM_COMPUTE_UNUSED(info);
+ ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
+ ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window);
+
+ Window output_window{ window };
+ output_window.set(Window::DimX, Window::Dimension(output_window.x().start(), output_window.x().end(), _input->info()->dimension(0)));
+ Window out_slice = output_window.first_slice_window_1D();
+
+ const auto src_shape = _input->info()->tensor_shape();
+ do
+ {
+ Iterator output_it(_output, out_slice);
+
+ execute_window_loop(out_slice, [&](const Coordinates & id)
+ {
+ const size_t x = id.x();
+ const size_t y = id.y();
+ const size_t z = id.z();
+ const size_t w = id[3];
+ Coordinates input_coords{ x % src_shape[0], y % src_shape[1], z % src_shape[2], w % src_shape[3] };
+ memcpy(output_it.ptr(), _input->ptr_to_element(input_coords), _input->info()->dimension(0) * _input->info()->element_size());
+ },
+ output_it);
+ }
+ while(output_window.slide_window_slice_1D(out_slice));
+}
+} // namespace arm_compute
diff --git a/src/runtime/NEON/functions/NETile.cpp b/src/runtime/NEON/functions/NETile.cpp
new file mode 100644
index 0000000000..0ca4413251
--- /dev/null
+++ b/src/runtime/NEON/functions/NETile.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/NEON/functions/NETile.h"
+
+#include "arm_compute/core/NEON/kernels/NETileKernel.h"
+#include "support/ToolchainSupport.h"
+
+namespace arm_compute
+{
+void NETile::configure(const ITensor *input, ITensor *output, const Multiples &multiples)
+{
+ auto k = arm_compute::support::cpp14::make_unique<NETileKernel>();
+ k->configure(input, output, multiples);
+ _kernel = std::move(k);
+}
+
+Status NETile::validate(const ITensorInfo *input, const ITensorInfo *output, const Multiples &multiples)
+{
+ return NETileKernel::validate(input, output, multiples);
+}
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Tile.cpp b/tests/validation/NEON/Tile.cpp
new file mode 100644
index 0000000000..209652009e
--- /dev/null
+++ b/tests/validation/NEON/Tile.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INNEUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY NEAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NETile.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/TileFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+const auto MultiplesDataset = framework::dataset::make("Multiples", { Multiples{ 3 },
+ Multiples{ 2, 2 },
+ Multiples{ 2, 3, 4, 5 },
+ Multiples{ 2, 1, 2, 2 },
+ Multiples{ 2, 1, 3 },
+ Multiples{ 3, 3, 3 },
+ Multiples{ 2, 2, 2 }
+ });
+} // namespace
+TEST_SUITE(NE)
+TEST_SUITE(Tile)
+
+// *INDENT-OFF*
+// clang-format off
+DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(
+ framework::dataset::make("InputInfo", { TensorInfo(TensorShape(10, 10), 1, DataType::F32),
+ TensorInfo(TensorShape(10, 10), 1, DataType::F32), // Mismatching shape
+ TensorInfo(TensorShape(10, 10), 1, DataType::F16), // Mismatching type
+ TensorInfo(TensorShape(10, 10), 1, DataType::F32)}), // Wrong multiples
+ framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(10, 20), 1, DataType::F32),
+ TensorInfo(TensorShape(20, 20), 1, DataType::F32),
+ TensorInfo(TensorShape(20, 20), 1, DataType::F32),
+ TensorInfo(TensorShape(10, 20), 1, DataType::F32)})),
+ framework::dataset::make("Multiples",{ Multiples{1, 2}, Multiples{1, 2}, Multiples{0, 1} })),
+ framework::dataset::make("Expected", {true, false, false, false })),
+ input_info, output_info, multiples, expected)
+{
+ const Status status = NETile::validate(&input_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), multiples);
+ ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
+}
+// clang-format on
+// *INDENT-ON*
+
+template <typename T>
+using NETileFixture = TileValidationFixture<Tensor, Accessor, NETile, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NETileFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)),
+ MultiplesDataset))
+{
+ // Validate output
+ validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NETileFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F16)), MultiplesDataset))
+{
+ // Validate output
+ validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END() // FP16
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NETileFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)),
+ MultiplesDataset))
+{
+ // Validate output
+ validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NETileFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)),
+ MultiplesDataset))
+{
+ // Validate output
+ validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END() // FP32
+TEST_SUITE_END() // Float
+
+TEST_SUITE(Integer)
+TEST_SUITE(S8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NETileFixture<int8_t>, framework::DatasetMode::ALL,
+ combine(
+ combine(datasets::SmallShapes(), framework::dataset::make("DataType", { DataType::S8 })),
+ MultiplesDataset))
+{
+ // Validate output
+ validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END() // S8
+TEST_SUITE_END() // Integer
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QASYMM8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NETileFixture<uint8_t>, framework::DatasetMode::ALL,
+ combine(
+ combine(datasets::SmallShapes(), framework::dataset::make("DataType", { DataType::QASYMM8 })),
+ MultiplesDataset))
+{
+ // Validate output
+ validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END() // QASYMM8
+TEST_SUITE_END() // Quantized
+
+TEST_SUITE_END() // Tile
+TEST_SUITE_END() // NE
+} // namespace validation
+} // namespace test
+} // namespace arm_compute