From 8247f7901ca49c7e719ffe9dcedd8838d3f7e46d Mon Sep 17 00:00:00 2001 From: Maksims Svecovs Date: Thu, 1 Feb 2024 22:57:53 +0000 Subject: [PATCH 1/2] [doc] Add documentation for transpose Adds doxygen comment for intrinsiccv_transpose Signed-off-by: Maksims Svecovs --- intrinsiccv/include/intrinsiccv.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/intrinsiccv/include/intrinsiccv.h b/intrinsiccv/include/intrinsiccv.h index da088e4c8..4ce617922 100644 --- a/intrinsiccv/include/intrinsiccv.h +++ b/intrinsiccv/include/intrinsiccv.h @@ -754,6 +754,31 @@ intrinsiccv_error_t intrinsiccv_split(const void *src_data, size_t src_stride, size_t height, size_t channels, size_t element_size); +/// Matrix transpose operation. +/// Inplace transpose ('src == dst') is only supported for +/// square matrixes (`src_width == src_height`). +/// +/// Example for `src[4,3]` to `dst[3,4]`: +/// ``` +/// | 0 | 2 | 2 | 2 | | 0 | 1 | 1 | +/// | 1 | 0 | 2 | 2 | -> | 2 | 0 | 1 | +/// | 1 | 1 | 0 | 0 | | 2 | 2 | 0 | +/// | 2 | 2 | 2 | +/// ``` +/// +/// @param src Pointer to the source data. Must be non-null. +/// @param src_stride Distance in bytes from the start of one row to the +/// start of the next row for the source data. +/// Must not be less than width * element_size. +/// @param dst Pointer to the destination data. Must be non-null. +/// Can be the same as source data for inplace operation. +/// @param dst_stride Distance in bytes from the start of one row to the +/// start of the next row for the destination data. +/// Must not be less than height * element_size. +/// @param src_width Number of elements in a row. +/// @param src_height Number of rows in the data. +/// @param element_size Size of one element in bytes. +/// intrinsiccv_error_t intrinsiccv_transpose(const void *src, size_t src_stride, void *dst, size_t dst_stride, size_t src_width, size_t src_height, -- GitLab From d7efb8c44ad8dc8ed992e3b1c6da8d6691117a83 Mon Sep 17 00:00:00 2001 From: Maksims Svecovs Date: Thu, 1 Feb 2024 21:53:19 +0000 Subject: [PATCH 2/2] [test] Add transpose test Adding test for intrinsiccv_transpose Signed-off-by: Maksims Svecovs --- test/api/test_transpose.cpp | 82 +++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 test/api/test_transpose.cpp diff --git a/test/api/test_transpose.cpp b/test/api/test_transpose.cpp new file mode 100644 index 000000000..b1dfecf90 --- /dev/null +++ b/test/api/test_transpose.cpp @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include "framework/array.h" +#include "framework/generator.h" + +template +class TestTranspose final { + public: + static void test(size_t padding) { + // Width is set to execute 2 vector paths and 1 scalar path + const size_t src_width = test::Options::vector_length() * 2 + 1; + // Only square data is supported inplace + // Otherwise execute 3 vector paths and 1 scalar path (not to match width) + const size_t src_height = + inplace ? src_width : test::Options::vector_length() * 3 + 1; + const size_t dst_width = src_height; + const size_t dst_height = src_width; + + test::Array2D source(src_width, src_height, padding, 1); + test::Array2D expected(dst_width, dst_height, padding, 1); + test::Array2D actual; + test::Array2D *p_actual = &source; + + // Only allocate actual array if needed + if constexpr (!inplace) { + actual = test::Array2D(dst_width, dst_height, padding, 1); + p_actual = &actual; + } + + // No specific values to test + test::PseudoRandomNumberGenerator generator; + source.fill(&generator); + + calculate_expected(source, expected); + + ASSERT_EQ(INTRINSICCV_OK, intrinsiccv_transpose( + source.data(), source.stride(), + p_actual->data(), p_actual->stride(), + src_width, src_height, sizeof(ElementType))); + + EXPECT_EQ_ARRAY2D(expected, *p_actual); + } + + protected: + static void calculate_expected(const test::Array2D &source, + test::Array2D &expected) { + for (size_t hindex = 0; hindex < source.height(); ++hindex) { + for (size_t vindex = 0; vindex < source.width(); ++vindex) { + // NOLINTBEGIN(clang-analyzer-core.uninitialized.Assign) + *expected.at(vindex, hindex) = *source.at(hindex, vindex); + // NOLINTEND(clang-analyzer-core.uninitialized.Assign) + } + } + } +}; + +template +class Transpose : public testing::Test {}; + +using ElementTypes = ::testing::Types; +TYPED_TEST_SUITE(Transpose, ElementTypes); + +TYPED_TEST(Transpose, ToNewBufferNoPadding) { + TestTranspose::test(0); +} + +TYPED_TEST(Transpose, ToNewBufferWithPadding) { + TestTranspose::test(1); +} + +TYPED_TEST(Transpose, InplaceNoPadding) { + TestTranspose::test(0); +} + +TYPED_TEST(Transpose, InplaceWithPadding) { + TestTranspose::test(1); +} -- GitLab