diff options
author | Pablo Tello <pablo.tello@arm.com> | 2019-03-04 14:14:02 +0000 |
---|---|---|
committer | Gian Marco Iodice <gianmarco.iodice@arm.com> | 2019-03-19 10:18:10 +0000 |
commit | 3dd5b6884a65c06bcb9d15589ee2dc2978e3b336 (patch) | |
tree | e45ccae66b69c8db853ac883080c1c6358a57aec /tests/validation | |
parent | 2f7c149f36fa3e6296aba6de666962947f032558 (diff) | |
download | ComputeLibrary-3dd5b6884a65c06bcb9d15589ee2dc2978e3b336.tar.gz |
COMPMID-1933: Implement NEHeightConcatenateLayer.
Added support to concactenate tensors along the Y axis in NEConcatenateLayer.
Change-Id: Ib714bfcf9954cc35918efa7d52fc9164bb08bdf6
Signed-off-by: Pablo Tello <pablo.tello@arm.com>
Reviewed-on: https://review.mlplatform.org/c/841
Reviewed-by: Gian Marco Iodice <gianmarco.iodice@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'tests/validation')
-rw-r--r-- | tests/validation/CL/WidthConcatenateLayer.cpp | 48 | ||||
-rw-r--r-- | tests/validation/Helpers.cpp | 13 | ||||
-rw-r--r-- | tests/validation/Helpers.h | 7 | ||||
-rw-r--r-- | tests/validation/NEON/HeightConcatenateLayer.cpp | 131 | ||||
-rw-r--r-- | tests/validation/NEON/WidthConcatenateLayer.cpp | 35 | ||||
-rw-r--r-- | tests/validation/fixtures/ConcatenateLayerFixture.h (renamed from tests/validation/fixtures/WidthConcatenateLayerFixture.h) | 46 | ||||
-rw-r--r-- | tests/validation/fixtures/LSTMLayerFixture.h | 4 | ||||
-rw-r--r-- | tests/validation/reference/ConcatenateLayer.cpp (renamed from tests/validation/reference/WidthConcatenateLayer.cpp) | 43 | ||||
-rw-r--r-- | tests/validation/reference/ConcatenateLayer.h (renamed from tests/validation/reference/WidthConcatenateLayer.h) | 10 |
9 files changed, 263 insertions, 74 deletions
diff --git a/tests/validation/CL/WidthConcatenateLayer.cpp b/tests/validation/CL/WidthConcatenateLayer.cpp index 647e0413a1..493320b9ad 100644 --- a/tests/validation/CL/WidthConcatenateLayer.cpp +++ b/tests/validation/CL/WidthConcatenateLayer.cpp @@ -24,14 +24,14 @@ #include "arm_compute/core/Types.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/CLTensorAllocator.h" -#include "arm_compute/runtime/CL/functions/CLWidthConcatenateLayer.h" +#include "arm_compute/runtime/CL/functions/CLConcatenateLayer.h" #include "tests/CL/CLAccessor.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/WidthConcatenateLayerFixture.h" +#include "tests/validation/fixtures/ConcatenateLayerFixture.h" namespace arm_compute { @@ -72,8 +72,7 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip( inputs_vector_info_raw.emplace_back(&input); } - bool is_valid = bool(CLWidthConcatenateLayer::validate(inputs_vector_info_raw, - &output_info.clone()->set_is_resizable(false))); + bool is_valid = bool(CLConcatenateLayer::validate(inputs_vector_info_raw,&output_info.clone()->set_is_resizable(false),DataLayoutDimension::WIDTH )); ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS); } // clang-format on @@ -93,26 +92,30 @@ TEST_CASE(Configuration, framework::DatasetMode::ALL) ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); // Create and configure function - CLWidthConcatenateLayer concat_layer; + CLConcatenateLayer concat_layer; - concat_layer.configure({ &src1, &src2, &src3 }, &dst); + concat_layer.configure({ &src1, &src2, &src3 }, &dst, DataLayoutDimension::WIDTH); } template <typename T> -using CLWidthConcatenateLayerFixture = WidthConcatenateLayerValidationFixture<CLTensor, ICLTensor, CLAccessor, CLWidthConcatenateLayer, T>; +using CLWidthConcatenateLayerFixture = ConcatenateLayerValidationFixture<CLTensor, ICLTensor, CLAccessor, CLConcatenateLayer, T>; TEST_SUITE(Float) TEST_SUITE(FP16) -FIXTURE_DATA_TEST_CASE(RunSmall, CLWidthConcatenateLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), +FIXTURE_DATA_TEST_CASE(RunSmall, CLWidthConcatenateLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), framework::dataset::make("DataType", - DataType::F16))) + DataType::F16)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(CLAccessor(_target), _reference); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(concat(datasets::Large2DShapes(), datasets::Small4DShapes()), - framework::dataset::make("DataType", - DataType::F16))) +FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(concat(datasets::Large2DShapes(), datasets::Small4DShapes()), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(CLAccessor(_target), _reference); @@ -120,15 +123,18 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<half>, framework TEST_SUITE_END() TEST_SUITE(FP32) -FIXTURE_DATA_TEST_CASE(RunSmall, CLWidthConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), +FIXTURE_DATA_TEST_CASE(RunSmall, CLWidthConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), framework::dataset::make("DataType", - DataType::F32))) + DataType::F32)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(CLAccessor(_target), _reference); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::WidthConcatenateLayerShapes(), framework::dataset::make("DataType", - DataType::F32))) +FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::ConcatenateLayerShapes(), framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("Axis", 0))) { // Validate output validate(CLAccessor(_target), _reference); @@ -138,15 +144,17 @@ TEST_SUITE_END() TEST_SUITE(Quantized) TEST_SUITE(QASYMM8) -FIXTURE_DATA_TEST_CASE(RunSmall, CLWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), +FIXTURE_DATA_TEST_CASE(RunSmall, CLWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), framework::dataset::make("DataType", - DataType::QASYMM8))) + DataType::QASYMM8)), + framework::dataset::make("Axis", 0))) { // Validate output validate(CLAccessor(_target), _reference); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::WidthConcatenateLayerShapes(), framework::dataset::make("DataType", - DataType::QASYMM8))) +FIXTURE_DATA_TEST_CASE(RunLarge, CLWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::ConcatenateLayerShapes(), framework::dataset::make("DataType", + DataType::QASYMM8)), + framework::dataset::make("Axis", 0))) { // Validate output validate(CLAccessor(_target), _reference); diff --git a/tests/validation/Helpers.cpp b/tests/validation/Helpers.cpp index 11c454ea67..e9612f2223 100644 --- a/tests/validation/Helpers.cpp +++ b/tests/validation/Helpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -98,17 +98,18 @@ TensorShape calculate_depth_concatenate_shape(const std::vector<TensorShape> &in return out_shape; } -TensorShape calculate_width_concatenate_shape(const std::vector<TensorShape> &input_shapes) +TensorShape calculate_concatenate_shape(const std::vector<TensorShape> &input_shapes, size_t axis) { ARM_COMPUTE_ERROR_ON(input_shapes.empty()); - TensorShape out_shape = input_shapes[0]; + ARM_COMPUTE_ERROR_ON(axis >= out_shape.num_dimensions()); - int width = std::accumulate(input_shapes.begin(), input_shapes.end(), 0, [](int sum, const TensorShape & shape) + const int new_size = std::accumulate(input_shapes.begin(), input_shapes.end(), 0, [&](int sum, const TensorShape & shape) { - return sum + shape.x(); + ARM_COMPUTE_ERROR_ON(axis >= shape.num_dimensions()); + return sum + shape[axis]; }); - out_shape.set(0, width); + out_shape.set(axis, new_size); return out_shape; } diff --git a/tests/validation/Helpers.h b/tests/validation/Helpers.h index 4d1d21440d..2e8c667a41 100644 --- a/tests/validation/Helpers.h +++ b/tests/validation/Helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -128,13 +128,14 @@ void fill_mask_from_pattern(uint8_t *mask, int cols, int rows, MatrixPattern pat */ TensorShape calculate_depth_concatenate_shape(const std::vector<TensorShape> &input_shapes); -/** Calculate output tensor shape give a vector of input tensor to concatenate +/** Calculate output tensor shape for the concatenate operation along a given axis * * @param[in] input_shapes Shapes of the tensors to concatenate across width. + * @param[in] axis Axis to use for the concatenate operation * * @return The shape of output concatenated tensor. */ -TensorShape calculate_width_concatenate_shape(const std::vector<TensorShape> &input_shapes); +TensorShape calculate_concatenate_shape(const std::vector<TensorShape> &input_shapes, size_t axis); /** Parameters of Harris Corners algorithm. */ struct HarrisCornersParameters diff --git a/tests/validation/NEON/HeightConcatenateLayer.cpp b/tests/validation/NEON/HeightConcatenateLayer.cpp new file mode 100644 index 0000000000..f5400f9246 --- /dev/null +++ b/tests/validation/NEON/HeightConcatenateLayer.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019 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/Types.h" +#include "arm_compute/runtime/NEON/functions/NEConcatenateLayer.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/ConcatenateLayerFixture.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +TEST_SUITE(NEON) +TEST_SUITE(HeightConcatenateLayer) + +// *INDENT-OFF* +// clang-format off +DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip( + framework::dataset::make("InputInfo1", { TensorInfo(TensorShape(23U, 15U, 5U), 1, DataType::F32), // Mismatching data type input/output + TensorInfo(TensorShape(22U, 27U, 5U), 1, DataType::F32), // Mismatching y dimension + TensorInfo(TensorShape(11U, 25U, 5U), 1, DataType::F32), // Mismatching total height + TensorInfo(TensorShape(16U, 25U, 5U), 1, DataType::F32) + }), + framework::dataset::make("InputInfo2", { TensorInfo(TensorShape(23U, 15U, 4U), 1, DataType::F32), + TensorInfo(TensorShape(22U, 127U, 5U), 1, DataType::F32), + TensorInfo(TensorShape(11U, 26U, 5U), 1, DataType::F32), + TensorInfo(TensorShape(16U, 25U, 5U), 1, DataType::F32) + })), + framework::dataset::make("OutputInfo", { TensorInfo(TensorShape(23U, 30U, 5U), 1, DataType::F16), + TensorInfo(TensorShape(22U, 12U, 5U), 1, DataType::F32), + TensorInfo(TensorShape(11U, 7U, 5U), 1, DataType::F32), + TensorInfo(TensorShape(16U, 50U, 5U), 1, DataType::F32) + })), + framework::dataset::make("Expected", { false, false, false, true })), + input_info1, input_info2, output_info,expected) +{ + std::vector<TensorInfo> inputs_vector_info; + inputs_vector_info.emplace_back(std::move(input_info1)); + inputs_vector_info.emplace_back(std::move(input_info2)); + + std::vector<ITensorInfo *> inputs_vector_info_raw; + for(auto &input : inputs_vector_info) + { + inputs_vector_info_raw.emplace_back(&input); + } + + bool is_valid = bool(NEConcatenateLayer::validate(inputs_vector_info_raw, &output_info.clone()->set_is_resizable(false), DataLayoutDimension::HEIGHT)); + ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS); +} +// clang-format on +// *INDENT-ON* + +template <typename T> +using NEHeightConcatenateLayerFixture = ConcatenateLayerValidationFixture<Tensor, ITensor, Accessor, NEConcatenateLayer, T>; + +TEST_SUITE(Float) +TEST_SUITE(FP32) +FIXTURE_DATA_TEST_CASE(RunSmall, NEHeightConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("Axis", 1))) +{ + // Validate output + validate(Accessor(_target), _reference); +} +FIXTURE_DATA_TEST_CASE(RunLarge, NEHeightConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::ConcatenateLayerShapes(), framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("Axis", 1))) + +{ + // Validate output + validate(Accessor(_target), _reference); +} +TEST_SUITE_END() // FP32 +TEST_SUITE_END() // Float + +TEST_SUITE(Quantized) +TEST_SUITE(QASYMM8) +FIXTURE_DATA_TEST_CASE(RunSmall, NEHeightConcatenateLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), + framework::dataset::make("DataType", + DataType::QASYMM8)), + framework::dataset::make("Axis", 1))) +{ + // Validate output + validate(Accessor(_target), _reference); +} +FIXTURE_DATA_TEST_CASE(RunLarge, NEHeightConcatenateLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::ConcatenateLayerShapes(), + framework::dataset::make("DataType", + DataType::QASYMM8)), + framework::dataset::make("Axis", 1))) +{ + // Validate output + validate(Accessor(_target), _reference); +} +TEST_SUITE_END() // QASYMM8 +TEST_SUITE_END() // Quantized + +TEST_SUITE_END() +TEST_SUITE_END() +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/NEON/WidthConcatenateLayer.cpp b/tests/validation/NEON/WidthConcatenateLayer.cpp index 6e94e92d05..dba14ebb35 100644 --- a/tests/validation/NEON/WidthConcatenateLayer.cpp +++ b/tests/validation/NEON/WidthConcatenateLayer.cpp @@ -22,7 +22,7 @@ * SOFTWARE. */ #include "arm_compute/core/Types.h" -#include "arm_compute/runtime/NEON/functions/NEWidthConcatenateLayer.h" +#include "arm_compute/runtime/NEON/functions/NEConcatenateLayer.h" #include "arm_compute/runtime/Tensor.h" #include "arm_compute/runtime/TensorAllocator.h" #include "tests/NEON/Accessor.h" @@ -31,7 +31,7 @@ #include "tests/framework/Macros.h" #include "tests/framework/datasets/Datasets.h" #include "tests/validation/Validation.h" -#include "tests/validation/fixtures/WidthConcatenateLayerFixture.h" +#include "tests/validation/fixtures/ConcatenateLayerFixture.h" namespace arm_compute { @@ -72,27 +72,30 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip( inputs_vector_info_raw.emplace_back(&input); } - bool is_valid = bool(NEWidthConcatenateLayer::validate(inputs_vector_info_raw, - &output_info.clone()->set_is_resizable(false))); + bool is_valid = bool(NEConcatenateLayer::validate(inputs_vector_info_raw, + &output_info.clone()->set_is_resizable(false),DataLayoutDimension::WIDTH)); ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS); } // clang-format on // *INDENT-ON* - template <typename T> -using NEWidthConcatenateLayerFixture = WidthConcatenateLayerValidationFixture<Tensor, ITensor, Accessor, NEWidthConcatenateLayer, T>; +using NEWidthConcatenateLayerFixture = ConcatenateLayerValidationFixture<Tensor, ITensor, Accessor, NEConcatenateLayer, T>; TEST_SUITE(Float) TEST_SUITE(FP32) -FIXTURE_DATA_TEST_CASE(RunSmall, NEWidthConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), +FIXTURE_DATA_TEST_CASE(RunSmall, NEWidthConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), framework::dataset::make("DataType", - DataType::F32))) + DataType::F32)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(Accessor(_target), _reference); } -FIXTURE_DATA_TEST_CASE(RunLarge, NEWidthConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::WidthConcatenateLayerShapes(), framework::dataset::make("DataType", - DataType::F32))) +FIXTURE_DATA_TEST_CASE(RunLarge, NEWidthConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::ConcatenateLayerShapes(), framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(Accessor(_target), _reference); @@ -102,15 +105,19 @@ TEST_SUITE_END() TEST_SUITE(Quantized) TEST_SUITE(QASYMM8) -FIXTURE_DATA_TEST_CASE(RunSmall, NEWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), +FIXTURE_DATA_TEST_CASE(RunSmall, NEWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(concat(datasets::Small2DShapes(), datasets::Tiny4DShapes()), framework::dataset::make("DataType", - DataType::QASYMM8))) + DataType::QASYMM8)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(Accessor(_target), _reference); } -FIXTURE_DATA_TEST_CASE(RunLarge, NEWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::WidthConcatenateLayerShapes(), framework::dataset::make("DataType", - DataType::QASYMM8))) +FIXTURE_DATA_TEST_CASE(RunLarge, NEWidthConcatenateLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::ConcatenateLayerShapes(), framework::dataset::make("DataType", + DataType::QASYMM8)), + framework::dataset::make("Axis", 0))) + { // Validate output validate(Accessor(_target), _reference); diff --git a/tests/validation/fixtures/WidthConcatenateLayerFixture.h b/tests/validation/fixtures/ConcatenateLayerFixture.h index 47a03ed865..db09957c09 100644 --- a/tests/validation/fixtures/WidthConcatenateLayerFixture.h +++ b/tests/validation/fixtures/ConcatenateLayerFixture.h @@ -33,7 +33,7 @@ #include "tests/framework/Asserts.h" #include "tests/framework/Fixture.h" #include "tests/validation/Helpers.h" -#include "tests/validation/reference/WidthConcatenateLayer.h" +#include "tests/validation/reference/ConcatenateLayer.h" #include <random> @@ -44,11 +44,11 @@ namespace test namespace validation { template <typename TensorType, typename ITensorType, typename AccessorType, typename FunctionType, typename T> -class WidthConcatenateLayerValidationFixture : public framework::Fixture +class ConcatenateLayerValidationFixture : public framework::Fixture { public: template <typename...> - void setup(TensorShape shape, DataType data_type) + void setup(TensorShape shape, DataType data_type, unsigned int axis) { // Create input shapes std::mt19937 gen(library->seed()); @@ -78,12 +78,12 @@ public: { // Decrease the dimension by a small percentage. Don't increase // as that could make tensor too large. - s.set(0, s[0] + 2 * static_cast<int>(s[0] * change_dis(gen))); + s.set(axis, s[axis] + 2 * static_cast<int>(s[axis] * change_dis(gen))); } } - _target = compute_target(shapes, qinfo, data_type); - _reference = compute_reference(shapes, qinfo, data_type); + _target = compute_target(shapes, qinfo, data_type, axis); + _reference = compute_reference(shapes, qinfo, data_type, axis); } protected: @@ -93,7 +93,7 @@ protected: library->fill_tensor_uniform(tensor, i); } - TensorType compute_target(std::vector<TensorShape> shapes, const std::vector<QuantizationInfo> &qinfo, DataType data_type) + TensorType compute_target(const std::vector<TensorShape> &shapes, const std::vector<QuantizationInfo> &qinfo, DataType data_type, unsigned int axis) { std::vector<TensorType> srcs; std::vector<ITensorType *> src_ptrs; @@ -107,13 +107,26 @@ protected: src_ptrs.emplace_back(&srcs.back()); } - TensorShape dst_shape = misc::shape_calculator::calculate_width_concatenate_shape(src_ptrs); - - TensorType dst = create_tensor<TensorType>(dst_shape, data_type, 1, qinfo[shapes.size()]); + const TensorShape dst_shape = misc::shape_calculator::calculate_concatenate_shape(src_ptrs, axis); + TensorType dst = create_tensor<TensorType>(dst_shape, data_type, 1, qinfo[shapes.size()]); // Create and configure function - FunctionType width_concat; - width_concat.configure(src_ptrs, &dst); + FunctionType concat; + switch(axis) + { + case 0: + concat.configure(src_ptrs, &dst, DataLayoutDimension::WIDTH); + break; + case 1: + concat.configure(src_ptrs, &dst, DataLayoutDimension::HEIGHT); + break; + case 2: + concat.configure(src_ptrs, &dst, DataLayoutDimension::CHANNEL); + break; + default: + ARM_COMPUTE_ERROR("Not supported"); + break; + } for(auto &src : srcs) { @@ -140,12 +153,12 @@ protected: } // Compute function - width_concat.run(); + concat.run(); return dst; } - SimpleTensor<T> compute_reference(std::vector<TensorShape> shapes, const std::vector<QuantizationInfo> &qinfo, DataType data_type) + SimpleTensor<T> compute_reference(const std::vector<TensorShape> &shapes, const std::vector<QuantizationInfo> &qinfo, DataType data_type, unsigned int axis) { std::vector<SimpleTensor<T>> srcs; @@ -156,10 +169,9 @@ protected: fill(srcs.back(), j); } - const TensorShape dst_shape = calculate_width_concatenate_shape(shapes); + const TensorShape dst_shape = calculate_concatenate_shape(shapes, axis); SimpleTensor<T> dst{ dst_shape, data_type, 1, qinfo[shapes.size()] }; - - return reference::widthconcatenate_layer<T>(srcs, dst); + return reference::concatenate_layer<T>(srcs, dst, axis); } TensorType _target{}; diff --git a/tests/validation/fixtures/LSTMLayerFixture.h b/tests/validation/fixtures/LSTMLayerFixture.h index b30f1e534b..2cf83b8b3d 100644 --- a/tests/validation/fixtures/LSTMLayerFixture.h +++ b/tests/validation/fixtures/LSTMLayerFixture.h @@ -29,11 +29,11 @@ #include "tests/framework/Fixture.h" #include "tests/validation/reference/ActivationLayer.h" #include "tests/validation/reference/ArithmeticOperations.h" +#include "tests/validation/reference/ConcatenateLayer.h" #include "tests/validation/reference/FullyConnectedLayer.h" #include "tests/validation/reference/GEMM.h" #include "tests/validation/reference/PixelWiseMultiplication.h" #include "tests/validation/reference/Transpose.h" -#include "tests/validation/reference/WidthConcatenateLayer.h" namespace arm_compute { @@ -415,7 +415,7 @@ protected: scratch_inputs.emplace_back(std::move(cell_state_out)); scratch_inputs.emplace_back(std::move(forget_gate)); scratch_inputs.emplace_back(std::move(output)); - scratch = reference::widthconcatenate_layer(scratch_inputs, scratch); + scratch = reference::concatenate_layer(scratch_inputs, scratch, Window::DimX); _reference_scratch = std::move(scratch); return output_state_out; } diff --git a/tests/validation/reference/WidthConcatenateLayer.cpp b/tests/validation/reference/ConcatenateLayer.cpp index 38543393ce..1440878829 100644 --- a/tests/validation/reference/WidthConcatenateLayer.cpp +++ b/tests/validation/reference/ConcatenateLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,9 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "WidthConcatenateLayer.h" +#include "ConcatenateLayer.h" #include "tests/validation/Helpers.h" +#include "tests/validation/reference/Permute.h" namespace arm_compute { @@ -33,24 +34,22 @@ namespace validation { namespace reference { +namespace +{ template <typename T> SimpleTensor<T> widthconcatenate_layer(const std::vector<SimpleTensor<T>> &srcs, SimpleTensor<T> &dst) { // Create reference std::vector<TensorShape> shapes; - for(const auto &src : srcs) { shapes.emplace_back(src.shape()); } - // Compute reference int width_offset = 0; const int width_out = dst.shape().x(); - // Set output tensor to 0 std::fill_n(dst.data(), dst.num_elements(), 0); - for(const auto &src : srcs) { ARM_COMPUTE_ERROR_ON(width_offset >= width_out); @@ -89,13 +88,43 @@ SimpleTensor<T> widthconcatenate_layer(const std::vector<SimpleTensor<T>> &srcs, } width_offset += width; } - return dst; } template SimpleTensor<float> widthconcatenate_layer(const std::vector<SimpleTensor<float>> &srcs, SimpleTensor<float> &dst); template SimpleTensor<half> widthconcatenate_layer(const std::vector<SimpleTensor<half>> &srcs, SimpleTensor<half> &dst); template SimpleTensor<uint8_t> widthconcatenate_layer(const std::vector<SimpleTensor<uint8_t>> &srcs, SimpleTensor<uint8_t> &dst); +} // namespace + +template <typename T> +SimpleTensor<T> concatenate_layer(std::vector<SimpleTensor<T>> &srcs, SimpleTensor<T> &dst, unsigned int axis) +{ + switch(axis) + { + case Window::DimX: + { + return widthconcatenate_layer(srcs, dst); + } + case Window::DimY: + { + for(auto &t : srcs) + { + t = reference::permute<T>(t, PermutationVector(1U, 0U)); + } + dst = reference::permute<T>(dst, PermutationVector(1U, 0U)); + return reference::permute<T>(widthconcatenate_layer(srcs, dst), PermutationVector(1U, 0U)); + } + default: + { + ARM_COMPUTE_ERROR("Not supported"); + return dst; + } + } +} + +template SimpleTensor<float> concatenate_layer(std::vector<SimpleTensor<float>> &srcs, SimpleTensor<float> &dst, unsigned int axis); +template SimpleTensor<half> concatenate_layer(std::vector<SimpleTensor<half>> &srcs, SimpleTensor<half> &dst, unsigned int axis); +template SimpleTensor<uint8_t> concatenate_layer(std::vector<SimpleTensor<uint8_t>> &srcs, SimpleTensor<uint8_t> &dst, unsigned int axis); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/WidthConcatenateLayer.h b/tests/validation/reference/ConcatenateLayer.h index 0f1f428f10..14fd097eee 100644 --- a/tests/validation/reference/WidthConcatenateLayer.h +++ b/tests/validation/reference/ConcatenateLayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_TEST_WIDTHCONCATENATE_LAYER_H__ -#define __ARM_COMPUTE_TEST_WIDTHCONCATENATE_LAYER_H__ +#ifndef __ARM_COMPUTE_TEST_CONCATENATE_LAYER_H__ +#define __ARM_COMPUTE_TEST_CONCATENATE_LAYER_H__ #include "tests/SimpleTensor.h" @@ -37,9 +37,9 @@ namespace validation namespace reference { template <typename T> -SimpleTensor<T> widthconcatenate_layer(const std::vector<SimpleTensor<T>> &srcs, SimpleTensor<T> &dst); +SimpleTensor<T> concatenate_layer(std::vector<SimpleTensor<T>> &srcs, SimpleTensor<T> &dst, unsigned int axis); } // namespace reference } // namespace validation } // namespace test } // namespace arm_compute -#endif /* __ARM_COMPUTE_TEST_WIDTHCONCATENATE_LAYER_H__ */ +#endif /* __ARM_COMPUTE_TEST_CONCATENATE_LAYER_H__ */ |