diff --git a/.devcontainer/coverage.sh b/.devcontainer/coverage.sh index d16b5ed1400754c3cd40f5712ea7f8c578525bb8..b4783498816d037535bf02122d52f79deaaf925a 100755 --- a/.devcontainer/coverage.sh +++ b/.devcontainer/coverage.sh @@ -16,10 +16,9 @@ EXTRA_CMAKE_ARGS="-DKLEIDICV_ENABLE_SVE2=ON -DKLEIDICV_ENABLE_SVE2_SELECTIVELY=O find build/kleidicv-coverage/ -type f -name *.gcda -delete LONG_VECTOR_TESTS="GRAY2.*:RGB*" -EXCLUDE_FLOAT_CONVERSION_TESTS="-FloatConversion*" qemu-aarch64 build/kleidicv-coverage/test/framework/kleidicv-framework-test -qemu-aarch64 -cpu cortex-a35 build/kleidicv-coverage/test/api/kleidicv-api-test --gtest_filter="${EXCLUDE_FLOAT_CONVERSION_TESTS}" +qemu-aarch64 -cpu cortex-a35 build/kleidicv-coverage/test/api/kleidicv-api-test qemu-aarch64 -cpu max,sve128=on,sme=off build/kleidicv-coverage/test/api/kleidicv-api-test --vector-length=16 qemu-aarch64 -cpu max,sve2048=on,sve-default-vector-length=256,sme=off \ build/kleidicv-coverage/test/api/kleidicv-api-test --gtest_filter="${LONG_VECTOR_TESTS}" --vector-length=256 diff --git a/adapters/opencv/kleidicv_hal.cpp b/adapters/opencv/kleidicv_hal.cpp index 17c191014d6377cfe741fb4e749f8fbad5debb0e..264e18dcf9521d5f04509c1cd51d9bebe8de0aa8 100644 --- a/adapters/opencv/kleidicv_hal.cpp +++ b/adapters/opencv/kleidicv_hal.cpp @@ -674,33 +674,6 @@ int convertTo(const uchar *src_data, size_t src_step, int src_depth, } } - // type conversion only - if (scale == 1.0 && shift == 0.0) { - // float32 to int8 - if (src_depth == CV_32F && dst_depth == CV_8S) { - return convert_error(kleidicv_float_conversion_f32_s8( - reinterpret_cast(src_data), src_step, - reinterpret_cast(dst_data), dst_step, width, height)); - } - // float32 to uint8 - if (src_depth == CV_32F && dst_depth == CV_8U) { - return convert_error(kleidicv_float_conversion_f32_u8( - reinterpret_cast(src_data), src_step, - reinterpret_cast(dst_data), dst_step, width, height)); - } - // int8 to float32 - if (src_depth == CV_8S && dst_depth == CV_32F) { - return convert_error(kleidicv_float_conversion_s8_f32( - reinterpret_cast(src_data), src_step, - reinterpret_cast(dst_data), dst_step, width, height)); - } - // uint8 to float32 - if (src_depth == CV_8U && dst_depth == CV_32F) { - return convert_error(kleidicv_float_conversion_u8_f32( - reinterpret_cast(src_data), src_step, - reinterpret_cast(dst_data), dst_step, width, height)); - } - } return CV_HAL_ERROR_NOT_IMPLEMENTED; } diff --git a/conformity/opencv/CMakeLists.txt b/conformity/opencv/CMakeLists.txt index c2fe46ac1c027247669dd70fedecf23e808978dc..360b44619577f5c6d0f37b8b20f28ff2d664fc68 100644 --- a/conformity/opencv/CMakeLists.txt +++ b/conformity/opencv/CMakeLists.txt @@ -32,7 +32,6 @@ add_executable( tests.cpp test_sobel.cpp test_gaussian_blur.cpp - test_float_conv.cpp ) target_link_libraries( @@ -69,7 +68,6 @@ add_executable( tests.cpp test_sobel.cpp test_gaussian_blur.cpp - test_float_conv.cpp ) target_link_libraries( diff --git a/conformity/opencv/test_float_conv.cpp b/conformity/opencv/test_float_conv.cpp deleted file mode 100644 index 8f7ca6a81e8f07966931799e60c29a533d2f5809..0000000000000000000000000000000000000000 --- a/conformity/opencv/test_float_conv.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#include "test_float_conv.h" - -#include - -float floatval(uint32_t v) { - static_assert(sizeof(float) == 4); - return *reinterpret_cast(&v); -} - -float quietNaN = floatval(0x7FC00000); -float signalingNaN = floatval(0x7FA00000); -float posInfinity = floatval(0x7F800000); -float negInfinity = floatval(0xFF800000); - -float minusNaN = floatval(0xFF800001); -float plusNaN = floatval(0x7F800001); -float plusZero = floatval(0x00000000); -float minusZero = floatval(0x80000000); - -float oneNaN = floatval(0x7FC00001); -float zeroDivZero = floatval(0xFFC00000); -float floatMin = floatval(0x00800000); -float floatMax = floatval(0x7F7FFFFF); - -float posSubnormalMin = floatval(0x00000001); -float posSubnormalMax = floatval(0x007FFFFF); -float negSubnormalMin = floatval(0x80000001); -float negSubnormalMax = floatval(0x807FFFFF); - -template -cv::Mat exec_float32_to_int8(cv::Mat& input) { - cv::Mat result; - input.convertTo(result, Signed ? CV_8SC1 : CV_8UC1); - return result; -} - -cv::Mat exec_int8_to_float32(cv::Mat& input) { - cv::Mat result; - input.convertTo(result, CV_32FC1); - return result; -} - -#if MANAGER -template -bool test_float32_to_int8_random(int index, - RecreatedMessageQueue& request_queue, - RecreatedMessageQueue& reply_queue) { - cv::RNG rng(0); - - for (size_t x = 5; x <= 16; ++x) { - for (size_t y = 5; y <= 16; ++y) { - cv::Mat input(x, y, CV_32FC(Channels)); - rng.fill(input, cv::RNG::UNIFORM, Signed ? -1000 : 0, 1000); - - cv::Mat actual = exec_float32_to_int8(input); - cv::Mat expected = get_expected_from_subordinate(index, request_queue, - reply_queue, input); - - if (are_matrices_different(0, actual, expected)) { - fail_print_matrices(x, y, input, actual, expected); - return true; - } - } - } - - return false; -} - -template -bool test_int8_to_float32_random(int index, - RecreatedMessageQueue& request_queue, - RecreatedMessageQueue& reply_queue) { - cv::RNG rng(0); - - for (size_t x = 5; x <= 16; ++x) { - for (size_t y = 5; y <= 16; ++y) { - cv::Mat input(x, y, Signed ? CV_8SC(Channels) : CV_8UC(Channels)); - rng.fill(input, cv::RNG::UNIFORM, Signed ? -1000 : 0, 1000); - - cv::Mat actual = exec_int8_to_float32(input); - cv::Mat expected = get_expected_from_subordinate(index, request_queue, - reply_queue, input); - - if (are_matrices_different(0, actual, expected)) { - fail_print_matrices(x, y, input, actual, expected); - return true; - } - } - } - - return false; -} - -static constexpr int custom_data_float_height = 8; -static constexpr int custom_data_float_width = 4; - -static float - custom_data_float[custom_data_float_height * custom_data_float_width] = { - // clang-format off - quietNaN, signalingNaN, posInfinity, negInfinity, - minusNaN, plusNaN, plusZero, minusZero, - oneNaN, zeroDivZero, floatMin, floatMax, - posSubnormalMin, posSubnormalMax, negSubnormalMin, negSubnormalMax, - 1111.11, -1112.22, 113.33, 114.44, - 111.51, 112.62, 113.73, 114.84, - 126.66, 127.11, 128.66, 129.11, - 11.5, 12.5, -11.5, -12.5, - // clang-format on -}; - -static constexpr int custom_data_int8_height = 1; -static constexpr int custom_data_int8_width = 7; - -static int8_t - custom_data_int8[custom_data_int8_height * custom_data_int8_width] = { - // clang-format off - -128, -127, -1, 0, 1, 126, 127 - // clang-format on -}; - -static uint8_t - custom_data_uint8[custom_data_int8_height * custom_data_int8_width] = { - // clang-format off - 0, 1, 126, 127, 128, 254, 255 - // clang-format on -}; - -template -bool test_float32_to_int8_custom(int index, - RecreatedMessageQueue& request_queue, - RecreatedMessageQueue& reply_queue) { - cv::Mat input(custom_data_float_height, custom_data_float_width, CV_32FC1, - custom_data_float); - - cv::Mat actual = exec_float32_to_int8(input); - cv::Mat expected = - get_expected_from_subordinate(index, request_queue, reply_queue, input); - - if (are_matrices_different(0, actual, expected)) { - fail_print_matrices(custom_data_float_height, custom_data_float_width, - input, actual, expected); - return true; - } - - return false; -} - -template -bool test_int8_to_float32_custom(int index, - RecreatedMessageQueue& request_queue, - RecreatedMessageQueue& reply_queue) { - cv::Mat input(custom_data_int8_height, custom_data_int8_width, - Signed ? CV_8SC1 : CV_8UC1, - Signed ? static_cast(custom_data_int8) - : static_cast(custom_data_uint8)); - - cv::Mat actual = exec_int8_to_float32(input); - cv::Mat expected = - get_expected_from_subordinate(index, request_queue, reply_queue, input); - - if (are_matrices_different(0, actual, expected)) { - fail_print_matrices(custom_data_int8_height, custom_data_int8_width, input, - actual, expected); - return true; - } - - return false; -} -#endif - -std::vector& float_conversion_tests_get() { - // clang-format off - static std::vector tests = { - TEST("Float32 to Signed Int8, fill, 1 channel", (test_float32_to_int8_random), exec_float32_to_int8), - TEST("Float32 to Signed Int8, fill, 2 channel", (test_float32_to_int8_random), exec_float32_to_int8), - TEST("Float32 to Signed Int8, fill, 3 channel", (test_float32_to_int8_random), exec_float32_to_int8), - TEST("Float32 to Signed Int8, fill, 4 channel", (test_float32_to_int8_random), exec_float32_to_int8), - - TEST("Float32 to Unsigned Int8, fill, 1 channel", (test_float32_to_int8_random), exec_float32_to_int8), - TEST("Float32 to Unsigned Int8, fill, 2 channel", (test_float32_to_int8_random), exec_float32_to_int8), - TEST("Float32 to Unsigned Int8, fill, 3 channel", (test_float32_to_int8_random), exec_float32_to_int8), - TEST("Float32 to Unsigned Int8, fill, 4 channel", (test_float32_to_int8_random), exec_float32_to_int8), - - TEST("Float32 to Signed Int8, custom (special)", test_float32_to_int8_custom, exec_float32_to_int8), - TEST("Float32 to Unsigned Int8, custom (special)", test_float32_to_int8_custom, exec_float32_to_int8), - - TEST("Signed Int8 to Float32, fill, 1 channel", (test_int8_to_float32_random), exec_int8_to_float32), - TEST("Signed Int8 to Float32, fill, 2 channel", (test_int8_to_float32_random), exec_int8_to_float32), - TEST("Signed Int8 to Float32, fill, 3 channel", (test_int8_to_float32_random), exec_int8_to_float32), - TEST("Signed Int8 to Float32, fill, 4 channel", (test_int8_to_float32_random), exec_int8_to_float32), - - TEST("Unsigned Int8 to Float32, fill, 1 channel", (test_int8_to_float32_random), exec_int8_to_float32), - TEST("Unsigned Int8 to Float32, fill, 2 channel", (test_int8_to_float32_random), exec_int8_to_float32), - TEST("Unsigned Int8 to Float32, fill, 3 channel", (test_int8_to_float32_random), exec_int8_to_float32), - TEST("Unsigned Int8 to Float32, fill, 4 channel", (test_int8_to_float32_random), exec_int8_to_float32), - - TEST("Signed Int8 to Float32, custom", test_int8_to_float32_custom, exec_int8_to_float32), - TEST("Unigned Int8 to Float32, custom", test_int8_to_float32_custom, exec_int8_to_float32), - }; - // clang-format on - return tests; -} diff --git a/conformity/opencv/test_float_conv.h b/conformity/opencv/test_float_conv.h deleted file mode 100644 index 9e4c40be6f28f9d49e2ca3e525ce3fd6c395b094..0000000000000000000000000000000000000000 --- a/conformity/opencv/test_float_conv.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#ifndef KLEIDICV_OPENCV_CONFORMITY_TEST_FLOAT_CONV_H_ -#define KLEIDICV_OPENCV_CONFORMITY_TEST_FLOAT_CONV_H_ - -#include - -#include "tests.h" - -std::vector& float_conversion_tests_get(); - -#endif // KLEIDICV_OPENCV_CONFORMITY_TEST_FLOAT_CONV_H_ diff --git a/conformity/opencv/tests.cpp b/conformity/opencv/tests.cpp index 0fe97db16ad4c84388d2c4efebc79ec400332504..e5fd49e6fcfbcca7a8ea7877c9186c77a9e86d6b 100644 --- a/conformity/opencv/tests.cpp +++ b/conformity/opencv/tests.cpp @@ -10,7 +10,6 @@ #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" -#include "test_float_conv.h" #include "test_gaussian_blur.h" #include "test_sobel.h" @@ -27,7 +26,6 @@ static std::vector merge_tests( std::vector all_tests = merge_tests({ sobel_tests_get, gaussian_blur_tests_get, - float_conversion_tests_get, }); #if MANAGER diff --git a/kleidicv/include/kleidicv/kleidicv.h b/kleidicv/include/kleidicv/kleidicv.h index 48283d67b95fd36ccbf1d6db688799000e6bdd33..48a8ed54d9898d3991f797b04a3486f982dca6b7 100644 --- a/kleidicv/include/kleidicv/kleidicv.h +++ b/kleidicv/include/kleidicv/kleidicv.h @@ -1254,65 +1254,6 @@ KLEIDICV_API_DECLARATION(kleidicv_scale_u8, const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, size_t width, size_t height, float scale, float shift); -/// Converts the elements in `src` from a floating-point type to an integer -/// type, then stores the result in `dst`. -/// -/// Each resulting element is saturated, i.e. it is the smallest/largest -/// number of the type of the element if the `src` data type cannot be -/// represented as the `dst` type. In case of some special values, such as the -/// different variations of `NaN`, the result is `0`. Source and destination -/// data length is `width` * `height`. Number of elements is limited to @ref -/// KLEIDICV_MAX_IMAGE_PIXELS. -/// -/// @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 * sizeof(type). -/// @param dst Pointer to the destination data. Must be non-null. -/// @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 width * sizeof(type). -/// @param width Number of elements in a row. -/// @param height Number of rows in the data. -/// -KLEIDICV_API_DECLARATION(kleidicv_float_conversion_f32_s8, const float *src, - size_t src_stride, int8_t *dst, size_t dst_stride, - size_t width, size_t height); -/// @copydoc kleidicv_float_conversion_f32_s8 -KLEIDICV_API_DECLARATION(kleidicv_float_conversion_f32_u8, const float *src, - size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height); - -/// Converts the elements in `src` from an integer type to a floating-point -/// type, then stores the result in `dst`. -/// -/// Each resulting element is saturated, i.e. it is the smallest/largest -/// number of the type of the element if the `src` data type cannot be -/// represented as the `dst` type. Source and destination data length is -/// `width` * `height`. Number of elements is limited to @ref -/// KLEIDICV_MAX_IMAGE_PIXELS. -/// -/// @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 * sizeof(type). -/// Must be a multiple of sizeof(type). -/// @param dst Pointer to the destination data. Must be non-null. -/// @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 width * sizeof(type). -/// Must be a multiple of sizeof(type). -/// @param width Number of pixels in a row. -/// @param height Number of rows in the data. -/// -KLEIDICV_API_DECLARATION(kleidicv_float_conversion_s8_f32, const int8_t *src, - size_t src_stride, float *dst, size_t dst_stride, - size_t width, size_t height); -/// @copydoc kleidicv_float_conversion_s8_f32 -KLEIDICV_API_DECLARATION(kleidicv_float_conversion_u8_f32, const uint8_t *src, - size_t src_stride, float *dst, size_t dst_stride, - size_t width, size_t height); - #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/kleidicv/src/conversions/float_conv_api.cpp b/kleidicv/src/conversions/float_conv_api.cpp deleted file mode 100644 index 0f3fdea2dcc1a00a80a99eba948063d34ea28315..0000000000000000000000000000000000000000 --- a/kleidicv/src/conversions/float_conv_api.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#include "kleidicv/dispatch.h" -#include "kleidicv/kleidicv.h" -#include "kleidicv/types.h" - -namespace kleidicv { - -namespace neon { - -template -kleidicv_error_t float_conversion(const InputType* src, size_t src_stride, - OutputType* dst, size_t dst_stride, - size_t width, size_t height); - -} // namespace neon - -namespace sve2 { - -template -kleidicv_error_t float_conversion(const InputType* src, size_t src_stride, - OutputType* dst, size_t dst_stride, - size_t width, size_t height); - -} // namespace sve2 - -namespace sme2 { - -template -kleidicv_error_t float_conversion(const InputType* src, size_t src_stride, - OutputType* dst, size_t dst_stride, - size_t width, size_t height); - -} // namespace sme2 - -#ifdef KLEIDICV_HAVE_SVE2 -#define SVE2_FUNC_POINTER(name, itype, otype) \ - [[maybe_unused]] static auto sve2_func_##itype##_##otype = \ - kleidicv::sve2::float_conversion; -#else -#define SVE2_FUNC_POINTER(name, itype, otype) -#endif // KLEIDICV_HAVE_SVE2 - -#ifdef KLEIDICV_HAVE_SME2 -#define SME2_FUNC_POINTER(name, itype, otype) \ - static auto sme2_func_##itype##_##otype = \ - kleidicv::sme2::float_conversion; -#else -#define SME2_FUNC_POINTER(name, itype, otype) -#endif // KLEIDICV_HAVE_SME2 - -// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) -#define KLEIDICV_DEFINE_C_API(name, itype, otype) \ - static auto neon_func_##itype##_##otype = \ - kleidicv::neon::float_conversion; \ - SVE2_FUNC_POINTER(name, itype, otype); \ - SME2_FUNC_POINTER(name, itype, otype); \ - KLEIDICV_MULTIVERSION_C_API( \ - name, neon_func_##itype##_##otype, \ - KLEIDICV_SVE2_IMPL_IF(sve2_func_##itype##_##otype), \ - sme2_func_##itype##_##otype) -// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) - -KLEIDICV_DEFINE_C_API(kleidicv_float_conversion_f32_s8, float, int8_t); -KLEIDICV_DEFINE_C_API(kleidicv_float_conversion_f32_u8, float, uint8_t); -KLEIDICV_DEFINE_C_API(kleidicv_float_conversion_s8_f32, int8_t, float); -KLEIDICV_DEFINE_C_API(kleidicv_float_conversion_u8_f32, uint8_t, float); - -} // namespace kleidicv diff --git a/kleidicv/src/conversions/float_conv_neon.cpp b/kleidicv/src/conversions/float_conv_neon.cpp deleted file mode 100644 index b6e1fe0a8a9fc5e479e812094fe0142195283ca5..0000000000000000000000000000000000000000 --- a/kleidicv/src/conversions/float_conv_neon.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#include "kleidicv/kleidicv.h" -#include "kleidicv/neon.h" - -namespace kleidicv::neon { - -template -kleidicv_error_t float_conversion(const InputType*, size_t, OutputType*, size_t, - size_t, size_t) { - return KLEIDICV_ERROR_NOT_IMPLEMENTED; -} - -#define KLEIDICV_INSTANTIATE_TEMPLATE(itype, otype) \ - template KLEIDICV_TARGET_FN_ATTRS kleidicv_error_t \ - float_conversion(const itype* src, size_t src_stride, \ - otype* dst, size_t dst_stride, size_t width, \ - size_t height) - -KLEIDICV_INSTANTIATE_TEMPLATE(float, int8_t); -KLEIDICV_INSTANTIATE_TEMPLATE(float, uint8_t); -KLEIDICV_INSTANTIATE_TEMPLATE(int8_t, float); -KLEIDICV_INSTANTIATE_TEMPLATE(uint8_t, float); - -} // namespace kleidicv::neon diff --git a/kleidicv/src/conversions/float_conv_sc.h b/kleidicv/src/conversions/float_conv_sc.h deleted file mode 100644 index e04884112471ca2a8ec77d6ad4f7d1613cba9399..0000000000000000000000000000000000000000 --- a/kleidicv/src/conversions/float_conv_sc.h +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#ifndef KLEIDICV_FLOAT_CONV_SC_H -#define KLEIDICV_FLOAT_CONV_SC_H - -#include -#include - -#include "kleidicv/kleidicv.h" -#include "kleidicv/sve2.h" - -namespace KLEIDICV_TARGET_NAMESPACE { - -template -class float_conversion_operation; - -template -class float_conversion_operation { - public: - using SrcVecTraits = KLEIDICV_TARGET_NAMESPACE::VecTraits; - using SrcVectorType = typename SrcVecTraits::VectorType; - using IntermediateVecTraits = KLEIDICV_TARGET_NAMESPACE::VecTraits< - std::conditional_t, int32_t, uint32_t>>; - using IntermediateVectorType = typename IntermediateVecTraits::VectorType; - - void process_row(size_t width, Columns src, - Columns dst) KLEIDICV_STREAMING_COMPATIBLE { - LoopUnroll{width, SrcVecTraits::num_lanes()} - .unroll_twice([&](size_t step) KLEIDICV_STREAMING_COMPATIBLE { - svbool_t pg = SrcVecTraits::svptrue(); - SrcVectorType src_vector1 = svld1(pg, &src[0]); - SrcVectorType src_vector2 = svld1_vnum(pg, &src[0], 1); - IntermediateVectorType result_vector1 = - vector_path(pg, src_vector1); - IntermediateVectorType result_vector2 = - vector_path(pg, src_vector2); - svst1b(pg, &dst[0], result_vector1); - svst1b_vnum(pg, &dst[0], 1, result_vector2); - src += ptrdiff_t(step); - dst += ptrdiff_t(step); - }) - .remaining([&](size_t length, size_t) KLEIDICV_STREAMING_COMPATIBLE { - size_t index = 0; - svbool_t pg = SrcVecTraits::svwhilelt(index, length); - while (svptest_first(SrcVecTraits::svptrue(), pg)) { - SrcVectorType src_vector = svld1(pg, &src[ptrdiff_t(index)]); - IntermediateVectorType result_vector = - vector_path(pg, src_vector); - svst1b(pg, &dst[ptrdiff_t(index)], result_vector); - // Update loop counter and calculate the next governing predicate. - index += SrcVecTraits::num_lanes(); - pg = SrcVecTraits::svwhilelt(index, length); - } - }); - } - - private: - template < - typename O, - std::enable_if_t && std::is_signed_v, int> = 0> - IntermediateVectorType vector_path(svbool_t& pg, SrcVectorType src) - KLEIDICV_STREAMING_COMPATIBLE { - constexpr float min_val = std::numeric_limits::min(); - constexpr float max_val = std::numeric_limits::max(); - - src = svrinti_f32_x(pg, src); - - svbool_t less = svcmplt_n_f32(pg, src, min_val); - src = svdup_n_f32_m(src, less, min_val); - - svbool_t greater = svcmpgt_n_f32(pg, src, max_val); - src = svdup_n_f32_m(src, greater, max_val); - - return svcvt_s32_f32_x(pg, src); - } - - template < - typename O, - std::enable_if_t && !std::is_signed_v, int> = 0> - IntermediateVectorType vector_path(svbool_t& pg, SrcVectorType src) - KLEIDICV_STREAMING_COMPATIBLE { - constexpr float max_val = std::numeric_limits::max(); - - src = svrinti_f32_x(pg, src); - - svbool_t greater = svcmpgt_n_f32(pg, src, max_val); - src = svdup_n_f32_m(src, greater, max_val); - - return svcvt_u32_f32_x(pg, src); - } -}; // end of class float_conversion_operation - -template -class float_conversion_operation { - public: - using VecTraits = KLEIDICV_TARGET_NAMESPACE::VecTraits; - using VectorType = typename VecTraits::VectorType; - void process_row(size_t width, Columns src, - Columns dst) { - LoopUnroll{width, VecTraits::num_lanes()} - .unroll_twice([&](size_t step) KLEIDICV_STREAMING_COMPATIBLE { - svbool_t pg = VecTraits::svptrue(); - VectorType dst_vector1 = vector_path(pg, &src[0]); - VectorType dst_vector2 = vector_path( - pg, &src.at(ptrdiff_t(VecTraits::num_lanes()))[0]); - svst1(pg, &dst[0], dst_vector1); - svst1_vnum(pg, &dst[0], 1, dst_vector2); - src += ptrdiff_t(step); - dst += ptrdiff_t(step); - }) - .remaining([&](size_t length, size_t) KLEIDICV_STREAMING_COMPATIBLE { - size_t index = 0; - svbool_t pg = VecTraits::svwhilelt(index, length); - while (svptest_first(VecTraits::svptrue(), pg)) { - VectorType dst_vector = - vector_path(pg, &src[ptrdiff_t(index)]); - svst1(pg, &dst[ptrdiff_t(index)], dst_vector); - // Update loop counter and calculate the next governing predicate. - index += VecTraits::num_lanes(); - pg = VecTraits::svwhilelt(index, length); - } - }); - } - - private: - template < - typename I, - std::enable_if_t && std::is_signed_v, int> = 0> - VectorType vector_path(svbool_t& pg, - const I* src) KLEIDICV_STREAMING_COMPATIBLE { - svint32_t src_vector = svld1sb_s32(pg, src); - return svcvt_f32_s32_x(pg, src_vector); - } - - template < - typename I, - std::enable_if_t && !std::is_signed_v, int> = 0> - VectorType vector_path(svbool_t& pg, - const I* src) KLEIDICV_STREAMING_COMPATIBLE { - svuint32_t src_vector = svld1ub_u32(pg, src); - return svcvt_f32_u32_x(pg, src_vector); - } -}; // end of class float_conversion_operation - -template -static kleidicv_error_t float_conversion_sc( - const I* src, size_t src_stride, O* dst, size_t dst_stride, size_t width, - size_t height) KLEIDICV_STREAMING_COMPATIBLE { - CHECK_POINTER_AND_STRIDE(src, src_stride); - CHECK_POINTER_AND_STRIDE(dst, dst_stride); - CHECK_IMAGE_SIZE(width, height); - - float_conversion_operation operation; - Rectangle rect{width, height}; - Rows src_rows{src, src_stride}; - Rows dst_rows{dst, dst_stride}; - zip_rows(operation, rect, src_rows, dst_rows); - - return KLEIDICV_OK; -} - -} // namespace KLEIDICV_TARGET_NAMESPACE - -#endif // KLEIDICV_FLOAT_CONV_SC_H diff --git a/kleidicv/src/conversions/float_conv_sme2.cpp b/kleidicv/src/conversions/float_conv_sme2.cpp deleted file mode 100644 index 49832008a06f080bdd47d0972b883f618fd801a2..0000000000000000000000000000000000000000 --- a/kleidicv/src/conversions/float_conv_sme2.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#include "float_conv_sc.h" - -namespace kleidicv::sme2 { - -template -KLEIDICV_LOCALLY_STREAMING KLEIDICV_TARGET_FN_ATTRS kleidicv_error_t -float_conversion(const InputType* src, size_t src_stride, OutputType* dst, - size_t dst_stride, size_t width, size_t height) { - return float_conversion_sc(src, src_stride, dst, - dst_stride, width, height); -} - -#define KLEIDICV_INSTANTIATE_TEMPLATE(itype, otype) \ - template KLEIDICV_TARGET_FN_ATTRS kleidicv_error_t \ - float_conversion(const itype* src, size_t src_stride, \ - otype* dst, size_t dst_stride, size_t width, \ - size_t height) - -KLEIDICV_INSTANTIATE_TEMPLATE(float, int8_t); -KLEIDICV_INSTANTIATE_TEMPLATE(float, uint8_t); -KLEIDICV_INSTANTIATE_TEMPLATE(int8_t, float); -KLEIDICV_INSTANTIATE_TEMPLATE(uint8_t, float); - -} // namespace kleidicv::sme2 diff --git a/kleidicv/src/conversions/float_conv_sve2.cpp b/kleidicv/src/conversions/float_conv_sve2.cpp deleted file mode 100644 index 6bbd5d72e12ff1118dafcbe756834df90c388121..0000000000000000000000000000000000000000 --- a/kleidicv/src/conversions/float_conv_sve2.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#include "float_conv_sc.h" - -namespace kleidicv::sve2 { - -template -KLEIDICV_TARGET_FN_ATTRS kleidicv_error_t -float_conversion(const InputType* src, size_t src_stride, OutputType* dst, - size_t dst_stride, size_t width, size_t height) { - return float_conversion_sc(src, src_stride, dst, - dst_stride, width, height); -} - -#define KLEIDICV_INSTANTIATE_TEMPLATE(itype, otype) \ - template KLEIDICV_TARGET_FN_ATTRS kleidicv_error_t \ - float_conversion(const itype* src, size_t src_stride, \ - otype* dst, size_t dst_stride, size_t width, \ - size_t height) - -KLEIDICV_INSTANTIATE_TEMPLATE(float, int8_t); -KLEIDICV_INSTANTIATE_TEMPLATE(float, uint8_t); -KLEIDICV_INSTANTIATE_TEMPLATE(int8_t, float); -KLEIDICV_INSTANTIATE_TEMPLATE(uint8_t, float); - -} // namespace kleidicv::sve2 diff --git a/scripts/ci.sh b/scripts/ci.sh index 27bad74fce64be49d6052bfae0af2004bf144670..7f444b1ab2832c3d4cc303bc3c145fd1d58953b8 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -52,17 +52,16 @@ ninja -C build/gcc # Run tests LONG_VECTOR_TESTS="GRAY2.*:RGB*" -EXCLUDE_FLOAT_CONVERSION_TESTS="-FloatConversion*" TESTRESULT=0 qemu-aarch64 build/test/framework/kleidicv-framework-test --gtest_output=xml:build/test-results/ || TESTRESULT=1 -qemu-aarch64 -cpu cortex-a35 build/test/api/kleidicv-api-test --gtest_filter="${EXCLUDE_FLOAT_CONVERSION_TESTS}" --gtest_output=xml:build/test-results/clang-neon/ || TESTRESULT=1 +qemu-aarch64 -cpu cortex-a35 build/test/api/kleidicv-api-test --gtest_output=xml:build/test-results/clang-neon/ || TESTRESULT=1 qemu-aarch64 -cpu max,sve128=on,sme=off \ build/test/api/kleidicv-api-test --gtest_output=xml:build/test-results/clang-sve128/ --vector-length=16 || TESTRESULT=1 qemu-aarch64 -cpu max,sve2048=on,sve-default-vector-length=256,sme=off \ build/test/api/kleidicv-api-test --gtest_filter="${LONG_VECTOR_TESTS}" --gtest_output=xml:build/test-results/clang-sve2048/ --vector-length=256 || TESTRESULT=1 qemu-aarch64 -cpu max,sve128=on,sme512=on \ build/test/api/kleidicv-api-test --gtest_output=xml:build/test-results/clang-sme/ --vector-length=64 || TESTRESULT=1 -qemu-aarch64 -cpu cortex-a35 build/gcc/test/api/kleidicv-api-test --gtest_filter="${EXCLUDE_FLOAT_CONVERSION_TESTS}" --gtest_output=xml:build/test-results/gcc-neon/ || TESTRESULT=1 +qemu-aarch64 -cpu cortex-a35 build/gcc/test/api/kleidicv-api-test --gtest_output=xml:build/test-results/gcc-neon/ || TESTRESULT=1 scripts/prefix_testsuite_names.py build/test-results/clang-neon/kleidicv-api-test.xml "clang-neon." scripts/prefix_testsuite_names.py build/test-results/clang-sve128/kleidicv-api-test.xml "clang-sve128." @@ -81,7 +80,7 @@ if [[ $(dpkg --print-architecture) = arm64 ]]; then -DKLEIDICV_ENABLE_SME2=OFF \ -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-sanitize-recover=all -Wno-pass-failed" ninja -C build/sanitize kleidicv-api-test - build/sanitize/test/api/kleidicv-api-test --gtest_filter="${EXCLUDE_FLOAT_CONVERSION_TESTS}" + build/sanitize/test/api/kleidicv-api-test fi # Build benchmarks, just to prevent bitrot. diff --git a/test/api/test_float_conv.cpp b/test/api/test_float_conv.cpp deleted file mode 100644 index 49fdde174d3ba4ce27968e291bcdc324ac655434..0000000000000000000000000000000000000000 --- a/test/api/test_float_conv.cpp +++ /dev/null @@ -1,438 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates -// -// SPDX-License-Identifier: Apache-2.0 - -#include - -#include "framework/array.h" -#include "framework/generator.h" -#include "framework/operation.h" -#include "framework/utils.h" -#include "kleidicv/kleidicv.h" -#include "test_config.h" - -#define KLEIDICV_FLOAT_CONVERSION(itype, itype_name, otype, otype_name) \ - KLEIDICV_API_DIFFERENT_IO_TYPES( \ - float_conversion, kleidicv_float_conversion_##itype_name##_##otype_name, \ - itype, otype) - -KLEIDICV_FLOAT_CONVERSION(float, f32, int8_t, s8); -KLEIDICV_FLOAT_CONVERSION(float, f32, uint8_t, u8); -KLEIDICV_FLOAT_CONVERSION(int8_t, s8, float, f32); -KLEIDICV_FLOAT_CONVERSION(uint8_t, u8, float, f32); - -template -class FloatConversionTest final { - private: - template - static constexpr T min() { - return std::numeric_limits::min(); - } - - template - static constexpr T max() { - return std::numeric_limits::max(); - } - - struct Elements { - size_t width; - size_t height; - - std::vector> source_rows; - std::vector> expected_rows; - - Elements(size_t _width, size_t _height, - std::vector>&& _source_rows, - std::vector>&& _expected_rows) - : width(_width), - height(_height), - source_rows(std::move(_source_rows)), - expected_rows(std::move(_expected_rows)) {} - }; - - struct Values { - InputType source; - OutputType expected; - }; - - static constexpr uint32_t quietNaN = 0x7FC00000; - static constexpr uint32_t signalingNaN = 0x7FA00000; - static constexpr uint32_t posInfinity = 0x7F800000; - static constexpr uint32_t negInfinity = 0xFF800000; - - static constexpr uint32_t minusNaN = 0xFF800001; - static constexpr uint32_t plusNaN = 0x7F800001; - static constexpr uint32_t plusZero = 0x00000000; - static constexpr uint32_t minusZero = 0x80000000; - - static constexpr uint32_t oneNaN = 0x7FC00001; - static constexpr uint32_t zeroDivZero = 0xFFC00000; - static constexpr uint32_t floatMin = 0x00800000; - static constexpr uint32_t floatMax = 0x7F7FFFFF; - - static constexpr uint32_t posSubnormalMin = 0x00000001; - static constexpr uint32_t posSubnormalMax = 0x007FFFFF; - static constexpr uint32_t negSubnormalMin = 0x80000001; - static constexpr uint32_t negSubnormalMax = 0x807FFFFF; - - static constexpr float floatval(uint32_t v) { - static_assert(sizeof(float) == 4); - KLEIDICV_NO_STRICT_ALIASING_BEGIN - return *reinterpret_cast(&v); - KLEIDICV_NO_STRICT_ALIASING_END - } - - template , bool> = true, - std::enable_if_t, bool> = true> - const Elements& get_custom_elements() { - static const Elements kTestElements = { - // clang-format off - 4, 8, - {{ - { floatval(quietNaN), floatval(signalingNaN), floatval(posInfinity), floatval(negInfinity) }, - { floatval(minusNaN), floatval(plusNaN), floatval(plusZero), floatval(minusZero) }, - { floatval(oneNaN), floatval(zeroDivZero), floatval(floatMin), floatval(floatMax) }, - { floatval(posSubnormalMin), floatval(posSubnormalMax), floatval(negSubnormalMin), floatval(negSubnormalMax) }, - { 1111.11, -1112.22, 113.33, 114.44 }, - { 111.51, 112.62, 113.73, 114.84 }, - { 126.66, 127.11, 128.66, 129.11 }, - { 11.5, 12.5, -11.5, -12.5 } - }}, - {{ - { 0, 0, 127, -128 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 127 }, - { 0, 0, 0, 0 }, - { 127, -128, 113, 114 }, - { 112, 113, 114, 115 }, - { 127, 127, 127, 127 }, - { 12, 12, -12, -12 } - }} - // clang-format on - }; - return kTestElements; - } - - template , bool> = true, - std::enable_if_t, bool> = true> - const Elements& get_custom_elements() { - static const Elements kTestElements = { - // clang-format off - 4, 8, - {{ - { floatval(quietNaN), floatval(signalingNaN), floatval(posInfinity), floatval(negInfinity) }, - { floatval(minusNaN), floatval(plusNaN), floatval(plusZero), floatval(minusZero) }, - { floatval(oneNaN), floatval(zeroDivZero), floatval(floatMin), floatval(floatMax) }, - { floatval(posSubnormalMin), floatval(posSubnormalMax), floatval(negSubnormalMin), floatval(negSubnormalMax) }, - { 1111.11, -1112.22, 113.33, 114.44 }, - { 111.51, 112.62, 113.73, 114.84 }, - { 126.66, 127.11, 128.66, 129.11 }, - { 11.5, 12.5, -11.5, -12.5 } - }}, - {{ - { 0, 0, 255, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 255 }, - { 0, 0, 0, 0 }, - { 255, 0, 113, 114 }, - { 112, 113, 114, 115 }, - { 127, 127, 129, 129 }, - { 12, 12, 0, 0 } - }} - // clang-format on - }; - return kTestElements; - } - - template , bool> = true, - std::enable_if_t, bool> = true> - const Elements& get_custom_elements() { - static const Elements kTestElements = { - // clang-format off - 5, 1, - {{ - { min(), min() + 1, 0, max() - 1, max() } - }}, - {{ - { static_cast(min()), static_cast(min()) + 1.0, 0, - static_cast(max()) - 1.0, static_cast(max()) } - }} - // clang-format on - }; - return kTestElements; - } - - template , bool> = true, - std::enable_if_t, bool> = true> - const Values& get_values() { - static const Values kTestValues = { - // clang-format off - 10.67F, 11 - // clang-format on - }; - return kTestValues; - } - - template , bool> = true, - std::enable_if_t, bool> = true> - const Values& get_values() { - static const Values kTestValues = { - // clang-format off - 11, 11.0 - // clang-format on - }; - return kTestValues; - } - - template , bool> = true, - std::enable_if_t, bool> = true> - 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) { - O calculated = 0; - // NOLINTBEGIN(clang-analyzer-core.uninitialized.Assign) - I result = *source.at(hindex, vindex); - // NOLINTEND(clang-analyzer-core.uninitialized.Assign) - if (result > max()) { - calculated = max(); - } else if (result < min()) { - calculated = min(); - } else { - calculated = result; - } - *expected.at(hindex, vindex) = calculated; - } - } - } - - template , bool> = true, - std::enable_if_t, bool> = true> - 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(hindex, vindex) = *source.at(hindex, vindex); - // NOLINTEND(clang-analyzer-core.uninitialized.Assign) - } - } - } - - template - size_t get_linear_height(size_t width, size_t minimum_size) { - size_t image_size = - std::max(minimum_size, static_cast(max() - min())); - size_t height = image_size / width + 1; - - return height; - } - - template - std::tuple, test::Array2D, test::Array2D> - get_linear_arrays(size_t width, size_t height) { - test::Array2D source(width, height, 1, 1); - test::Array2D expected(width, height, 1, 1); - test::Array2D actual(width, height, 1, 1); - - if constexpr (std::is_same_v && std::is_integral_v) { - test::GenerateLinearSeries generator(min()); - source.fill(generator); - } else if constexpr (std::is_integral_v && std::is_same_v) { - test::GenerateLinearSeries generator(min()); - source.fill(generator); - } else { - static_assert(sizeof(I) == 0 && sizeof(O) == 0, "should never happen"); - } - - calculate_expected(source, expected); - - return {source, expected, actual}; - } - - public: - // minimum_size set by caller to trigger the 'big' conversion path. - template - void test_linear(size_t width, size_t minimum_size = 1) { - size_t height = 0; - if constexpr (std::is_same_v && std::is_integral_v) { - height = get_linear_height(width, minimum_size); - } else if constexpr (std::is_integral_v && std::is_same_v) { - height = get_linear_height(width, minimum_size); - } else { - static_assert(sizeof(I) == 0 && sizeof(O) == 0, "should never happen"); - } - - auto arrays = get_linear_arrays(width, height); - - test::Array2D& source = std::get<0>(arrays); - test::Array2D& expected = std::get<1>(arrays); - test::Array2D& actual = std::get<2>(arrays); - - ASSERT_EQ(KLEIDICV_OK, (float_conversion()( - source.data(), source.stride(), actual.data(), - actual.stride(), width, height))); - - EXPECT_EQ_ARRAY2D(expected, actual); - } - - void test_custom() { - auto elements_list = get_custom_elements(); - const size_t& width = elements_list.width; - const size_t& height = elements_list.height; - - test::Array2D source(width, height); - test::Array2D expected(width, height); - test::Array2D actual(width, height); - - for (size_t i = 0; i < height; i++) { - source.set(i, 0, elements_list.source_rows[i]); - expected.set(i, 0, elements_list.expected_rows[i]); - } - - ASSERT_EQ(KLEIDICV_OK, (float_conversion()( - source.data(), source.stride(), actual.data(), - actual.stride(), width, height))); - - EXPECT_EQ_ARRAY2D(expected, actual); - } - - void test_sizes(const size_t width, const size_t height) { - auto values_list = get_values(); - - test::Array2D source(width, height, 1, 1); - test::Array2D expected(width, height, 1, 1); - test::Array2D actual(width, height, 1, 1); - - source.fill(values_list.source); - expected.fill(values_list.expected); - - actual.fill(0); - - ASSERT_EQ(KLEIDICV_OK, (float_conversion()( - source.data(), source.stride(), actual.data(), - actual.stride(), width, height))); - - EXPECT_EQ_ARRAY2D(expected, actual); - } -}; // end of class FloatConversionTest - -template -class FloatConversion : public testing::Test {}; - -using ElementTypes = - ::testing::Types, std::pair, - std::pair, std::pair>; - -// Tests kleidicv_float_conversion API. -TYPED_TEST_SUITE(FloatConversion, ElementTypes); - -TYPED_TEST(FloatConversion, NullPointer) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - InputType src[1] = {}; - OutputType dst[1]; - test::test_null_args(float_conversion(), src, - sizeof(InputType), dst, sizeof(OutputType), 1, 1); -} - -TYPED_TEST(FloatConversion, OversizeImage) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - InputType src[1] = {}; - OutputType dst[1]; - EXPECT_EQ(KLEIDICV_ERROR_RANGE, - (float_conversion()( - src, sizeof(InputType), dst, sizeof(OutputType), - KLEIDICV_MAX_IMAGE_PIXELS + 1, 1))); - EXPECT_EQ(KLEIDICV_ERROR_RANGE, - (float_conversion()( - src, sizeof(InputType), dst, sizeof(OutputType), 1, - KLEIDICV_MAX_IMAGE_PIXELS + 1))); - EXPECT_EQ(KLEIDICV_ERROR_RANGE, - (float_conversion()( - src, sizeof(TypeParam), dst, sizeof(OutputType), - KLEIDICV_MAX_IMAGE_PIXELS + 1, KLEIDICV_MAX_IMAGE_PIXELS + 1))); -} - -TYPED_TEST(FloatConversion, Scalar) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{} - .template test_linear( - test::Options::vector_length() - 1); -} -TYPED_TEST(FloatConversion, Vector) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{} - .template test_linear( - test::Options::vector_length() * 2); -} -TYPED_TEST(FloatConversion, Custom) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_custom(); -} -TYPED_TEST(FloatConversion, CustomFits128VectorSize) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(4, 1); -} -TYPED_TEST(FloatConversion, CustomFits128VectorSize2x) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(4, 2); -} -TYPED_TEST(FloatConversion, CustomFits128VectorSize3x) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(4, 3); -} -TYPED_TEST(FloatConversion, CustomFits512VectorSize) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(4, 4); -} -TYPED_TEST(FloatConversion, CustomFits512VectorSize2x) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(4, 8); -} -TYPED_TEST(FloatConversion, CustomFits512VectorSize3x) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(6, 8); -} -TYPED_TEST(FloatConversion, Custom128OneRemaining) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(1, 17); -} -TYPED_TEST(FloatConversion, Custom128AllButOneRemaining) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(5, 3); -} -TYPED_TEST(FloatConversion, CustomAboutHalfRemaining) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(19, 2); -} -TYPED_TEST(FloatConversion, CustomEmpty) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(0, 0); -} -TYPED_TEST(FloatConversion, CustomOne) { - using InputType = typename TypeParam::first_type; - using OutputType = typename TypeParam::second_type; - FloatConversionTest{}.test_sizes(1, 1); -}