From 7aa727dcc39b2b9db7c52e40772db1e926408f14 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 1 Aug 2025 18:09:57 -0500 Subject: [PATCH 01/20] Add gpu kernel unit testing infra --- src/targets/gpu/compile_hip_code_object.cpp | 27 +- .../migraphx/gpu/compile_hip_code_object.hpp | 3 + .../gpu/include/migraphx/gpu/kernel.hpp | 2 + src/targets/gpu/kernel.cpp | 5 + .../kernels/include/migraphx/kernels/test.hpp | 279 ++++++++++++++++++ test/CMakeLists.txt | 1 + test/gpu/kernels/CMakeLists.txt | 72 +++++ test/gpu/kernels/basic.cpp | 13 + test/gpu/kernels/main.cpp | 104 +++++++ test/include/test.hpp | 23 +- 10 files changed, 515 insertions(+), 14 deletions(-) create mode 100644 src/targets/gpu/kernels/include/migraphx/kernels/test.hpp create mode 100644 test/gpu/kernels/CMakeLists.txt create mode 100644 test/gpu/kernels/basic.cpp create mode 100644 test/gpu/kernels/main.cpp diff --git a/src/targets/gpu/compile_hip_code_object.cpp b/src/targets/gpu/compile_hip_code_object.cpp index 18e43691cab..7292971c295 100644 --- a/src/targets/gpu/compile_hip_code_object.cpp +++ b/src/targets/gpu/compile_hip_code_object.cpp @@ -169,14 +169,11 @@ std::size_t compute_block_size(const context& ctx, std::size_t n, std::size_t ma return std::min(std::max(min_block_size, block_size), max_block_size); } -operation -compile_hip_code_object(context& ctx, const std::string& content, hip_compile_options options) +std::vector +compile_hip_raw(context& ctx, const std::string& content, hip_compile_options options) { assert(options.global > 0); assert(options.local > 0); - assert(not options.inputs.empty()); - assert(options.inputs.size() == options.virtual_inputs.size() or - options.virtual_inputs.empty()); std::vector srcs = options.additional_src_files; static auto kernels{::migraphx_kernels()}; std::transform( @@ -185,9 +182,6 @@ compile_hip_code_object(context& ctx, const std::string& content, hip_compile_op std::back_inserter(srcs), [](const std::pair& elem) { return src_file{elem}; }); srcs.emplace_back("main.cpp", content); - auto args_hpp = - generate_args_hpp(options.virtual_inputs.empty() ? options.inputs : options.virtual_inputs); - srcs.emplace_back("args.hpp", args_hpp); if(options.global % options.local != 0 and hip_accept_non_uniform_wg()) options.emplace_param("-fno-offload-uniform-block"); @@ -202,10 +196,23 @@ compile_hip_code_object(context& ctx, const std::string& content, hip_compile_op options.params.insert(options.params.end(), warnings.begin(), warnings.end()); options.emplace_param("-ftemplate-backtrace-limit=0"); options.emplace_param("-Werror"); - auto cos = compile_hip_src(srcs, options.params, get_device_name()); + auto cos = compile_hip_src(srcs, options.params, ctx.get_current_device().get_device_name()); if(cos.size() != 1) MIGRAPHX_THROW("No code object"); - return code_object_op{value::binary{cos.front()}, + return cos.front(); +} + +operation +compile_hip_code_object(context& ctx, const std::string& content, hip_compile_options options) +{ + assert(not options.inputs.empty()); + assert(options.inputs.size() == options.virtual_inputs.size() or + options.virtual_inputs.empty()); + auto args_hpp = + generate_args_hpp(options.virtual_inputs.empty() ? options.inputs : options.virtual_inputs); + options.additional_src_files.emplace_back("args.hpp", args_hpp); + + return code_object_op{value::binary{compile_hip_raw(ctx, content, std::move(options))}, options.kernel_name, options.global, options.local, diff --git a/src/targets/gpu/include/migraphx/gpu/compile_hip_code_object.hpp b/src/targets/gpu/include/migraphx/gpu/compile_hip_code_object.hpp index 80662f7429c..f434348dbd5 100644 --- a/src/targets/gpu/include/migraphx/gpu/compile_hip_code_object.hpp +++ b/src/targets/gpu/include/migraphx/gpu/compile_hip_code_object.hpp @@ -73,6 +73,9 @@ struct hip_compile_options MIGRAPHX_GPU_EXPORT std::function compute_global_for(const context& ctx, std::size_t n, std::size_t over = 1); +MIGRAPHX_GPU_EXPORT std::vector +compile_hip_raw(context& ctx, const std::string& content, hip_compile_options options); + MIGRAPHX_GPU_EXPORT operation compile_hip_code_object(context& ctx, const std::string& content, hip_compile_options options); diff --git a/src/targets/gpu/include/migraphx/gpu/kernel.hpp b/src/targets/gpu/include/migraphx/gpu/kernel.hpp index 63accdea4d8..4788c314820 100644 --- a/src/targets/gpu/include/migraphx/gpu/kernel.hpp +++ b/src/targets/gpu/include/migraphx/gpu/kernel.hpp @@ -47,6 +47,8 @@ struct MIGRAPHX_GPU_EXPORT kernel { } + bool empty() const; + void launch(hipStream_t stream, std::size_t global, std::size_t local, diff --git a/src/targets/gpu/kernel.cpp b/src/targets/gpu/kernel.cpp index 09fad678f3a..7725691d935 100644 --- a/src/targets/gpu/kernel.cpp +++ b/src/targets/gpu/kernel.cpp @@ -79,6 +79,11 @@ kernel::kernel(const char* image, const std::string& name) : impl(std::make_shar MIGRAPHX_THROW("Failed to get function: " + name + ": " + hip_error(status)); } +bool kernel::empty() const +{ + return impl == nullptr; +} + static void launch_kernel(hipFunction_t fun, hipStream_t stream, std::size_t global, diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp new file mode 100644 index 00000000000..9c3f67f906b --- /dev/null +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -0,0 +1,279 @@ +#ifndef MIGRAPHX_GUARD_KERNELS_TEST_HPP +#define MIGRAPHX_GUARD_KERNELS_TEST_HPP + +#include +#include + +namespace migraphx { + +namespace test { + +template +struct rank : rank +{ +}; + +template <> +struct rank<0> +{ +}; + +// clang-format off +// NOLINTNEXTLINE +#define TEST_FOREACH_BINARY_OPERATORS(m) \ + m(==, equal) \ + m(!=, not_equal) \ + m(<=, less_than_equal) \ + m(>=, greater_than_equal) \ + m(<, less_than) \ + m(>, greater_than) \ + m(and, and_op) \ + m(or, or_op) +// clang-format on + +// clang-format off +// NOLINTNEXTLINE +#define TEST_FOREACH_UNARY_OPERATORS(m) \ + m(not, not_op) +// clang-format on + +// NOLINTNEXTLINE +#define TEST_EACH_BINARY_OPERATOR_OBJECT(op, name) \ + struct name \ + { \ + static constexpr const char* as_string() { return #op; } \ + template \ + static constexpr decltype(auto) call(T&& x, U&& y) \ + { \ + return x op y; \ + } \ + }; + +// NOLINTNEXTLINE +#define TEST_EACH_UNARY_OPERATOR_OBJECT(op, name) \ + struct name \ + { \ + static constexpr const char* as_string() { return #op; } \ + template \ + static constexpr decltype(auto) call(T&& x) \ + { \ + return op x; \ + } \ + }; + +TEST_FOREACH_BINARY_OPERATORS(TEST_EACH_BINARY_OPERATOR_OBJECT) +TEST_FOREACH_UNARY_OPERATORS(TEST_EACH_UNARY_OPERATOR_OBJECT) + +struct nop +{ + static constexpr const char* as_string() { return ""; } + template + static constexpr auto call(T&& x) + { + return static_cast(x); + } +}; + +struct function +{ + static constexpr const char* as_string() { return ""; } + template + static constexpr decltype(auto) call(T&& x) + { + return x(); + } +}; + +template +constexpr Stream& print_stream_impl(rank<0>, Stream& s, const T&) +{ + // TODO: Print typename + s << '?'; + return s; +} + +template +constexpr auto print_stream_impl(rank<1>, Stream& s, const T& x) + -> decltype(s << x) +{ + return s << x; +} + +template +constexpr void print_stream(Stream& s, const T& x) +{ + print_stream_impl(rank<2>{}, s, x); +} + +template +constexpr const T& get_value(const T& x) +{ + return x; +} + +template +struct lhs_expression; + +template +constexpr lhs_expression make_lhs_expression(T&& lhs); + +template +constexpr lhs_expression make_lhs_expression(T&& lhs, Operator); + +// NOLINTNEXTLINE +#define TEST_EXPR_BINARY_OPERATOR(op, name) \ + template \ + constexpr auto operator op(V&& rhs2) const \ + { \ + return make_expression(*this, static_cast(rhs2), name{}); /* NOLINT */ \ + } + +// NOLINTNEXTLINE +#define TEST_EXPR_UNARY_OPERATOR(op, name) \ + constexpr auto operator op() const { return make_lhs_expression(lhs, name{}); /* NOLINT */ } + +template +struct expression +{ + T lhs; + U rhs; + + template + friend constexpr Stream& operator<<(Stream& s, const expression& self) + { + print_stream(s, self.lhs); + s << " " << Operator::as_string() << " "; + print_stream(s, self.rhs); + return s; + } + + friend constexpr decltype(auto) get_value(const expression& e) { return e.value(); } + + constexpr decltype(auto) value() const { return Operator::call(get_value(lhs), get_value(rhs)); }; + + TEST_FOREACH_UNARY_OPERATORS(TEST_EXPR_UNARY_OPERATOR) + TEST_FOREACH_BINARY_OPERATORS(TEST_EXPR_BINARY_OPERATOR) +}; + +// TODO: Remove rvalue references +template +constexpr expression make_expression(T&& lhs, U&& rhs, Operator) +{ + return {static_cast(lhs), static_cast(rhs)}; +} + +// TODO: Remove rvalue reference +template +constexpr lhs_expression make_lhs_expression(T&& lhs) +{ + return lhs_expression{static_cast(lhs)}; +} + +template +constexpr lhs_expression make_lhs_expression(T&& lhs, Operator) +{ + return lhs_expression{static_cast(lhs)}; +} + +template +struct lhs_expression +{ + T lhs; + constexpr explicit lhs_expression(T e) : lhs(static_cast(e)) {} + + template + friend constexpr Stream& operator<<(Stream& s, const lhs_expression& self) + { + const char* op = Operator::as_string(); + if(op != nullptr or *op != '\0') + s << Operator::as_string() << " "; + print_stream(s, self.lhs); + return s; + } + + friend constexpr decltype(auto) get_value(const lhs_expression& e) { return e.value(); } + + constexpr decltype(auto) value() const { return Operator::call(get_value(lhs)); } + + TEST_FOREACH_BINARY_OPERATORS(TEST_EXPR_BINARY_OPERATOR) + TEST_FOREACH_UNARY_OPERATORS(TEST_EXPR_UNARY_OPERATOR) + +// NOLINTNEXTLINE +#define TEST_LHS_REOPERATOR(op) \ + template \ + constexpr auto operator op(const U& rhs) const \ + { \ + return make_lhs_expression(lhs op rhs); \ + } + TEST_LHS_REOPERATOR(+) + TEST_LHS_REOPERATOR(-) + TEST_LHS_REOPERATOR(*) + TEST_LHS_REOPERATOR(/) + TEST_LHS_REOPERATOR(%) + TEST_LHS_REOPERATOR(&) + TEST_LHS_REOPERATOR(|) + TEST_LHS_REOPERATOR(^) +}; + +struct capture +{ + template + constexpr auto operator->*(const T& x) const + { + return make_lhs_expression(x); + } + + template + constexpr auto operator->*(const lhs_expression& x) const + { + return x; + } +}; + +MIGRAPHX_HIP_NORETURN __device__ inline void fail() { abort(); } + +template +__device__ void failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) +{ + // TODO: Check failures across multiple lanes + if(not bool(x.value()) and threadIdx.x == 0) + { + println_once(func); + println_once(file, ":", line, ":"); + println_once(" FAILED: ", msg, " [ ", x, " ]"); + f(); + } +} + +// NOLINTNEXTLINE +#define TEST_CAPTURE(...) migraphx::test::capture{}->*__VA_ARGS__ + +#ifdef _WIN32 +// NOLINTNEXTLINE +#define TEST_PRETTY_FUNCTION __FUNCSIG__ +#else +// NOLINTNEXTLINE +#define TEST_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#endif + +// NOLINTNEXTLINE +#define CHECK(...) \ + migraphx::test::failed( \ + TEST_CAPTURE(__VA_ARGS__), #__VA_ARGS__, TEST_PRETTY_FUNCTION, __FILE__, __LINE__, [] {}) + +// NOLINTNEXTLINE +#define EXPECT(...) \ + migraphx::test::failed(TEST_CAPTURE(__VA_ARGS__), \ + #__VA_ARGS__, \ + TEST_PRETTY_FUNCTION, \ + __FILE__, \ + __LINE__, \ + &migraphx::test::fail) + +// NOLINTNEXTLINE +#define TEST_CASE(...) \ + __device__ void __VA_ARGS__() \ + +} // namespace test +} // namespace migraphx +#endif // MIGRAPHX_GUARD_KERNELS_TEST_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c14e4091c22..eede89f0cce 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -62,6 +62,7 @@ if(MIGRAPHX_ENABLE_GPU) endif() target_link_libraries(test_gpu_${BASE_NAME} migraphx_gpu migraphx_kernels register_targets) endforeach() + add_subdirectory(gpu/kernels) endif() if(MIGRAPHX_ENABLE_FPGA) diff --git a/test/gpu/kernels/CMakeLists.txt b/test/gpu/kernels/CMakeLists.txt new file mode 100644 index 00000000000..b5e50a77670 --- /dev/null +++ b/test/gpu/kernels/CMakeLists.txt @@ -0,0 +1,72 @@ +##################################################################################### +# The MIT License (MIT) +# +# Copyright (c) 2015-2024 Advanced Micro Devices, Inc. All rights reserved. +# +# 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. +##################################################################################### + +file(GLOB KERNELS_TESTS CONFIGURE_DEPENDS *.cpp) +list(REMOVE_ITEM KERNELS_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) + +message("KERNELS_TESTS: ${KERNELS_TESTS}") + +add_embed_library(kernel_tests ${KERNELS_TESTS} RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}) +rocm_add_test_executable(test_gpu_kernels main.cpp) + +target_link_libraries(test_gpu_kernels migraphx migraphx_gpu kernel_tests) + + + +# foreach(TEST ${KERNELS_TESTS}) +# get_filename_component(BASE_NAME ${TEST} NAME_WE) +# rocm_add_test_executable(test_gpu_kernels_${BASE_NAME} main.cpp) +# rocm_clang_tidy_check(test_gpu_kernels_${BASE_NAME}) +# endforeach() + + + + + +# function(add_gpu_kernels_test ${TEST_NAME}) +# add_executable(${TEST_NAME} ${ARGN}) +# rocm_clang_tidy_check(${TEST_NAME}) +# target_link_libraries(${TEST_NAME} migraphx migraphx_all_targets) +# target_include_directories(${TEST_NAME} PUBLIC ../include) +# endfunction(add_kernels_test) + + +# add_executable(test_kernels ${VERIFY_TESTS}) +# rocm_mark_as_test(test_kernels) +# rocm_install_test(TARGETS test_kernels) +# target_link_libraries(test_kernels migraphx migraphx_all_targets) +# target_include_directories(test_kernels PUBLIC ../include) +# rocm_clang_tidy_check(test_kernels) + +# foreach(SECTION general reduce rnn conv gemm) +# rocm_add_test(NAME test_kernels_${SECTION} COMMAND test_kernels ${SECTION}) +# set_tests_properties(test_kernels_${SECTION} PROPERTIES +# COST 100 +# ) +# if(MIGRAPHX_ENABLE_GPU) +# set_tests_properties(test_kernels_${SECTION} PROPERTIES +# RESOURCE_LOCK gpu +# ) +# endif() +# endforeach() diff --git a/test/gpu/kernels/basic.cpp b/test/gpu/kernels/basic.cpp new file mode 100644 index 00000000000..c40109c4e8c --- /dev/null +++ b/test/gpu/kernels/basic.cpp @@ -0,0 +1,13 @@ +#include + +TEST_CASE(always_true) +{ + EXPECT(true); +} + +TEST_CASE(compare) +{ + int x = 2; + int y = 2; + EXPECT(x == y); +} diff --git a/test/gpu/kernels/main.cpp b/test/gpu/kernels/main.cpp new file mode 100644 index 00000000000..fa0febff89e --- /dev/null +++ b/test/gpu/kernels/main.cpp @@ -0,0 +1,104 @@ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static migraphx::src_file make_src_file(const std::string& name, const std::string& content) +{ + return {name, content}; +} + +std::vector parse_cases(const std::string_view& content) +{ + std::regex case_re(R"(TEST_CASE\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\))"); + std::match_results m; + std::vector test_names; + + auto it = content.cbegin(); + while (std::regex_search(it, content.cend(), m, case_re)) { + test_names.push_back(m[1].str()); + it = m.suffix().first; + } + return test_names; +} + +struct test_suite : std::enable_shared_from_this +{ + std::string name; + std::string_view content; + std::map test_cases; + migraphx::gpu::hip_compile_options options = {}; + migraphx::gpu::kernel k; + + test_suite(const std::string_view& src_name, const std::string_view& src_content) + : name(src_name.substr(0, src_name.size() - 4)), content(src_content) + { + auto cases = parse_cases(src_content); + for(std::size_t i = 0 ; i < cases.size(); ++i) + { + test_cases[name + "." + cases[i]] = i; + } + + migraphx::gpu::context ctx; + options.global = 1; + options.local = ctx.get_current_device().get_wavefront_size(); + options.kernel_name = "gpu_test_kernel"; + } + + std::string generate_source() const + { + std::ostringstream out; + out << content << '\n'; + out << "extern \"C\" __global__ void " << options.kernel_name << "(int id) {\n"; + out << " switch(id) {\n"; + for(const auto&[case_name, i] : test_cases) + { + auto fname = case_name.substr(name.size() + 1); + out << " case " << i << ": " << fname << "(); break;\n"; + } + out << " default: abort();\n"; + out << " }\n"; + out << "}\n"; + return out.str(); + } + + void compile() + { + if(not k.empty()) + return; + migraphx::gpu::context ctx; + auto binary = migraphx::gpu::compile_hip_raw(ctx, generate_source(), options); + + k = {binary, options.kernel_name}; + } + + void run(const std::string& case_name) + { + compile(); + k.launch(nullptr, options.global, options.local)(test_cases.at(case_name)); + CHECK(hipDeviceSynchronize() == hipSuccess); + } +}; + +int main(int argc, const char* argv[]) +{ + test::driver d{}; + for(auto[name, content]: ::kernel_tests()) + { + auto ts = std::make_shared(name, content); + for(auto&& p:ts->test_cases) { + auto case_name = p.first; + test::add_test_case(case_name, [ts, case_name] { + ts->run(case_name); + }); + } + } + d.run(argc, argv); +} diff --git a/test/include/test.hpp b/test/include/test.hpp index 8d5475855d3..3b456b27b37 100644 --- a/test/include/test.hpp +++ b/test/include/test.hpp @@ -762,6 +762,22 @@ struct driver out() << std::endl; } + template + void run_test_cases(Range&& cases, const string_map& args) + { + if(on_selected_cases and args.count("--continue") == 0) + { + std::vector selected_cases; + std::transform(cases.begin(), + cases.end(), + std::back_inserter(selected_cases), + [](const auto& p) { return p.first; }); + on_selected_cases(selected_cases); + } + for(auto&& p : cases) + run_test_case(p.first, p.second, args); + } + void run(int argc, const char* argv[]) { auto args = parse(argc, argv); @@ -783,8 +799,7 @@ struct driver auto cases = args[""]; if(cases.empty()) { - for(auto&& tc : get_test_cases()) - run_test_case(tc.first, tc.second, args); + run_test_cases(get_test_cases(), args); } else { @@ -812,8 +827,7 @@ struct driver << color::reset << std::endl; failed.push_back(iname); } - for(auto&& p : found_cases) - run_test_case(p.first, p.second, args); + run_test_cases(found_cases, args); } } out() << color::fg_green << "[==========] " << color::fg_yellow << ran << " tests ran" @@ -829,6 +843,7 @@ struct driver } } + std::function&)> on_selected_cases = nullptr; std::function(const std::string&)> get_case_names = [](const std::string& name) -> std::vector { return {name}; }; std::vector arguments = {}; From c20742fcd7bef1fa488d76d05162c817241ca05b Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 1 Aug 2025 18:10:06 -0500 Subject: [PATCH 02/20] Format --- src/targets/gpu/kernel.cpp | 5 +- .../kernels/include/migraphx/kernels/test.hpp | 84 ++++++++++--------- test/gpu/kernels/basic.cpp | 5 +- test/gpu/kernels/main.cpp | 20 ++--- test/include/test.hpp | 2 +- 5 files changed, 56 insertions(+), 60 deletions(-) diff --git a/src/targets/gpu/kernel.cpp b/src/targets/gpu/kernel.cpp index 7725691d935..735ef775b89 100644 --- a/src/targets/gpu/kernel.cpp +++ b/src/targets/gpu/kernel.cpp @@ -79,10 +79,7 @@ kernel::kernel(const char* image, const std::string& name) : impl(std::make_shar MIGRAPHX_THROW("Failed to get function: " + name + ": " + hip_error(status)); } -bool kernel::empty() const -{ - return impl == nullptr; -} +bool kernel::empty() const { return impl == nullptr; } static void launch_kernel(hipFunction_t fun, hipStream_t stream, diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index 9c3f67f906b..786fe0f2c85 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -38,27 +38,27 @@ struct rank<0> // clang-format on // NOLINTNEXTLINE -#define TEST_EACH_BINARY_OPERATOR_OBJECT(op, name) \ - struct name \ - { \ +#define TEST_EACH_BINARY_OPERATOR_OBJECT(op, name) \ + struct name \ + { \ static constexpr const char* as_string() { return #op; } \ - template \ - static constexpr decltype(auto) call(T&& x, U&& y) \ - { \ - return x op y; \ - } \ + template \ + static constexpr decltype(auto) call(T && x, U&& y) \ + { \ + return x op y; \ + } \ }; // NOLINTNEXTLINE -#define TEST_EACH_UNARY_OPERATOR_OBJECT(op, name) \ - struct name \ - { \ +#define TEST_EACH_UNARY_OPERATOR_OBJECT(op, name) \ + struct name \ + { \ static constexpr const char* as_string() { return #op; } \ - template \ - static constexpr decltype(auto) call(T&& x) \ - { \ - return op x; \ - } \ + template \ + static constexpr decltype(auto) call(T && x) \ + { \ + return op x; \ + } \ }; TEST_FOREACH_BINARY_OPERATORS(TEST_EACH_BINARY_OPERATOR_OBJECT) @@ -93,8 +93,7 @@ constexpr Stream& print_stream_impl(rank<0>, Stream& s, const T&) } template -constexpr auto print_stream_impl(rank<1>, Stream& s, const T& x) - -> decltype(s << x) +constexpr auto print_stream_impl(rank<1>, Stream& s, const T& x) -> decltype(s << x) { return s << x; } @@ -121,10 +120,10 @@ template constexpr lhs_expression make_lhs_expression(T&& lhs, Operator); // NOLINTNEXTLINE -#define TEST_EXPR_BINARY_OPERATOR(op, name) \ - template \ - constexpr auto operator op(V&& rhs2) const \ - { \ +#define TEST_EXPR_BINARY_OPERATOR(op, name) \ + template \ + constexpr auto operator op(V&& rhs2) const \ + { \ return make_expression(*this, static_cast(rhs2), name{}); /* NOLINT */ \ } @@ -138,7 +137,7 @@ struct expression T lhs; U rhs; - template + template friend constexpr Stream& operator<<(Stream& s, const expression& self) { print_stream(s, self.lhs); @@ -149,7 +148,10 @@ struct expression friend constexpr decltype(auto) get_value(const expression& e) { return e.value(); } - constexpr decltype(auto) value() const { return Operator::call(get_value(lhs), get_value(rhs)); }; + constexpr decltype(auto) value() const + { + return Operator::call(get_value(lhs), get_value(rhs)); + }; TEST_FOREACH_UNARY_OPERATORS(TEST_EXPR_UNARY_OPERATOR) TEST_FOREACH_BINARY_OPERATORS(TEST_EXPR_BINARY_OPERATOR) @@ -181,7 +183,7 @@ struct lhs_expression T lhs; constexpr explicit lhs_expression(T e) : lhs(static_cast(e)) {} - template + template friend constexpr Stream& operator<<(Stream& s, const lhs_expression& self) { const char* op = Operator::as_string(); @@ -199,11 +201,11 @@ struct lhs_expression TEST_FOREACH_UNARY_OPERATORS(TEST_EXPR_UNARY_OPERATOR) // NOLINTNEXTLINE -#define TEST_LHS_REOPERATOR(op) \ - template \ - constexpr auto operator op(const U& rhs) const \ - { \ - return make_lhs_expression(lhs op rhs); \ +#define TEST_LHS_REOPERATOR(op) \ + template \ + constexpr auto operator op(const U& rhs) const \ + { \ + return make_lhs_expression(lhs op rhs); \ } TEST_LHS_REOPERATOR(+) TEST_LHS_REOPERATOR(-) @@ -233,7 +235,8 @@ struct capture MIGRAPHX_HIP_NORETURN __device__ inline void fail() { abort(); } template -__device__ void failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) +__device__ void +failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) { // TODO: Check failures across multiple lanes if(not bool(x.value()) and threadIdx.x == 0) @@ -257,22 +260,21 @@ __device__ void failed(const T& x, const char* msg, const char* func, const char #endif // NOLINTNEXTLINE -#define CHECK(...) \ - migraphx::test::failed( \ +#define CHECK(...) \ + migraphx::test::failed( \ TEST_CAPTURE(__VA_ARGS__), #__VA_ARGS__, TEST_PRETTY_FUNCTION, __FILE__, __LINE__, [] {}) // NOLINTNEXTLINE -#define EXPECT(...) \ +#define EXPECT(...) \ migraphx::test::failed(TEST_CAPTURE(__VA_ARGS__), \ - #__VA_ARGS__, \ - TEST_PRETTY_FUNCTION, \ - __FILE__, \ - __LINE__, \ - &migraphx::test::fail) + #__VA_ARGS__, \ + TEST_PRETTY_FUNCTION, \ + __FILE__, \ + __LINE__, \ + &migraphx::test::fail) // NOLINTNEXTLINE -#define TEST_CASE(...) \ - __device__ void __VA_ARGS__() \ +#define TEST_CASE(...) __device__ void __VA_ARGS__() } // namespace test } // namespace migraphx diff --git a/test/gpu/kernels/basic.cpp b/test/gpu/kernels/basic.cpp index c40109c4e8c..3c64b322a41 100644 --- a/test/gpu/kernels/basic.cpp +++ b/test/gpu/kernels/basic.cpp @@ -1,9 +1,6 @@ #include -TEST_CASE(always_true) -{ - EXPECT(true); -} +TEST_CASE(always_true) { EXPECT(true); } TEST_CASE(compare) { diff --git a/test/gpu/kernels/main.cpp b/test/gpu/kernels/main.cpp index fa0febff89e..80b4556e450 100644 --- a/test/gpu/kernels/main.cpp +++ b/test/gpu/kernels/main.cpp @@ -22,7 +22,8 @@ std::vector parse_cases(const std::string_view& content) std::vector test_names; auto it = content.cbegin(); - while (std::regex_search(it, content.cend(), m, case_re)) { + while(std::regex_search(it, content.cend(), m, case_re)) + { test_names.push_back(m[1].str()); it = m.suffix().first; } @@ -41,14 +42,14 @@ struct test_suite : std::enable_shared_from_this : name(src_name.substr(0, src_name.size() - 4)), content(src_content) { auto cases = parse_cases(src_content); - for(std::size_t i = 0 ; i < cases.size(); ++i) + for(std::size_t i = 0; i < cases.size(); ++i) { test_cases[name + "." + cases[i]] = i; } migraphx::gpu::context ctx; - options.global = 1; - options.local = ctx.get_current_device().get_wavefront_size(); + options.global = 1; + options.local = ctx.get_current_device().get_wavefront_size(); options.kernel_name = "gpu_test_kernel"; } @@ -58,7 +59,7 @@ struct test_suite : std::enable_shared_from_this out << content << '\n'; out << "extern \"C\" __global__ void " << options.kernel_name << "(int id) {\n"; out << " switch(id) {\n"; - for(const auto&[case_name, i] : test_cases) + for(const auto& [case_name, i] : test_cases) { auto fname = case_name.substr(name.size() + 1); out << " case " << i << ": " << fname << "(); break;\n"; @@ -90,14 +91,13 @@ struct test_suite : std::enable_shared_from_this int main(int argc, const char* argv[]) { test::driver d{}; - for(auto[name, content]: ::kernel_tests()) + for(auto [name, content] : ::kernel_tests()) { auto ts = std::make_shared(name, content); - for(auto&& p:ts->test_cases) { + for(auto&& p : ts->test_cases) + { auto case_name = p.first; - test::add_test_case(case_name, [ts, case_name] { - ts->run(case_name); - }); + test::add_test_case(case_name, [ts, case_name] { ts->run(case_name); }); } } d.run(argc, argv); diff --git a/test/include/test.hpp b/test/include/test.hpp index 3b456b27b37..d2d9632ba45 100644 --- a/test/include/test.hpp +++ b/test/include/test.hpp @@ -762,7 +762,7 @@ struct driver out() << std::endl; } - template + template void run_test_cases(Range&& cases, const string_map& args) { if(on_selected_cases and args.count("--continue") == 0) From b0d7a46be3ea238dd7d9bd3fea971df4d844b6ac Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 4 Aug 2025 10:55:32 -0500 Subject: [PATCH 03/20] Add algorithm tests --- test/gpu/kernels/algorithm.cpp | 930 +++++++++++++++++++++++++++++++++ 1 file changed, 930 insertions(+) create mode 100644 test/gpu/kernels/algorithm.cpp diff --git a/test/gpu/kernels/algorithm.cpp b/test/gpu/kernels/algorithm.cpp new file mode 100644 index 00000000000..5bdee3c09a0 --- /dev/null +++ b/test/gpu/kernels/algorithm.cpp @@ -0,0 +1,930 @@ +#include +#include +#include +#include + +struct empty_range +{ + constexpr int* begin() + { + return nullptr; + } + + constexpr int* end() + { + return nullptr; + } +}; + + +TEST_CASE(swap_basic) { + int a = 5, b = 10; + migraphx::swap(a, b); + EXPECT(a == 10 && b == 5); +} +TEST_CASE(swap_same_value) { + int a = 7, b = 7; + migraphx::swap(a, b); + EXPECT(a == 7 && b == 7); +} +TEST_CASE(swap_different_types) { + double a = 3.14; + double b = 2.71; + migraphx::swap(a, b); + EXPECT(migraphx::float_equal(a, 2.71) && migraphx::float_equal(b, 3.14)); +} +TEST_CASE(iter_swap_basic) { + migraphx::array arr = {1, 2, 3}; + migraphx::iter_swap(arr.begin(), arr.begin() + 2); + migraphx::array expected = {3, 2, 1}; + EXPECT(arr == expected); +} +TEST_CASE(iter_swap_same_iterator) { + migraphx::array arr = {1, 2, 3}; + migraphx::array original = arr; + migraphx::iter_swap(arr.begin(), arr.begin()); + EXPECT(arr == original); +} +TEST_CASE(iter_swap_adjacent) { + migraphx::array arr = {10, 20, 30, 40}; + migraphx::iter_swap(arr.begin() + 1, arr.begin() + 2); + migraphx::array expected = {10, 30, 20, 40}; + EXPECT(arr == expected); +} + +TEST_CASE(less_functor) { + migraphx::less comp; + EXPECT(comp(1, 2)); + EXPECT(!comp(2, 1)); + EXPECT(!comp(5, 5)); +} +TEST_CASE(greater_functor) { + migraphx::greater comp; + EXPECT(comp(2, 1)); + EXPECT(!comp(1, 2)); + EXPECT(!comp(5, 5)); +} + +TEST_CASE(accumulate_basic) { + migraphx::array arr = {1, 2, 3, 4}; + auto sum = migraphx::accumulate(arr.begin(), arr.end(), 0, [](int a, int b) { return a + b; }); + EXPECT(sum == 10); +} +TEST_CASE(accumulate_empty_range) { + empty_range arr = {}; + auto sum = migraphx::accumulate(arr.begin(), arr.begin(), 42, [](int a, int b) { return a + b; }); + EXPECT(sum == 42); +} +TEST_CASE(accumulate_multiply) { + migraphx::array arr = {2, 3, 4}; + auto product = migraphx::accumulate(arr.begin(), arr.end(), 1, [](int a, int b) { return a * b; }); + EXPECT(product == 24); +} +TEST_CASE(accumulate_single_element) { + migraphx::array arr = {7}; + auto sum = migraphx::accumulate(arr.begin(), arr.end(), 5, [](int a, int b) { return a + b; }); + EXPECT(sum == 12); +} + +TEST_CASE(copy_basic) { + migraphx::array src = {1, 2, 3, 4}; + migraphx::array dst = {0, 0, 0, 0}; + migraphx::copy(src.begin(), src.end(), dst.begin()); + EXPECT(src == dst); +} +TEST_CASE(copy_empty_range) { + migraphx::array src = {1, 2, 3}; + migraphx::array dst = {0, 0, 0}; + auto result = migraphx::copy(src.begin(), src.begin(), dst.begin()); + EXPECT(result == dst.begin()); + migraphx::array expected = {0, 0, 0}; + EXPECT(dst == expected); +} +TEST_CASE(copy_partial) { + migraphx::array src = {10, 20, 30, 40, 50}; + migraphx::array dst = {0, 0, 0}; + migraphx::copy(src.begin() + 1, src.begin() + 4, dst.begin()); + migraphx::array expected = {20, 30, 40}; + EXPECT(dst == expected); +} +TEST_CASE(copy_if_basic) { + migraphx::array src = {1, 2, 3, 4, 5, 6}; + migraphx::array dst = {0, 0, 0, 0, 0, 0}; + auto end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); + EXPECT(dst[0] == 2); + EXPECT(dst[1] == 4); + EXPECT(dst[2] == 6); + EXPECT(end_it == dst.begin() + 3); +} +TEST_CASE(copy_if_none_match) { + migraphx::array src = {1, 3, 5}; + migraphx::array dst = {0, 0, 0}; + auto end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); + EXPECT(end_it == dst.begin()); + migraphx::array expected = {0, 0, 0}; + EXPECT(dst == expected); +} +TEST_CASE(copy_if_all_match) { + migraphx::array src = {2, 4, 6}; + migraphx::array dst = {0, 0, 0}; + auto end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); + EXPECT(end_it == dst.end()); + EXPECT(src == dst); +} + +TEST_CASE(is_sorted_until_sorted) { + migraphx::array arr = {1, 2, 3, 4}; + auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(is_sorted_until_unsorted) { + migraphx::array arr = {1, 2, 4, 3, 5}; + auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(is_sorted_until_empty) { + empty_range arr = {}; + auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(is_sorted_until_single) { + migraphx::array arr = {42}; + auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(is_sorted_until_descending) { + migraphx::array arr = {4, 3, 2, 1}; + auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::greater{}); + EXPECT(result == arr.end()); +} +TEST_CASE(is_sorted_true) { + migraphx::array arr = {1, 2, 3, 4}; + EXPECT(migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); +} +TEST_CASE(is_sorted_false) { + migraphx::array arr = {1, 3, 2, 4}; + EXPECT(!migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); +} +TEST_CASE(is_sorted_empty) { + empty_range arr = {}; + EXPECT(migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); +} +TEST_CASE(is_sorted_duplicates) { + migraphx::array arr = {1, 2, 2, 3}; + EXPECT(migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); +} + +TEST_CASE(for_each_basic) { + migraphx::array arr = {1, 2, 3}; + int sum = 0; + migraphx::for_each(arr.begin(), arr.end(), [&sum](int x) { sum += x; }); + EXPECT(sum == 6); +} +TEST_CASE(for_each_modify) { + migraphx::array arr = {1, 2, 3}; + migraphx::for_each(arr.begin(), arr.end(), [](int& x) { x *= 2; }); + migraphx::array expected = {2, 4, 6}; + EXPECT(arr == expected); +} +TEST_CASE(for_each_empty) { + empty_range arr = {}; + int count = 0; + migraphx::for_each(arr.begin(), arr.end(), [&count](int) { count++; }); + EXPECT(count == 0); +} + +TEST_CASE(find_if_found) { + migraphx::array arr = {1, 3, 5, 7, 9}; + auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(find_if_not_found) { + migraphx::array arr = {1, 3, 5, 7}; + auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 10; }); + EXPECT(result == arr.end()); +} +TEST_CASE(find_if_first_element) { + migraphx::array arr = {10, 3, 5, 7}; + auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); + EXPECT(result == arr.begin()); +} +TEST_CASE(find_if_empty) { + empty_range arr = {}; + auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); + EXPECT(result == arr.end()); +} +TEST_CASE(find_basic) { + migraphx::array arr = {10, 20, 30, 40}; + auto result = migraphx::find(arr.begin(), arr.end(), 30); + EXPECT(result == arr.begin() + 2); +} +TEST_CASE(find_not_found) { + migraphx::array arr = {10, 20, 30, 40}; + auto result = migraphx::find(arr.begin(), arr.end(), 50); + EXPECT(result == arr.end()); +} +TEST_CASE(find_first_element) { + migraphx::array arr = {10, 20, 30, 40}; + auto result = migraphx::find(arr.begin(), arr.end(), 10); + EXPECT(result == arr.begin()); +} +TEST_CASE(find_duplicates) { + migraphx::array arr = {10, 20, 30, 20, 40}; + auto result = migraphx::find(arr.begin(), arr.end(), 20); + EXPECT(result == arr.begin() + 1); +} + +TEST_CASE(any_of_true) { + migraphx::array arr = {1, 3, 5, 7}; + EXPECT(migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); +} +TEST_CASE(any_of_false) { + migraphx::array arr = {1, 3, 5, 7}; + EXPECT(!migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); +} +TEST_CASE(any_of_empty) { + empty_range arr = {}; + EXPECT(!migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); +} +TEST_CASE(any_of_first_element) { + migraphx::array arr = {10, 1, 2, 3}; + EXPECT(migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); +} +TEST_CASE(none_of_true) { + migraphx::array arr = {1, 3, 5, 7}; + EXPECT(migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); +} +TEST_CASE(none_of_false) { + migraphx::array arr = {1, 3, 5, 7}; + EXPECT(!migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); +} +TEST_CASE(none_of_empty) { + empty_range arr = {}; + EXPECT(migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); +} +TEST_CASE(all_of_true) { + migraphx::array arr = {2, 4, 6, 8}; + EXPECT(migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); +} +TEST_CASE(all_of_false) { + migraphx::array arr = {2, 4, 5, 8}; + EXPECT(!migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); +} +TEST_CASE(all_of_empty) { + empty_range arr = {}; + EXPECT(migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); +} +TEST_CASE(all_of_single_true) { + migraphx::array arr = {4}; + EXPECT(migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); +} +TEST_CASE(all_of_single_false) { + migraphx::array arr = {5}; + EXPECT(!migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); +} + +TEST_CASE(search_found) { + migraphx::array haystack = {1, 2, 3, 4, 3, 4}; + migraphx::array needle = {3, 4}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 2); +} +TEST_CASE(search_not_found) { + migraphx::array haystack = {1, 2, 3, 4, 5}; + migraphx::array needle = {6, 7}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.end()); +} +TEST_CASE(search_empty_needle) { + migraphx::array haystack = {1, 2, 3}; + empty_range needle = {}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin()); +} +TEST_CASE(search_empty_haystack) { + empty_range haystack = {}; + migraphx::array needle = {1}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.end()); +} +TEST_CASE(search_exact_match) { + migraphx::array haystack = {1, 2, 3}; + migraphx::array needle = {1, 2, 3}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin()); +} +TEST_CASE(search_partial_match) { + migraphx::array haystack = {1, 2, 1, 2, 3}; + migraphx::array needle = {1, 2, 3}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 2); +} +// Additional search tests (extensive) +TEST_CASE(search_overlapping_pattern) { + migraphx::array haystack = {1, 2, 1, 2, 1, 2, 3, 4}; + migraphx::array needle = {1, 2, 3}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 4); +} +TEST_CASE(search_pattern_at_end) { + migraphx::array haystack = {1, 2, 3, 4, 5, 6}; + migraphx::array needle = {5, 6}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 4); +} +TEST_CASE(search_pattern_at_beginning) { + migraphx::array haystack = {1, 2, 3, 4, 5, 6}; + migraphx::array needle = {1, 2}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin()); +} +TEST_CASE(search_single_element_pattern) { + migraphx::array haystack = {1, 3, 5, 7, 9}; + migraphx::array needle = {5}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 2); +} +TEST_CASE(search_single_element_pattern_not_found) { + migraphx::array haystack = {1, 3, 5, 7, 9}; + migraphx::array needle = {4}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.end()); +} +TEST_CASE(search_repeated_elements) { + migraphx::array haystack = {2, 2, 2, 2, 1, 2, 2, 3}; + migraphx::array needle = {2, 2, 3}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 5); +} +TEST_CASE(search_partial_match_backtrack) { + migraphx::array haystack = {1, 2, 3, 1, 2, 4, 1, 2, 3, 4}; + migraphx::array needle = {1, 2, 3, 4}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 6); +} +TEST_CASE(search_multiple_false_starts) { + migraphx::array haystack = {1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 5, 6}; + migraphx::array needle = {1, 2, 3, 4}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 6); +} +TEST_CASE(search_needle_longer_than_haystack) { + migraphx::array haystack = {1, 2, 3}; + migraphx::array needle = {1, 2, 3, 4, 5}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.end()); +} +TEST_CASE(search_identical_arrays) { + migraphx::array haystack = {5, 10, 15, 20}; + migraphx::array needle = {5, 10, 15, 20}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin()); +} +TEST_CASE(search_all_same_elements) { + migraphx::array haystack = {3, 3, 3, 3, 3, 3}; + migraphx::array needle = {3, 3, 3}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin()); +} +TEST_CASE(search_pattern_appears_multiple_times) { + migraphx::array haystack = {1, 2, 3, 1, 2, 3, 1, 2, 3}; + migraphx::array needle = {2, 3}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 1); +} +TEST_CASE(search_partial_range) { + migraphx::array haystack = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + migraphx::array needle = {4, 5}; + auto result = migraphx::search(haystack.begin() + 2, haystack.begin() + 7, needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 4); +} +TEST_CASE(search_stress_long_pattern) { + migraphx::array haystack = {1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 1}; + migraphx::array needle = {2, 3, 4, 5, 6, 7}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 5); +} +TEST_CASE(search_stress_worst_case_complexity) { + migraphx::array haystack = {1, 1, 1, 1, 1, 1, 1, 2}; + migraphx::array needle = {1, 1, 1, 1, 1, 1, 2}; + auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + EXPECT(result == haystack.begin() + 1); +} + +TEST_CASE(inner_product_basic) { + migraphx::array a = {1, 2, 3}; + migraphx::array b = {4, 5, 6}; + auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 0); + EXPECT(result == 32); +} +TEST_CASE(inner_product_custom_ops) { + migraphx::array a = {1, 2, 3}; + migraphx::array b = {4, 5, 6}; + auto result = migraphx::inner_product( + a.begin(), a.end(), b.begin(), 1, + [](int x, int y) { return x * y; }, + [](int x, int y) { return x + y; } + ); + EXPECT(result == 315); +} +TEST_CASE(inner_product_empty) { + empty_range a = {}; + empty_range b = {}; + auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 42); + EXPECT(result == 42); +} +TEST_CASE(inner_product_single) { + migraphx::array a = {3}; + migraphx::array b = {7}; + auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 5); + EXPECT(result == 26); +} + +TEST_CASE(equal_true) { + migraphx::array a = {1, 2, 3, 4}; + migraphx::array b = {1, 2, 3, 4}; + EXPECT(migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); +} +TEST_CASE(equal_false) { + migraphx::array a = {1, 2, 3, 4}; + migraphx::array b = {1, 2, 3, 5}; + EXPECT(!migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); +} +TEST_CASE(equal_empty) { + empty_range a = {}; + empty_range b = {}; + EXPECT(migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); +} +TEST_CASE(equal_custom_predicate) { + migraphx::array a = {1, 2, 3}; + migraphx::array b = {2, 4, 6}; + EXPECT(migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x * 2 == y; })); +} + +TEST_CASE(iota_basic) { + migraphx::array arr = {0, 0, 0, 0, 0}; + migraphx::iota(arr.begin(), arr.end(), 10); + migraphx::array expected = {10, 11, 12, 13, 14}; + EXPECT(arr == expected); +} +TEST_CASE(iota_empty) { + empty_range arr = {}; + migraphx::iota(arr.begin(), arr.end(), 5); +} +TEST_CASE(iota_single) { + migraphx::array arr = {0}; + migraphx::iota(arr.begin(), arr.end(), 42); + EXPECT(arr[0] == 42); +} +TEST_CASE(iota_negative) { + migraphx::array arr = {0, 0, 0}; + migraphx::iota(arr.begin(), arr.end(), -5); + migraphx::array expected = {-5, -4, -3}; + EXPECT(arr == expected); +} + +TEST_CASE(min_element_basic) { + migraphx::array arr = {3, 1, 4, 1, 5}; + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.begin() + 1); +} +TEST_CASE(min_element_empty) { + empty_range arr = {}; + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(min_element_single) { + migraphx::array arr = {42}; + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.begin()); +} +TEST_CASE(min_element_all_equal) { + migraphx::array arr = {5, 5, 5, 5}; + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(result == arr.begin()); +} +TEST_CASE(min_element_custom_compare) { + migraphx::array arr = {1, 2, 3, 4}; + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::greater{}); + EXPECT(result == arr.begin() + 3); +} + +TEST_CASE(rotate_left_by_two) { + migraphx::array arr = {1, 2, 3, 4, 5, 6}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); + migraphx::array expected = {3, 4, 5, 6, 1, 2}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 4); +} +TEST_CASE(rotate_right_by_one) { + migraphx::array arr = {1, 2, 3, 4, 5}; + auto result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); + migraphx::array expected = {5, 1, 2, 3, 4}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 1); +} +TEST_CASE(rotate_half_array) { + migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); + migraphx::array expected = {5, 6, 7, 8, 1, 2, 3, 4}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 4); +} +TEST_CASE(rotate_almost_full) { + migraphx::array arr = {1, 2, 3, 4, 5}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); + migraphx::array expected = {5, 1, 2, 3, 4}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 1); +} +TEST_CASE(rotate_two_elements) { + migraphx::array arr = {1, 2}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); + migraphx::array expected = {2, 1}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 1); +} +TEST_CASE(rotate_partial_range) { + migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; + auto result = migraphx::rotate(arr.begin() + 1, arr.begin() + 3, arr.begin() + 5); + migraphx::array expected = {1, 4, 5, 2, 3, 6, 7}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(rotate_with_duplicates) { + migraphx::array arr = {1, 1, 2, 2, 3, 3}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); + migraphx::array expected = {2, 2, 3, 3, 1, 1}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 4); +} +TEST_CASE(rotate_stress_test_large_shift) { + migraphx::array arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); + migraphx::array expected = {7, 8, 9, 0, 1, 2, 3, 4, 5, 6}; + EXPECT(arr == expected); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(rotate_edge_case_middle_equals_first) { + migraphx::array arr = {1, 2, 3, 4}; + migraphx::array original = arr; + auto result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); + EXPECT(arr == original); + EXPECT(result == arr.end()); +} +TEST_CASE(rotate_edge_case_middle_equals_last) { + migraphx::array arr = {1, 2, 3, 4}; + migraphx::array original = arr; + auto result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); + EXPECT(arr == original); + EXPECT(result == arr.begin()); +} + +TEST_CASE(upper_bound_basic) { + migraphx::array arr = {1, 2, 2, 3, 4}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(upper_bound_not_found) { + migraphx::array arr = {1, 2, 3, 4}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_first_element) { + migraphx::array arr = {1, 2, 3, 4}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); + EXPECT(result == arr.begin()); +} +TEST_CASE(upper_bound_empty) { + empty_range arr = {}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_all_equal) { + migraphx::array arr = {2, 2, 2}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_multiple_duplicates) { + migraphx::array arr = {1, 2, 2, 2, 2, 3, 4, 5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + EXPECT(result == arr.begin() + 5); +} +TEST_CASE(upper_bound_all_smaller) { + migraphx::array arr = {1, 2, 3, 4, 5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); + EXPECT(result == arr.begin()); +} +TEST_CASE(upper_bound_all_larger) { + migraphx::array arr = {1, 2, 3, 4, 5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 10, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_single_element_match) { + migraphx::array arr = {5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_single_element_smaller) { + migraphx::array arr = {5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::less{}); + EXPECT(result == arr.begin()); +} +TEST_CASE(upper_bound_single_element_larger) { + migraphx::array arr = {5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_beginning_duplicates) { + migraphx::array arr = {1, 1, 1, 4, 5, 6}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 1, migraphx::less{}); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(upper_bound_end_duplicates) { + migraphx::array arr = {1, 2, 3, 5, 5, 5}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + EXPECT(result == arr.end()); +} +TEST_CASE(upper_bound_middle_value) { + migraphx::array arr = {1, 3, 5, 7, 9, 11, 13}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); + EXPECT(result == arr.begin() + 4); +} +TEST_CASE(upper_bound_partial_range) { + migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; + auto result = migraphx::upper_bound(arr.begin() + 2, arr.begin() + 6, 4, migraphx::less{}); + EXPECT(result == arr.begin() + 4); +} +TEST_CASE(upper_bound_reverse_comparator) { + migraphx::array arr = {5, 4, 3, 2, 1}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::greater{}); + EXPECT(result == arr.begin() + 3); +} +TEST_CASE(upper_bound_large_array_power_of_two) { + migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 8, migraphx::less{}); + EXPECT(result == arr.begin() + 8); +} +TEST_CASE(upper_bound_stress_binary_search) { + migraphx::array arr = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 16, migraphx::less{}); + EXPECT(result == arr.begin() + 8); +} +TEST_CASE(upper_bound_stress_test_boundary) { + migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; + for (int i = 1; i <= 7; ++i) { + auto result = migraphx::upper_bound(arr.begin(), arr.end(), i, migraphx::less{}); + EXPECT(result == arr.begin() + i); + } +} + +TEST_CASE(sort_basic) { + migraphx::array arr = {5, 2, 8, 1, 9}; + migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); + migraphx::array expected = {1, 2, 5, 8, 9}; + EXPECT(arr == expected); +} +TEST_CASE(sort_already_sorted) { + migraphx::array arr = {1, 2, 3, 4}; + migraphx::array original = arr; + migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(arr == original); +} +TEST_CASE(sort_reverse_sorted) { + migraphx::array arr = {4, 3, 2, 1}; + migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4}; + EXPECT(arr == expected); +} +TEST_CASE(sort_duplicates) { + migraphx::array arr = {3, 1, 4, 1, 5, 2}; + migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); + migraphx::array expected = {1, 1, 2, 3, 4, 5}; + EXPECT(arr == expected); +} +TEST_CASE(sort_empty) { + empty_range arr = {}; + migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); +} +TEST_CASE(sort_single) { + migraphx::array arr = {42}; + migraphx::array original = arr; + migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(arr == original); +} +TEST_CASE(sort_default_comparator) { + migraphx::array arr = {3, 1, 4, 2}; + migraphx::sort(arr.begin(), arr.end()); + migraphx::array expected = {1, 2, 3, 4}; + EXPECT(arr == expected); +} + +TEST_CASE(stable_sort_basic) { + migraphx::array arr = {5, 2, 8, 1, 9}; + migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); + migraphx::array expected = {1, 2, 5, 8, 9}; + EXPECT(arr == expected); +} +TEST_CASE(stable_sort_empty) { + empty_range arr = {}; + migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); +} +TEST_CASE(stable_sort_single) { + migraphx::array arr = {42}; + migraphx::array original = arr; + migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(arr == original); +} +TEST_CASE(stable_sort_already_sorted) { + migraphx::array arr = {1, 2, 3, 4}; + migraphx::array original = arr; + migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); + EXPECT(arr == original); +} +TEST_CASE(stable_sort_default_comparator) { + migraphx::array arr = {3, 1, 4, 2}; + migraphx::stable_sort(arr.begin(), arr.end()); + migraphx::array expected = {1, 2, 3, 4}; + EXPECT(arr == expected); +} + +TEST_CASE(merge_basic) { + migraphx::array arr1 = {1, 3, 5}; + migraphx::array arr2 = {2, 4, 6}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4, 5, 6}; + EXPECT(result == expected); +} +TEST_CASE(merge_empty_first) { + empty_range arr1 = {}; + migraphx::array arr2 = {1, 2, 3}; + migraphx::array result = {0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + EXPECT(result == arr2); +} +TEST_CASE(merge_empty_second) { + migraphx::array arr1 = {1, 2, 3}; + empty_range arr2 = {}; + migraphx::array result = {0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + EXPECT(result == arr1); +} +TEST_CASE(merge_both_empty) { + empty_range arr1 = {}; + empty_range arr2 = {}; + empty_range result = {}; + auto end_it = migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + EXPECT(end_it == result.end()); +} +TEST_CASE(merge_overlapping_ranges) { + migraphx::array arr1 = {1, 3, 5, 7}; + migraphx::array arr2 = {2, 6}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 5, 6, 7}; + EXPECT(result == expected); +} +TEST_CASE(merge_duplicates) { + migraphx::array arr1 = {1, 2, 3}; + migraphx::array arr2 = {2, 3, 4}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 2, 3, 3, 4}; + EXPECT(result == expected); +} +// Additional merge tests (extensive) +TEST_CASE(merge_different_sizes) { + migraphx::array arr1 = {1, 5}; + migraphx::array arr2 = {2, 3, 4, 6}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4, 5, 6}; + EXPECT(result == expected); +} +TEST_CASE(merge_first_all_smaller) { + migraphx::array arr1 = {1, 2, 3}; + migraphx::array arr2 = {4, 5, 6}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4, 5, 6}; + EXPECT(result == expected); +} +TEST_CASE(merge_first_all_larger) { + migraphx::array arr1 = {4, 5, 6}; + migraphx::array arr2 = {1, 2, 3}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4, 5, 6}; + EXPECT(result == expected); +} +TEST_CASE(merge_interleaved) { + migraphx::array arr1 = {1, 3, 5, 7}; + migraphx::array arr2 = {2, 4, 6, 8}; + migraphx::array result = {0, 0, 0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4, 5, 6, 7, 8}; + EXPECT(result == expected); +} +TEST_CASE(merge_many_duplicates) { + migraphx::array arr1 = {1, 1, 2, 2}; + migraphx::array arr2 = {1, 2, 2, 3}; + migraphx::array result = {0, 0, 0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 1, 1, 2, 2, 2, 2, 3}; + EXPECT(result == expected); +} +TEST_CASE(merge_all_equal_elements) { + migraphx::array arr1 = {5, 5, 5}; + migraphx::array arr2 = {5, 5}; + migraphx::array result = {0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {5, 5, 5, 5, 5}; + EXPECT(result == expected); +} +TEST_CASE(merge_single_elements) { + migraphx::array arr1 = {3}; + migraphx::array arr2 = {1}; + migraphx::array result = {0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 3}; + EXPECT(result == expected); +} +TEST_CASE(merge_one_single_element) { + migraphx::array arr1 = {3}; + migraphx::array arr2 = {1, 2, 4, 5}; + migraphx::array result = {0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 4, 5}; + EXPECT(result == expected); +} +TEST_CASE(merge_reverse_order) { + migraphx::array arr1 = {6, 4, 2}; + migraphx::array arr2 = {5, 3, 1}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::greater{}); + migraphx::array expected = {6, 5, 4, 3, 2, 1}; + EXPECT(result == expected); +} +TEST_CASE(merge_negative_numbers) { + migraphx::array arr1 = {-5, -2, 1}; + migraphx::array arr2 = {-3, 0, 3}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {-5, -3, -2, 0, 1, 3}; + EXPECT(result == expected); +} +TEST_CASE(merge_large_difference) { + migraphx::array arr1 = {1, 1000, 2000}; + migraphx::array arr2 = {2, 500, 1500}; + migraphx::array result = {0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 500, 1000, 1500, 2000}; + EXPECT(result == expected); +} +TEST_CASE(merge_partial_ranges) { + migraphx::array arr1 = {0, 1, 2, 3, 4, 5, 6, 7}; + migraphx::array arr2 = {10, 11, 12, 13, 14, 15}; + migraphx::array result = {0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin() + 2, arr1.begin() + 5, arr2.begin() + 1, arr2.begin() + 3, result.begin(), migraphx::less{}); + migraphx::array expected = {2, 3, 4, 11, 12}; + EXPECT(result == expected); +} +TEST_CASE(merge_stability_test) { + migraphx::array arr1 = {1, 3, 5, 7}; + migraphx::array arr2 = {2, 3, 6, 7}; + migraphx::array result = {0, 0, 0, 0, 0, 0, 0, 0}; + migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::array expected = {1, 2, 3, 3, 5, 6, 7, 7}; + EXPECT(result == expected); +} + +TEST_CASE(common_mistakes_off_by_one) { + migraphx::array arr = {5}; + auto result = migraphx::find(arr.begin(), arr.end(), 5); + EXPECT(result == arr.begin()); + result = migraphx::find(arr.begin(), arr.end(), 10); + EXPECT(result == arr.end()); +} +TEST_CASE(common_mistakes_empty_ranges) { + empty_range empty = {}; + EXPECT(migraphx::is_sorted(empty.begin(), empty.end(), migraphx::less{})); + EXPECT(migraphx::all_of(empty.begin(), empty.end(), [](int) { return false; })); + EXPECT(!migraphx::any_of(empty.begin(), empty.end(), [](int) { return true; })); + EXPECT(migraphx::none_of(empty.begin(), empty.end(), [](int) { return true; })); + auto min_it = migraphx::min_element(empty.begin(), empty.end(), migraphx::less{}); + EXPECT(min_it == empty.end()); +} +TEST_CASE(common_mistakes_self_assignment) { + int x = 42; + migraphx::swap(x, x); + EXPECT(x == 42); +} +TEST_CASE(common_mistakes_predicate_consistency) { + migraphx::array arr = {1, 2, 3, 4}; + int call_count = 0; + auto predicate = [&call_count](int x) { call_count++; return x > 2; }; + auto result = migraphx::find_if(arr.begin(), arr.end(), predicate); + EXPECT(result == arr.begin() + 2); + EXPECT(call_count == 3); +} From ea12168628672113afbad970b0d2c69d77171d75 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 4 Aug 2025 10:55:35 -0500 Subject: [PATCH 04/20] Format --- test/gpu/kernels/algorithm.cpp | 766 ++++++++++++++++++++------------- 1 file changed, 473 insertions(+), 293 deletions(-) diff --git a/test/gpu/kernels/algorithm.cpp b/test/gpu/kernels/algorithm.cpp index 5bdee3c09a0..d77a1828e25 100644 --- a/test/gpu/kernels/algorithm.cpp +++ b/test/gpu/kernels/algorithm.cpp @@ -5,908 +5,1083 @@ struct empty_range { - constexpr int* begin() - { - return nullptr; - } + constexpr int* begin() { return nullptr; } - constexpr int* end() - { - return nullptr; - } + constexpr int* end() { return nullptr; } }; - -TEST_CASE(swap_basic) { +TEST_CASE(swap_basic) +{ int a = 5, b = 10; migraphx::swap(a, b); EXPECT(a == 10 && b == 5); } -TEST_CASE(swap_same_value) { +TEST_CASE(swap_same_value) +{ int a = 7, b = 7; migraphx::swap(a, b); EXPECT(a == 7 && b == 7); } -TEST_CASE(swap_different_types) { +TEST_CASE(swap_different_types) +{ double a = 3.14; double b = 2.71; migraphx::swap(a, b); EXPECT(migraphx::float_equal(a, 2.71) && migraphx::float_equal(b, 3.14)); } -TEST_CASE(iter_swap_basic) { +TEST_CASE(iter_swap_basic) +{ migraphx::array arr = {1, 2, 3}; migraphx::iter_swap(arr.begin(), arr.begin() + 2); migraphx::array expected = {3, 2, 1}; EXPECT(arr == expected); } -TEST_CASE(iter_swap_same_iterator) { - migraphx::array arr = {1, 2, 3}; +TEST_CASE(iter_swap_same_iterator) +{ + migraphx::array arr = {1, 2, 3}; migraphx::array original = arr; migraphx::iter_swap(arr.begin(), arr.begin()); EXPECT(arr == original); } -TEST_CASE(iter_swap_adjacent) { +TEST_CASE(iter_swap_adjacent) +{ migraphx::array arr = {10, 20, 30, 40}; migraphx::iter_swap(arr.begin() + 1, arr.begin() + 2); migraphx::array expected = {10, 30, 20, 40}; EXPECT(arr == expected); } -TEST_CASE(less_functor) { +TEST_CASE(less_functor) +{ migraphx::less comp; EXPECT(comp(1, 2)); EXPECT(!comp(2, 1)); EXPECT(!comp(5, 5)); } -TEST_CASE(greater_functor) { +TEST_CASE(greater_functor) +{ migraphx::greater comp; EXPECT(comp(2, 1)); EXPECT(!comp(1, 2)); EXPECT(!comp(5, 5)); } -TEST_CASE(accumulate_basic) { +TEST_CASE(accumulate_basic) +{ migraphx::array arr = {1, 2, 3, 4}; auto sum = migraphx::accumulate(arr.begin(), arr.end(), 0, [](int a, int b) { return a + b; }); EXPECT(sum == 10); } -TEST_CASE(accumulate_empty_range) { +TEST_CASE(accumulate_empty_range) +{ empty_range arr = {}; - auto sum = migraphx::accumulate(arr.begin(), arr.begin(), 42, [](int a, int b) { return a + b; }); + auto sum = + migraphx::accumulate(arr.begin(), arr.begin(), 42, [](int a, int b) { return a + b; }); EXPECT(sum == 42); } -TEST_CASE(accumulate_multiply) { +TEST_CASE(accumulate_multiply) +{ migraphx::array arr = {2, 3, 4}; - auto product = migraphx::accumulate(arr.begin(), arr.end(), 1, [](int a, int b) { return a * b; }); + auto product = + migraphx::accumulate(arr.begin(), arr.end(), 1, [](int a, int b) { return a * b; }); EXPECT(product == 24); } -TEST_CASE(accumulate_single_element) { +TEST_CASE(accumulate_single_element) +{ migraphx::array arr = {7}; auto sum = migraphx::accumulate(arr.begin(), arr.end(), 5, [](int a, int b) { return a + b; }); EXPECT(sum == 12); } -TEST_CASE(copy_basic) { +TEST_CASE(copy_basic) +{ migraphx::array src = {1, 2, 3, 4}; migraphx::array dst = {0, 0, 0, 0}; migraphx::copy(src.begin(), src.end(), dst.begin()); EXPECT(src == dst); } -TEST_CASE(copy_empty_range) { +TEST_CASE(copy_empty_range) +{ migraphx::array src = {1, 2, 3}; migraphx::array dst = {0, 0, 0}; - auto result = migraphx::copy(src.begin(), src.begin(), dst.begin()); + auto result = migraphx::copy(src.begin(), src.begin(), dst.begin()); EXPECT(result == dst.begin()); migraphx::array expected = {0, 0, 0}; EXPECT(dst == expected); } -TEST_CASE(copy_partial) { +TEST_CASE(copy_partial) +{ migraphx::array src = {10, 20, 30, 40, 50}; migraphx::array dst = {0, 0, 0}; migraphx::copy(src.begin() + 1, src.begin() + 4, dst.begin()); migraphx::array expected = {20, 30, 40}; EXPECT(dst == expected); } -TEST_CASE(copy_if_basic) { +TEST_CASE(copy_if_basic) +{ migraphx::array src = {1, 2, 3, 4, 5, 6}; migraphx::array dst = {0, 0, 0, 0, 0, 0}; - auto end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); + auto end_it = + migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(dst[0] == 2); EXPECT(dst[1] == 4); EXPECT(dst[2] == 6); EXPECT(end_it == dst.begin() + 3); } -TEST_CASE(copy_if_none_match) { +TEST_CASE(copy_if_none_match) +{ migraphx::array src = {1, 3, 5}; migraphx::array dst = {0, 0, 0}; - auto end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); + auto end_it = + migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(end_it == dst.begin()); migraphx::array expected = {0, 0, 0}; EXPECT(dst == expected); } -TEST_CASE(copy_if_all_match) { +TEST_CASE(copy_if_all_match) +{ migraphx::array src = {2, 4, 6}; migraphx::array dst = {0, 0, 0}; - auto end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); + auto end_it = + migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(end_it == dst.end()); EXPECT(src == dst); } -TEST_CASE(is_sorted_until_sorted) { +TEST_CASE(is_sorted_until_sorted) +{ migraphx::array arr = {1, 2, 3, 4}; auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(is_sorted_until_unsorted) { +TEST_CASE(is_sorted_until_unsorted) +{ migraphx::array arr = {1, 2, 4, 3, 5}; auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin() + 3); } -TEST_CASE(is_sorted_until_empty) { +TEST_CASE(is_sorted_until_empty) +{ empty_range arr = {}; - auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(is_sorted_until_single) { +TEST_CASE(is_sorted_until_single) +{ migraphx::array arr = {42}; auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(is_sorted_until_descending) { +TEST_CASE(is_sorted_until_descending) +{ migraphx::array arr = {4, 3, 2, 1}; auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::greater{}); EXPECT(result == arr.end()); } -TEST_CASE(is_sorted_true) { +TEST_CASE(is_sorted_true) +{ migraphx::array arr = {1, 2, 3, 4}; EXPECT(migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); } -TEST_CASE(is_sorted_false) { +TEST_CASE(is_sorted_false) +{ migraphx::array arr = {1, 3, 2, 4}; EXPECT(!migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); } -TEST_CASE(is_sorted_empty) { +TEST_CASE(is_sorted_empty) +{ empty_range arr = {}; EXPECT(migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); } -TEST_CASE(is_sorted_duplicates) { +TEST_CASE(is_sorted_duplicates) +{ migraphx::array arr = {1, 2, 2, 3}; EXPECT(migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); } -TEST_CASE(for_each_basic) { +TEST_CASE(for_each_basic) +{ migraphx::array arr = {1, 2, 3}; - int sum = 0; + int sum = 0; migraphx::for_each(arr.begin(), arr.end(), [&sum](int x) { sum += x; }); EXPECT(sum == 6); } -TEST_CASE(for_each_modify) { +TEST_CASE(for_each_modify) +{ migraphx::array arr = {1, 2, 3}; migraphx::for_each(arr.begin(), arr.end(), [](int& x) { x *= 2; }); migraphx::array expected = {2, 4, 6}; EXPECT(arr == expected); } -TEST_CASE(for_each_empty) { +TEST_CASE(for_each_empty) +{ empty_range arr = {}; - int count = 0; + int count = 0; migraphx::for_each(arr.begin(), arr.end(), [&count](int) { count++; }); EXPECT(count == 0); } -TEST_CASE(find_if_found) { +TEST_CASE(find_if_found) +{ migraphx::array arr = {1, 3, 5, 7, 9}; auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); EXPECT(result == arr.begin() + 3); } -TEST_CASE(find_if_not_found) { +TEST_CASE(find_if_not_found) +{ migraphx::array arr = {1, 3, 5, 7}; auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 10; }); EXPECT(result == arr.end()); } -TEST_CASE(find_if_first_element) { +TEST_CASE(find_if_first_element) +{ migraphx::array arr = {10, 3, 5, 7}; auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); EXPECT(result == arr.begin()); } -TEST_CASE(find_if_empty) { +TEST_CASE(find_if_empty) +{ empty_range arr = {}; - auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); + auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); EXPECT(result == arr.end()); } -TEST_CASE(find_basic) { +TEST_CASE(find_basic) +{ migraphx::array arr = {10, 20, 30, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 30); + auto result = migraphx::find(arr.begin(), arr.end(), 30); EXPECT(result == arr.begin() + 2); } -TEST_CASE(find_not_found) { +TEST_CASE(find_not_found) +{ migraphx::array arr = {10, 20, 30, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 50); + auto result = migraphx::find(arr.begin(), arr.end(), 50); EXPECT(result == arr.end()); } -TEST_CASE(find_first_element) { +TEST_CASE(find_first_element) +{ migraphx::array arr = {10, 20, 30, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 10); + auto result = migraphx::find(arr.begin(), arr.end(), 10); EXPECT(result == arr.begin()); } -TEST_CASE(find_duplicates) { +TEST_CASE(find_duplicates) +{ migraphx::array arr = {10, 20, 30, 20, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 20); + auto result = migraphx::find(arr.begin(), arr.end(), 20); EXPECT(result == arr.begin() + 1); } -TEST_CASE(any_of_true) { +TEST_CASE(any_of_true) +{ migraphx::array arr = {1, 3, 5, 7}; EXPECT(migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); } -TEST_CASE(any_of_false) { +TEST_CASE(any_of_false) +{ migraphx::array arr = {1, 3, 5, 7}; EXPECT(!migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); } -TEST_CASE(any_of_empty) { +TEST_CASE(any_of_empty) +{ empty_range arr = {}; EXPECT(!migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); } -TEST_CASE(any_of_first_element) { +TEST_CASE(any_of_first_element) +{ migraphx::array arr = {10, 1, 2, 3}; EXPECT(migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); } -TEST_CASE(none_of_true) { +TEST_CASE(none_of_true) +{ migraphx::array arr = {1, 3, 5, 7}; EXPECT(migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); } -TEST_CASE(none_of_false) { +TEST_CASE(none_of_false) +{ migraphx::array arr = {1, 3, 5, 7}; EXPECT(!migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); } -TEST_CASE(none_of_empty) { +TEST_CASE(none_of_empty) +{ empty_range arr = {}; EXPECT(migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); } -TEST_CASE(all_of_true) { +TEST_CASE(all_of_true) +{ migraphx::array arr = {2, 4, 6, 8}; EXPECT(migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } -TEST_CASE(all_of_false) { +TEST_CASE(all_of_false) +{ migraphx::array arr = {2, 4, 5, 8}; EXPECT(!migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } -TEST_CASE(all_of_empty) { +TEST_CASE(all_of_empty) +{ empty_range arr = {}; EXPECT(migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); } -TEST_CASE(all_of_single_true) { +TEST_CASE(all_of_single_true) +{ migraphx::array arr = {4}; EXPECT(migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } -TEST_CASE(all_of_single_false) { +TEST_CASE(all_of_single_false) +{ migraphx::array arr = {5}; EXPECT(!migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } -TEST_CASE(search_found) { +TEST_CASE(search_found) +{ migraphx::array haystack = {1, 2, 3, 4, 3, 4}; - migraphx::array needle = {3, 4}; + migraphx::array needle = {3, 4}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } -TEST_CASE(search_not_found) { +TEST_CASE(search_not_found) +{ migraphx::array haystack = {1, 2, 3, 4, 5}; - migraphx::array needle = {6, 7}; + migraphx::array needle = {6, 7}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } -TEST_CASE(search_empty_needle) { +TEST_CASE(search_empty_needle) +{ migraphx::array haystack = {1, 2, 3}; - empty_range needle = {}; + empty_range needle = {}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } -TEST_CASE(search_empty_haystack) { - empty_range haystack = {}; +TEST_CASE(search_empty_haystack) +{ + empty_range haystack = {}; migraphx::array needle = {1}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } -TEST_CASE(search_exact_match) { +TEST_CASE(search_exact_match) +{ migraphx::array haystack = {1, 2, 3}; - migraphx::array needle = {1, 2, 3}; + migraphx::array needle = {1, 2, 3}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } -TEST_CASE(search_partial_match) { +TEST_CASE(search_partial_match) +{ migraphx::array haystack = {1, 2, 1, 2, 3}; - migraphx::array needle = {1, 2, 3}; + migraphx::array needle = {1, 2, 3}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } // Additional search tests (extensive) -TEST_CASE(search_overlapping_pattern) { +TEST_CASE(search_overlapping_pattern) +{ migraphx::array haystack = {1, 2, 1, 2, 1, 2, 3, 4}; - migraphx::array needle = {1, 2, 3}; + migraphx::array needle = {1, 2, 3}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } -TEST_CASE(search_pattern_at_end) { +TEST_CASE(search_pattern_at_end) +{ migraphx::array haystack = {1, 2, 3, 4, 5, 6}; - migraphx::array needle = {5, 6}; + migraphx::array needle = {5, 6}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } -TEST_CASE(search_pattern_at_beginning) { +TEST_CASE(search_pattern_at_beginning) +{ migraphx::array haystack = {1, 2, 3, 4, 5, 6}; - migraphx::array needle = {1, 2}; + migraphx::array needle = {1, 2}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } -TEST_CASE(search_single_element_pattern) { +TEST_CASE(search_single_element_pattern) +{ migraphx::array haystack = {1, 3, 5, 7, 9}; - migraphx::array needle = {5}; + migraphx::array needle = {5}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } -TEST_CASE(search_single_element_pattern_not_found) { +TEST_CASE(search_single_element_pattern_not_found) +{ migraphx::array haystack = {1, 3, 5, 7, 9}; - migraphx::array needle = {4}; + migraphx::array needle = {4}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } -TEST_CASE(search_repeated_elements) { +TEST_CASE(search_repeated_elements) +{ migraphx::array haystack = {2, 2, 2, 2, 1, 2, 2, 3}; - migraphx::array needle = {2, 2, 3}; + migraphx::array needle = {2, 2, 3}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 5); } -TEST_CASE(search_partial_match_backtrack) { +TEST_CASE(search_partial_match_backtrack) +{ migraphx::array haystack = {1, 2, 3, 1, 2, 4, 1, 2, 3, 4}; - migraphx::array needle = {1, 2, 3, 4}; + migraphx::array needle = {1, 2, 3, 4}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 6); } -TEST_CASE(search_multiple_false_starts) { +TEST_CASE(search_multiple_false_starts) +{ migraphx::array haystack = {1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 5, 6}; - migraphx::array needle = {1, 2, 3, 4}; + migraphx::array needle = {1, 2, 3, 4}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 6); } -TEST_CASE(search_needle_longer_than_haystack) { +TEST_CASE(search_needle_longer_than_haystack) +{ migraphx::array haystack = {1, 2, 3}; - migraphx::array needle = {1, 2, 3, 4, 5}; + migraphx::array needle = {1, 2, 3, 4, 5}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } -TEST_CASE(search_identical_arrays) { +TEST_CASE(search_identical_arrays) +{ migraphx::array haystack = {5, 10, 15, 20}; - migraphx::array needle = {5, 10, 15, 20}; + migraphx::array needle = {5, 10, 15, 20}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } -TEST_CASE(search_all_same_elements) { +TEST_CASE(search_all_same_elements) +{ migraphx::array haystack = {3, 3, 3, 3, 3, 3}; - migraphx::array needle = {3, 3, 3}; + migraphx::array needle = {3, 3, 3}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } -TEST_CASE(search_pattern_appears_multiple_times) { +TEST_CASE(search_pattern_appears_multiple_times) +{ migraphx::array haystack = {1, 2, 3, 1, 2, 3, 1, 2, 3}; - migraphx::array needle = {2, 3}; + migraphx::array needle = {2, 3}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 1); } -TEST_CASE(search_partial_range) { +TEST_CASE(search_partial_range) +{ migraphx::array haystack = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - migraphx::array needle = {4, 5}; - auto result = migraphx::search(haystack.begin() + 2, haystack.begin() + 7, needle.begin(), needle.end()); + migraphx::array needle = {4, 5}; + auto result = + migraphx::search(haystack.begin() + 2, haystack.begin() + 7, needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } -TEST_CASE(search_stress_long_pattern) { +TEST_CASE(search_stress_long_pattern) +{ migraphx::array haystack = {1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 1}; - migraphx::array needle = {2, 3, 4, 5, 6, 7}; + migraphx::array needle = {2, 3, 4, 5, 6, 7}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 5); } -TEST_CASE(search_stress_worst_case_complexity) { +TEST_CASE(search_stress_worst_case_complexity) +{ migraphx::array haystack = {1, 1, 1, 1, 1, 1, 1, 2}; - migraphx::array needle = {1, 1, 1, 1, 1, 1, 2}; + migraphx::array needle = {1, 1, 1, 1, 1, 1, 2}; auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 1); } -TEST_CASE(inner_product_basic) { +TEST_CASE(inner_product_basic) +{ migraphx::array a = {1, 2, 3}; migraphx::array b = {4, 5, 6}; - auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 0); + auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 0); EXPECT(result == 32); } -TEST_CASE(inner_product_custom_ops) { +TEST_CASE(inner_product_custom_ops) +{ migraphx::array a = {1, 2, 3}; migraphx::array b = {4, 5, 6}; - auto result = migraphx::inner_product( - a.begin(), a.end(), b.begin(), 1, + auto result = migraphx::inner_product( + a.begin(), + a.end(), + b.begin(), + 1, [](int x, int y) { return x * y; }, - [](int x, int y) { return x + y; } - ); + [](int x, int y) { return x + y; }); EXPECT(result == 315); } -TEST_CASE(inner_product_empty) { +TEST_CASE(inner_product_empty) +{ empty_range a = {}; empty_range b = {}; - auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 42); + auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 42); EXPECT(result == 42); } -TEST_CASE(inner_product_single) { +TEST_CASE(inner_product_single) +{ migraphx::array a = {3}; migraphx::array b = {7}; - auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 5); + auto result = migraphx::inner_product(a.begin(), a.end(), b.begin(), 5); EXPECT(result == 26); } -TEST_CASE(equal_true) { +TEST_CASE(equal_true) +{ migraphx::array a = {1, 2, 3, 4}; migraphx::array b = {1, 2, 3, 4}; EXPECT(migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); } -TEST_CASE(equal_false) { +TEST_CASE(equal_false) +{ migraphx::array a = {1, 2, 3, 4}; migraphx::array b = {1, 2, 3, 5}; EXPECT(!migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); } -TEST_CASE(equal_empty) { +TEST_CASE(equal_empty) +{ empty_range a = {}; empty_range b = {}; EXPECT(migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); } -TEST_CASE(equal_custom_predicate) { +TEST_CASE(equal_custom_predicate) +{ migraphx::array a = {1, 2, 3}; migraphx::array b = {2, 4, 6}; EXPECT(migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x * 2 == y; })); } -TEST_CASE(iota_basic) { +TEST_CASE(iota_basic) +{ migraphx::array arr = {0, 0, 0, 0, 0}; migraphx::iota(arr.begin(), arr.end(), 10); migraphx::array expected = {10, 11, 12, 13, 14}; EXPECT(arr == expected); } -TEST_CASE(iota_empty) { +TEST_CASE(iota_empty) +{ empty_range arr = {}; migraphx::iota(arr.begin(), arr.end(), 5); } -TEST_CASE(iota_single) { +TEST_CASE(iota_single) +{ migraphx::array arr = {0}; migraphx::iota(arr.begin(), arr.end(), 42); EXPECT(arr[0] == 42); } -TEST_CASE(iota_negative) { +TEST_CASE(iota_negative) +{ migraphx::array arr = {0, 0, 0}; migraphx::iota(arr.begin(), arr.end(), -5); migraphx::array expected = {-5, -4, -3}; EXPECT(arr == expected); } -TEST_CASE(min_element_basic) { +TEST_CASE(min_element_basic) +{ migraphx::array arr = {3, 1, 4, 1, 5}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin() + 1); } -TEST_CASE(min_element_empty) { +TEST_CASE(min_element_empty) +{ empty_range arr = {}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(min_element_single) { +TEST_CASE(min_element_single) +{ migraphx::array arr = {42}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin()); } -TEST_CASE(min_element_all_equal) { +TEST_CASE(min_element_all_equal) +{ migraphx::array arr = {5, 5, 5, 5}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin()); } -TEST_CASE(min_element_custom_compare) { +TEST_CASE(min_element_custom_compare) +{ migraphx::array arr = {1, 2, 3, 4}; auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::greater{}); EXPECT(result == arr.begin() + 3); } -TEST_CASE(rotate_left_by_two) { - migraphx::array arr = {1, 2, 3, 4, 5, 6}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); +TEST_CASE(rotate_left_by_two) +{ + migraphx::array arr = {1, 2, 3, 4, 5, 6}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); migraphx::array expected = {3, 4, 5, 6, 1, 2}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); } -TEST_CASE(rotate_right_by_one) { - migraphx::array arr = {1, 2, 3, 4, 5}; - auto result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); +TEST_CASE(rotate_right_by_one) +{ + migraphx::array arr = {1, 2, 3, 4, 5}; + auto result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); migraphx::array expected = {5, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); } -TEST_CASE(rotate_half_array) { - migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); +TEST_CASE(rotate_half_array) +{ + migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); migraphx::array expected = {5, 6, 7, 8, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); } -TEST_CASE(rotate_almost_full) { - migraphx::array arr = {1, 2, 3, 4, 5}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); +TEST_CASE(rotate_almost_full) +{ + migraphx::array arr = {1, 2, 3, 4, 5}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); migraphx::array expected = {5, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); } -TEST_CASE(rotate_two_elements) { - migraphx::array arr = {1, 2}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); +TEST_CASE(rotate_two_elements) +{ + migraphx::array arr = {1, 2}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); migraphx::array expected = {2, 1}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); } -TEST_CASE(rotate_partial_range) { +TEST_CASE(rotate_partial_range) +{ migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; auto result = migraphx::rotate(arr.begin() + 1, arr.begin() + 3, arr.begin() + 5); migraphx::array expected = {1, 4, 5, 2, 3, 6, 7}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 3); } -TEST_CASE(rotate_with_duplicates) { - migraphx::array arr = {1, 1, 2, 2, 3, 3}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); +TEST_CASE(rotate_with_duplicates) +{ + migraphx::array arr = {1, 1, 2, 2, 3, 3}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); migraphx::array expected = {2, 2, 3, 3, 1, 1}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); } -TEST_CASE(rotate_stress_test_large_shift) { - migraphx::array arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); +TEST_CASE(rotate_stress_test_large_shift) +{ + migraphx::array arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + auto result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); migraphx::array expected = {7, 8, 9, 0, 1, 2, 3, 4, 5, 6}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 3); } -TEST_CASE(rotate_edge_case_middle_equals_first) { - migraphx::array arr = {1, 2, 3, 4}; +TEST_CASE(rotate_edge_case_middle_equals_first) +{ + migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; - auto result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); + auto result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); EXPECT(arr == original); EXPECT(result == arr.end()); } -TEST_CASE(rotate_edge_case_middle_equals_last) { - migraphx::array arr = {1, 2, 3, 4}; +TEST_CASE(rotate_edge_case_middle_equals_last) +{ + migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; - auto result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); + auto result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); EXPECT(arr == original); EXPECT(result == arr.begin()); } -TEST_CASE(upper_bound_basic) { +TEST_CASE(upper_bound_basic) +{ migraphx::array arr = {1, 2, 2, 3, 4}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.begin() + 3); } -TEST_CASE(upper_bound_not_found) { +TEST_CASE(upper_bound_not_found) +{ migraphx::array arr = {1, 2, 3, 4}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_first_element) { +TEST_CASE(upper_bound_first_element) +{ migraphx::array arr = {1, 2, 3, 4}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); EXPECT(result == arr.begin()); } -TEST_CASE(upper_bound_empty) { +TEST_CASE(upper_bound_empty) +{ empty_range arr = {}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_all_equal) { +TEST_CASE(upper_bound_all_equal) +{ migraphx::array arr = {2, 2, 2}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_multiple_duplicates) { +TEST_CASE(upper_bound_multiple_duplicates) +{ migraphx::array arr = {1, 2, 2, 2, 2, 3, 4, 5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.begin() + 5); } -TEST_CASE(upper_bound_all_smaller) { +TEST_CASE(upper_bound_all_smaller) +{ migraphx::array arr = {1, 2, 3, 4, 5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); EXPECT(result == arr.begin()); } -TEST_CASE(upper_bound_all_larger) { +TEST_CASE(upper_bound_all_larger) +{ migraphx::array arr = {1, 2, 3, 4, 5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 10, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_single_element_match) { +TEST_CASE(upper_bound_single_element_match) +{ migraphx::array arr = {5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_single_element_smaller) { +TEST_CASE(upper_bound_single_element_smaller) +{ migraphx::array arr = {5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::less{}); EXPECT(result == arr.begin()); } -TEST_CASE(upper_bound_single_element_larger) { +TEST_CASE(upper_bound_single_element_larger) +{ migraphx::array arr = {5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_beginning_duplicates) { +TEST_CASE(upper_bound_beginning_duplicates) +{ migraphx::array arr = {1, 1, 1, 4, 5, 6}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 1, migraphx::less{}); EXPECT(result == arr.begin() + 3); } -TEST_CASE(upper_bound_end_duplicates) { +TEST_CASE(upper_bound_end_duplicates) +{ migraphx::array arr = {1, 2, 3, 5, 5, 5}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } -TEST_CASE(upper_bound_middle_value) { +TEST_CASE(upper_bound_middle_value) +{ migraphx::array arr = {1, 3, 5, 7, 9, 11, 13}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); EXPECT(result == arr.begin() + 4); } -TEST_CASE(upper_bound_partial_range) { +TEST_CASE(upper_bound_partial_range) +{ migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; auto result = migraphx::upper_bound(arr.begin() + 2, arr.begin() + 6, 4, migraphx::less{}); EXPECT(result == arr.begin() + 4); } -TEST_CASE(upper_bound_reverse_comparator) { +TEST_CASE(upper_bound_reverse_comparator) +{ migraphx::array arr = {5, 4, 3, 2, 1}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::greater{}); EXPECT(result == arr.begin() + 3); } -TEST_CASE(upper_bound_large_array_power_of_two) { +TEST_CASE(upper_bound_large_array_power_of_two) +{ migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 8, migraphx::less{}); EXPECT(result == arr.begin() + 8); } -TEST_CASE(upper_bound_stress_binary_search) { +TEST_CASE(upper_bound_stress_binary_search) +{ migraphx::array arr = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; auto result = migraphx::upper_bound(arr.begin(), arr.end(), 16, migraphx::less{}); EXPECT(result == arr.begin() + 8); } -TEST_CASE(upper_bound_stress_test_boundary) { +TEST_CASE(upper_bound_stress_test_boundary) +{ migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; - for (int i = 1; i <= 7; ++i) { + for(int i = 1; i <= 7; ++i) + { auto result = migraphx::upper_bound(arr.begin(), arr.end(), i, migraphx::less{}); EXPECT(result == arr.begin() + i); } } -TEST_CASE(sort_basic) { +TEST_CASE(sort_basic) +{ migraphx::array arr = {5, 2, 8, 1, 9}; migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); migraphx::array expected = {1, 2, 5, 8, 9}; EXPECT(arr == expected); } -TEST_CASE(sort_already_sorted) { - migraphx::array arr = {1, 2, 3, 4}; +TEST_CASE(sort_already_sorted) +{ + migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); EXPECT(arr == original); } -TEST_CASE(sort_reverse_sorted) { +TEST_CASE(sort_reverse_sorted) +{ migraphx::array arr = {4, 3, 2, 1}; migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4}; EXPECT(arr == expected); } -TEST_CASE(sort_duplicates) { +TEST_CASE(sort_duplicates) +{ migraphx::array arr = {3, 1, 4, 1, 5, 2}; migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); migraphx::array expected = {1, 1, 2, 3, 4, 5}; EXPECT(arr == expected); } -TEST_CASE(sort_empty) { +TEST_CASE(sort_empty) +{ empty_range arr = {}; migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); } -TEST_CASE(sort_single) { - migraphx::array arr = {42}; +TEST_CASE(sort_single) +{ + migraphx::array arr = {42}; migraphx::array original = arr; migraphx::sort(arr.begin(), arr.end(), migraphx::less{}); EXPECT(arr == original); } -TEST_CASE(sort_default_comparator) { +TEST_CASE(sort_default_comparator) +{ migraphx::array arr = {3, 1, 4, 2}; migraphx::sort(arr.begin(), arr.end()); migraphx::array expected = {1, 2, 3, 4}; EXPECT(arr == expected); } -TEST_CASE(stable_sort_basic) { +TEST_CASE(stable_sort_basic) +{ migraphx::array arr = {5, 2, 8, 1, 9}; migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); migraphx::array expected = {1, 2, 5, 8, 9}; EXPECT(arr == expected); } -TEST_CASE(stable_sort_empty) { +TEST_CASE(stable_sort_empty) +{ empty_range arr = {}; migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); } -TEST_CASE(stable_sort_single) { - migraphx::array arr = {42}; +TEST_CASE(stable_sort_single) +{ + migraphx::array arr = {42}; migraphx::array original = arr; migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); EXPECT(arr == original); } -TEST_CASE(stable_sort_already_sorted) { - migraphx::array arr = {1, 2, 3, 4}; +TEST_CASE(stable_sort_already_sorted) +{ + migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; migraphx::stable_sort(arr.begin(), arr.end(), migraphx::less{}); EXPECT(arr == original); } -TEST_CASE(stable_sort_default_comparator) { +TEST_CASE(stable_sort_default_comparator) +{ migraphx::array arr = {3, 1, 4, 2}; migraphx::stable_sort(arr.begin(), arr.end()); migraphx::array expected = {1, 2, 3, 4}; EXPECT(arr == expected); } -TEST_CASE(merge_basic) { - migraphx::array arr1 = {1, 3, 5}; - migraphx::array arr2 = {2, 4, 6}; +TEST_CASE(merge_basic) +{ + migraphx::array arr1 = {1, 3, 5}; + migraphx::array arr2 = {2, 4, 6}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4, 5, 6}; EXPECT(result == expected); } -TEST_CASE(merge_empty_first) { - empty_range arr1 = {}; - migraphx::array arr2 = {1, 2, 3}; +TEST_CASE(merge_empty_first) +{ + empty_range arr1 = {}; + migraphx::array arr2 = {1, 2, 3}; migraphx::array result = {0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); EXPECT(result == arr2); } -TEST_CASE(merge_empty_second) { - migraphx::array arr1 = {1, 2, 3}; - empty_range arr2 = {}; +TEST_CASE(merge_empty_second) +{ + migraphx::array arr1 = {1, 2, 3}; + empty_range arr2 = {}; migraphx::array result = {0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); EXPECT(result == arr1); } -TEST_CASE(merge_both_empty) { - empty_range arr1 = {}; - empty_range arr2 = {}; +TEST_CASE(merge_both_empty) +{ + empty_range arr1 = {}; + empty_range arr2 = {}; empty_range result = {}; - auto end_it = migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + auto end_it = migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); EXPECT(end_it == result.end()); } -TEST_CASE(merge_overlapping_ranges) { - migraphx::array arr1 = {1, 3, 5, 7}; - migraphx::array arr2 = {2, 6}; +TEST_CASE(merge_overlapping_ranges) +{ + migraphx::array arr1 = {1, 3, 5, 7}; + migraphx::array arr2 = {2, 6}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 5, 6, 7}; EXPECT(result == expected); } -TEST_CASE(merge_duplicates) { - migraphx::array arr1 = {1, 2, 3}; - migraphx::array arr2 = {2, 3, 4}; +TEST_CASE(merge_duplicates) +{ + migraphx::array arr1 = {1, 2, 3}; + migraphx::array arr2 = {2, 3, 4}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 2, 3, 3, 4}; EXPECT(result == expected); } // Additional merge tests (extensive) -TEST_CASE(merge_different_sizes) { - migraphx::array arr1 = {1, 5}; - migraphx::array arr2 = {2, 3, 4, 6}; +TEST_CASE(merge_different_sizes) +{ + migraphx::array arr1 = {1, 5}; + migraphx::array arr2 = {2, 3, 4, 6}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4, 5, 6}; EXPECT(result == expected); } -TEST_CASE(merge_first_all_smaller) { - migraphx::array arr1 = {1, 2, 3}; - migraphx::array arr2 = {4, 5, 6}; +TEST_CASE(merge_first_all_smaller) +{ + migraphx::array arr1 = {1, 2, 3}; + migraphx::array arr2 = {4, 5, 6}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4, 5, 6}; EXPECT(result == expected); } -TEST_CASE(merge_first_all_larger) { - migraphx::array arr1 = {4, 5, 6}; - migraphx::array arr2 = {1, 2, 3}; +TEST_CASE(merge_first_all_larger) +{ + migraphx::array arr1 = {4, 5, 6}; + migraphx::array arr2 = {1, 2, 3}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4, 5, 6}; EXPECT(result == expected); } -TEST_CASE(merge_interleaved) { - migraphx::array arr1 = {1, 3, 5, 7}; - migraphx::array arr2 = {2, 4, 6, 8}; +TEST_CASE(merge_interleaved) +{ + migraphx::array arr1 = {1, 3, 5, 7}; + migraphx::array arr2 = {2, 4, 6, 8}; migraphx::array result = {0, 0, 0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4, 5, 6, 7, 8}; EXPECT(result == expected); } -TEST_CASE(merge_many_duplicates) { - migraphx::array arr1 = {1, 1, 2, 2}; - migraphx::array arr2 = {1, 2, 2, 3}; +TEST_CASE(merge_many_duplicates) +{ + migraphx::array arr1 = {1, 1, 2, 2}; + migraphx::array arr2 = {1, 2, 2, 3}; migraphx::array result = {0, 0, 0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 1, 1, 2, 2, 2, 2, 3}; EXPECT(result == expected); } -TEST_CASE(merge_all_equal_elements) { - migraphx::array arr1 = {5, 5, 5}; - migraphx::array arr2 = {5, 5}; +TEST_CASE(merge_all_equal_elements) +{ + migraphx::array arr1 = {5, 5, 5}; + migraphx::array arr2 = {5, 5}; migraphx::array result = {0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {5, 5, 5, 5, 5}; EXPECT(result == expected); } -TEST_CASE(merge_single_elements) { - migraphx::array arr1 = {3}; - migraphx::array arr2 = {1}; +TEST_CASE(merge_single_elements) +{ + migraphx::array arr1 = {3}; + migraphx::array arr2 = {1}; migraphx::array result = {0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 3}; EXPECT(result == expected); } -TEST_CASE(merge_one_single_element) { - migraphx::array arr1 = {3}; - migraphx::array arr2 = {1, 2, 4, 5}; +TEST_CASE(merge_one_single_element) +{ + migraphx::array arr1 = {3}; + migraphx::array arr2 = {1, 2, 4, 5}; migraphx::array result = {0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 4, 5}; EXPECT(result == expected); } -TEST_CASE(merge_reverse_order) { - migraphx::array arr1 = {6, 4, 2}; - migraphx::array arr2 = {5, 3, 1}; +TEST_CASE(merge_reverse_order) +{ + migraphx::array arr1 = {6, 4, 2}; + migraphx::array arr2 = {5, 3, 1}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::greater{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::greater{}); migraphx::array expected = {6, 5, 4, 3, 2, 1}; EXPECT(result == expected); } -TEST_CASE(merge_negative_numbers) { - migraphx::array arr1 = {-5, -2, 1}; - migraphx::array arr2 = {-3, 0, 3}; +TEST_CASE(merge_negative_numbers) +{ + migraphx::array arr1 = {-5, -2, 1}; + migraphx::array arr2 = {-3, 0, 3}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {-5, -3, -2, 0, 1, 3}; EXPECT(result == expected); } -TEST_CASE(merge_large_difference) { - migraphx::array arr1 = {1, 1000, 2000}; - migraphx::array arr2 = {2, 500, 1500}; +TEST_CASE(merge_large_difference) +{ + migraphx::array arr1 = {1, 1000, 2000}; + migraphx::array arr2 = {2, 500, 1500}; migraphx::array result = {0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 500, 1000, 1500, 2000}; EXPECT(result == expected); } -TEST_CASE(merge_partial_ranges) { - migraphx::array arr1 = {0, 1, 2, 3, 4, 5, 6, 7}; - migraphx::array arr2 = {10, 11, 12, 13, 14, 15}; +TEST_CASE(merge_partial_ranges) +{ + migraphx::array arr1 = {0, 1, 2, 3, 4, 5, 6, 7}; + migraphx::array arr2 = {10, 11, 12, 13, 14, 15}; migraphx::array result = {0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin() + 2, arr1.begin() + 5, arr2.begin() + 1, arr2.begin() + 3, result.begin(), migraphx::less{}); + migraphx::merge(arr1.begin() + 2, + arr1.begin() + 5, + arr2.begin() + 1, + arr2.begin() + 3, + result.begin(), + migraphx::less{}); migraphx::array expected = {2, 3, 4, 11, 12}; EXPECT(result == expected); } -TEST_CASE(merge_stability_test) { - migraphx::array arr1 = {1, 3, 5, 7}; - migraphx::array arr2 = {2, 3, 6, 7}; +TEST_CASE(merge_stability_test) +{ + migraphx::array arr1 = {1, 3, 5, 7}; + migraphx::array arr2 = {2, 3, 6, 7}; migraphx::array result = {0, 0, 0, 0, 0, 0, 0, 0}; - migraphx::merge(arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); + migraphx::merge( + arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); migraphx::array expected = {1, 2, 3, 3, 5, 6, 7, 7}; EXPECT(result == expected); } -TEST_CASE(common_mistakes_off_by_one) { +TEST_CASE(common_mistakes_off_by_one) +{ migraphx::array arr = {5}; - auto result = migraphx::find(arr.begin(), arr.end(), 5); + auto result = migraphx::find(arr.begin(), arr.end(), 5); EXPECT(result == arr.begin()); result = migraphx::find(arr.begin(), arr.end(), 10); EXPECT(result == arr.end()); } -TEST_CASE(common_mistakes_empty_ranges) { +TEST_CASE(common_mistakes_empty_ranges) +{ empty_range empty = {}; EXPECT(migraphx::is_sorted(empty.begin(), empty.end(), migraphx::less{})); EXPECT(migraphx::all_of(empty.begin(), empty.end(), [](int) { return false; })); @@ -915,15 +1090,20 @@ TEST_CASE(common_mistakes_empty_ranges) { auto min_it = migraphx::min_element(empty.begin(), empty.end(), migraphx::less{}); EXPECT(min_it == empty.end()); } -TEST_CASE(common_mistakes_self_assignment) { +TEST_CASE(common_mistakes_self_assignment) +{ int x = 42; migraphx::swap(x, x); EXPECT(x == 42); } -TEST_CASE(common_mistakes_predicate_consistency) { +TEST_CASE(common_mistakes_predicate_consistency) +{ migraphx::array arr = {1, 2, 3, 4}; - int call_count = 0; - auto predicate = [&call_count](int x) { call_count++; return x > 2; }; + int call_count = 0; + auto predicate = [&call_count](int x) { + call_count++; + return x > 2; + }; auto result = migraphx::find_if(arr.begin(), arr.end(), predicate); EXPECT(result == arr.begin() + 2); EXPECT(call_count == 3); From ab3e73a6775f6089cd3571337db0339e03ef3c8b Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 4 Aug 2025 11:43:48 -0500 Subject: [PATCH 05/20] Apply fixits --- src/targets/gpu/CMakeLists.txt | 23 +- .../include/migraphx/kernels/algorithm.hpp | 2 +- .../kernels/include/migraphx/kernels/test.hpp | 1 + test/gpu/kernels/CMakeLists.txt | 40 +--- test/gpu/kernels/algorithm.cpp | 204 ++++++++---------- 5 files changed, 112 insertions(+), 158 deletions(-) diff --git a/src/targets/gpu/CMakeLists.txt b/src/targets/gpu/CMakeLists.txt index 497ac403cec..a05841aab47 100644 --- a/src/targets/gpu/CMakeLists.txt +++ b/src/targets/gpu/CMakeLists.txt @@ -108,23 +108,26 @@ target_include_directories(migraphx_device PRIVATE $) +target_link_libraries(compile_migraphx_gpu_kernels INTERFACE compile_for_gpu) +if(MIGRAPHX_USE_COMPOSABLEKERNEL) + target_link_libraries(compile_migraphx_gpu_kernels composable_kernel::jit_library) +endif() + +add_library(migraphx_gpu_kernel_file_check EXCLUDE_FROM_ALL) foreach(KERNEL_FILE ${KERNEL_FILES}) get_filename_component(KERNEL_BASE_FILE ${KERNEL_FILE} NAME_WE) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/kernels/include/migraphx/kernels/${KERNEL_BASE_FILE}.cpp "#include \n") - target_sources(kernel_file_check PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/kernels/include/migraphx/kernels/${KERNEL_BASE_FILE}.cpp) + target_sources(migraphx_gpu_kernel_file_check PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/kernels/include/migraphx/kernels/${KERNEL_BASE_FILE}.cpp) endforeach() -target_compile_definitions(kernel_file_check PRIVATE -DMIGRAPHX_NLOCAL=256) -target_compile_definitions(kernel_file_check PRIVATE -DMIGRAPHX_WAVEFRONTSIZE=64) -target_include_directories(kernel_file_check PRIVATE $) -target_link_libraries(kernel_file_check compile_for_gpu) -if(MIGRAPHX_USE_COMPOSABLEKERNEL) - target_link_libraries(kernel_file_check composable_kernel::jit_library) -endif() +target_link_libraries(migraphx_gpu_kernel_file_check compile_migraphx_gpu_kernels) -rocm_clang_tidy_check(kernel_file_check) +rocm_clang_tidy_check(migraphx_gpu_kernel_file_check) file(GLOB JIT_GPU_SRCS CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/jit/*.cpp) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp index 682b01a4fb4..b6cc2007061 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp @@ -281,7 +281,7 @@ constexpr Iterator upper_bound(Iterator first, Iterator last, const T& value, Co while(count > 0) { - auto it = first; + auto *it = first; auto step = count / 2; it += step; diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index 786fe0f2c85..0680d83eea0 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -239,6 +239,7 @@ __device__ void failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) { // TODO: Check failures across multiple lanes + // NOLINTNEXTLINE(readability-static-accessed-through-instance) if(not bool(x.value()) and threadIdx.x == 0) { println_once(func); diff --git a/test/gpu/kernels/CMakeLists.txt b/test/gpu/kernels/CMakeLists.txt index b5e50a77670..86a2e0bd71d 100644 --- a/test/gpu/kernels/CMakeLists.txt +++ b/test/gpu/kernels/CMakeLists.txt @@ -32,41 +32,7 @@ rocm_add_test_executable(test_gpu_kernels main.cpp) target_link_libraries(test_gpu_kernels migraphx migraphx_gpu kernel_tests) +add_library(migraphx_gpu_test_kernel_file_check EXCLUDE_FROM_ALL ${KERNELS_TESTS}) +target_link_libraries(migraphx_gpu_test_kernel_file_check compile_migraphx_gpu_kernels) +rocm_clang_tidy_check(migraphx_gpu_test_kernel_file_check) - -# foreach(TEST ${KERNELS_TESTS}) -# get_filename_component(BASE_NAME ${TEST} NAME_WE) -# rocm_add_test_executable(test_gpu_kernels_${BASE_NAME} main.cpp) -# rocm_clang_tidy_check(test_gpu_kernels_${BASE_NAME}) -# endforeach() - - - - - -# function(add_gpu_kernels_test ${TEST_NAME}) -# add_executable(${TEST_NAME} ${ARGN}) -# rocm_clang_tidy_check(${TEST_NAME}) -# target_link_libraries(${TEST_NAME} migraphx migraphx_all_targets) -# target_include_directories(${TEST_NAME} PUBLIC ../include) -# endfunction(add_kernels_test) - - -# add_executable(test_kernels ${VERIFY_TESTS}) -# rocm_mark_as_test(test_kernels) -# rocm_install_test(TARGETS test_kernels) -# target_link_libraries(test_kernels migraphx migraphx_all_targets) -# target_include_directories(test_kernels PUBLIC ../include) -# rocm_clang_tidy_check(test_kernels) - -# foreach(SECTION general reduce rnn conv gemm) -# rocm_add_test(NAME test_kernels_${SECTION} COMMAND test_kernels ${SECTION}) -# set_tests_properties(test_kernels_${SECTION} PROPERTIES -# COST 100 -# ) -# if(MIGRAPHX_ENABLE_GPU) -# set_tests_properties(test_kernels_${SECTION} PROPERTIES -# RESOURCE_LOCK gpu -# ) -# endif() -# endforeach() diff --git a/test/gpu/kernels/algorithm.cpp b/test/gpu/kernels/algorithm.cpp index d77a1828e25..13da164da61 100644 --- a/test/gpu/kernels/algorithm.cpp +++ b/test/gpu/kernels/algorithm.cpp @@ -12,22 +12,24 @@ struct empty_range TEST_CASE(swap_basic) { - int a = 5, b = 10; + int a = 5; + int b = 10; migraphx::swap(a, b); - EXPECT(a == 10 && b == 5); + EXPECT(a == 10 and b == 5); } TEST_CASE(swap_same_value) { - int a = 7, b = 7; + int a = 7; + int b = 7; migraphx::swap(a, b); - EXPECT(a == 7 && b == 7); + EXPECT(a == 7 and b == 7); } TEST_CASE(swap_different_types) { double a = 3.14; double b = 2.71; migraphx::swap(a, b); - EXPECT(migraphx::float_equal(a, 2.71) && migraphx::float_equal(b, 3.14)); + EXPECT(migraphx::float_equal(a, 2.71) and migraphx::float_equal(b, 3.14)); } TEST_CASE(iter_swap_basic) { @@ -55,15 +57,15 @@ TEST_CASE(less_functor) { migraphx::less comp; EXPECT(comp(1, 2)); - EXPECT(!comp(2, 1)); - EXPECT(!comp(5, 5)); + EXPECT( not comp(2, 1)); + EXPECT( not comp(5, 5)); } TEST_CASE(greater_functor) { migraphx::greater comp; EXPECT(comp(2, 1)); - EXPECT(!comp(1, 2)); - EXPECT(!comp(5, 5)); + EXPECT( not comp(1, 2)); + EXPECT( not comp(5, 5)); } TEST_CASE(accumulate_basic) @@ -104,7 +106,7 @@ TEST_CASE(copy_empty_range) { migraphx::array src = {1, 2, 3}; migraphx::array dst = {0, 0, 0}; - auto result = migraphx::copy(src.begin(), src.begin(), dst.begin()); + auto *result = migraphx::copy(src.begin(), src.begin(), dst.begin()); EXPECT(result == dst.begin()); migraphx::array expected = {0, 0, 0}; EXPECT(dst == expected); @@ -121,7 +123,7 @@ TEST_CASE(copy_if_basic) { migraphx::array src = {1, 2, 3, 4, 5, 6}; migraphx::array dst = {0, 0, 0, 0, 0, 0}; - auto end_it = + auto *end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(dst[0] == 2); EXPECT(dst[1] == 4); @@ -132,7 +134,7 @@ TEST_CASE(copy_if_none_match) { migraphx::array src = {1, 3, 5}; migraphx::array dst = {0, 0, 0}; - auto end_it = + auto *end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(end_it == dst.begin()); migraphx::array expected = {0, 0, 0}; @@ -142,7 +144,7 @@ TEST_CASE(copy_if_all_match) { migraphx::array src = {2, 4, 6}; migraphx::array dst = {0, 0, 0}; - auto end_it = + auto *end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(end_it == dst.end()); EXPECT(src == dst); @@ -151,31 +153,31 @@ TEST_CASE(copy_if_all_match) TEST_CASE(is_sorted_until_sorted) { migraphx::array arr = {1, 2, 3, 4}; - auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_until_unsorted) { migraphx::array arr = {1, 2, 4, 3, 5}; - auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(is_sorted_until_empty) { empty_range arr = {}; - auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_until_single) { migraphx::array arr = {42}; - auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_until_descending) { migraphx::array arr = {4, 3, 2, 1}; - auto result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::greater{}); + auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::greater{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_true) @@ -186,7 +188,7 @@ TEST_CASE(is_sorted_true) TEST_CASE(is_sorted_false) { migraphx::array arr = {1, 3, 2, 4}; - EXPECT(!migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); + EXPECT( not migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); } TEST_CASE(is_sorted_empty) { @@ -224,49 +226,49 @@ TEST_CASE(for_each_empty) TEST_CASE(find_if_found) { migraphx::array arr = {1, 3, 5, 7, 9}; - auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); + auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); EXPECT(result == arr.begin() + 3); } TEST_CASE(find_if_not_found) { migraphx::array arr = {1, 3, 5, 7}; - auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 10; }); + auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 10; }); EXPECT(result == arr.end()); } TEST_CASE(find_if_first_element) { migraphx::array arr = {10, 3, 5, 7}; - auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); + auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); EXPECT(result == arr.begin()); } TEST_CASE(find_if_empty) { empty_range arr = {}; - auto result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); + auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); EXPECT(result == arr.end()); } TEST_CASE(find_basic) { migraphx::array arr = {10, 20, 30, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 30); + auto *result = migraphx::find(arr.begin(), arr.end(), 30); EXPECT(result == arr.begin() + 2); } TEST_CASE(find_not_found) { migraphx::array arr = {10, 20, 30, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 50); + auto *result = migraphx::find(arr.begin(), arr.end(), 50); EXPECT(result == arr.end()); } TEST_CASE(find_first_element) { migraphx::array arr = {10, 20, 30, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 10); + auto *result = migraphx::find(arr.begin(), arr.end(), 10); EXPECT(result == arr.begin()); } TEST_CASE(find_duplicates) { migraphx::array arr = {10, 20, 30, 20, 40}; - auto result = migraphx::find(arr.begin(), arr.end(), 20); + auto *result = migraphx::find(arr.begin(), arr.end(), 20); EXPECT(result == arr.begin() + 1); } @@ -278,12 +280,12 @@ TEST_CASE(any_of_true) TEST_CASE(any_of_false) { migraphx::array arr = {1, 3, 5, 7}; - EXPECT(!migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); + EXPECT( not migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); } TEST_CASE(any_of_empty) { empty_range arr = {}; - EXPECT(!migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); + EXPECT( not migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); } TEST_CASE(any_of_first_element) { @@ -298,7 +300,7 @@ TEST_CASE(none_of_true) TEST_CASE(none_of_false) { migraphx::array arr = {1, 3, 5, 7}; - EXPECT(!migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); + EXPECT( not migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); } TEST_CASE(none_of_empty) { @@ -313,7 +315,7 @@ TEST_CASE(all_of_true) TEST_CASE(all_of_false) { migraphx::array arr = {2, 4, 5, 8}; - EXPECT(!migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); + EXPECT( not migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } TEST_CASE(all_of_empty) { @@ -328,49 +330,49 @@ TEST_CASE(all_of_single_true) TEST_CASE(all_of_single_false) { migraphx::array arr = {5}; - EXPECT(!migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); + EXPECT( not migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } TEST_CASE(search_found) { migraphx::array haystack = {1, 2, 3, 4, 3, 4}; migraphx::array needle = {3, 4}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } TEST_CASE(search_not_found) { migraphx::array haystack = {1, 2, 3, 4, 5}; migraphx::array needle = {6, 7}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_empty_needle) { migraphx::array haystack = {1, 2, 3}; empty_range needle = {}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_empty_haystack) { empty_range haystack = {}; migraphx::array needle = {1}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_exact_match) { migraphx::array haystack = {1, 2, 3}; migraphx::array needle = {1, 2, 3}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_partial_match) { migraphx::array haystack = {1, 2, 1, 2, 3}; migraphx::array needle = {1, 2, 3}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } // Additional search tests (extensive) @@ -378,91 +380,91 @@ TEST_CASE(search_overlapping_pattern) { migraphx::array haystack = {1, 2, 1, 2, 1, 2, 3, 4}; migraphx::array needle = {1, 2, 3}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } TEST_CASE(search_pattern_at_end) { migraphx::array haystack = {1, 2, 3, 4, 5, 6}; migraphx::array needle = {5, 6}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } TEST_CASE(search_pattern_at_beginning) { migraphx::array haystack = {1, 2, 3, 4, 5, 6}; migraphx::array needle = {1, 2}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_single_element_pattern) { migraphx::array haystack = {1, 3, 5, 7, 9}; migraphx::array needle = {5}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } TEST_CASE(search_single_element_pattern_not_found) { migraphx::array haystack = {1, 3, 5, 7, 9}; migraphx::array needle = {4}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_repeated_elements) { migraphx::array haystack = {2, 2, 2, 2, 1, 2, 2, 3}; migraphx::array needle = {2, 2, 3}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 5); } TEST_CASE(search_partial_match_backtrack) { migraphx::array haystack = {1, 2, 3, 1, 2, 4, 1, 2, 3, 4}; migraphx::array needle = {1, 2, 3, 4}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 6); } TEST_CASE(search_multiple_false_starts) { migraphx::array haystack = {1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 5, 6}; migraphx::array needle = {1, 2, 3, 4}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 6); } TEST_CASE(search_needle_longer_than_haystack) { migraphx::array haystack = {1, 2, 3}; migraphx::array needle = {1, 2, 3, 4, 5}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_identical_arrays) { migraphx::array haystack = {5, 10, 15, 20}; migraphx::array needle = {5, 10, 15, 20}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_all_same_elements) { migraphx::array haystack = {3, 3, 3, 3, 3, 3}; migraphx::array needle = {3, 3, 3}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_pattern_appears_multiple_times) { migraphx::array haystack = {1, 2, 3, 1, 2, 3, 1, 2, 3}; migraphx::array needle = {2, 3}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 1); } TEST_CASE(search_partial_range) { migraphx::array haystack = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; migraphx::array needle = {4, 5}; - auto result = + auto *result = migraphx::search(haystack.begin() + 2, haystack.begin() + 7, needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } @@ -470,14 +472,14 @@ TEST_CASE(search_stress_long_pattern) { migraphx::array haystack = {1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 1}; migraphx::array needle = {2, 3, 4, 5, 6, 7}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 5); } TEST_CASE(search_stress_worst_case_complexity) { migraphx::array haystack = {1, 1, 1, 1, 1, 1, 1, 2}; migraphx::array needle = {1, 1, 1, 1, 1, 1, 2}; - auto result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 1); } @@ -526,7 +528,7 @@ TEST_CASE(equal_false) { migraphx::array a = {1, 2, 3, 4}; migraphx::array b = {1, 2, 3, 5}; - EXPECT(!migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); + EXPECT( not migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); } TEST_CASE(equal_empty) { @@ -570,38 +572,38 @@ TEST_CASE(iota_negative) TEST_CASE(min_element_basic) { migraphx::array arr = {3, 1, 4, 1, 5}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin() + 1); } TEST_CASE(min_element_empty) { empty_range arr = {}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(min_element_single) { migraphx::array arr = {42}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(min_element_all_equal) { migraphx::array arr = {5, 5, 5, 5}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(min_element_custom_compare) { migraphx::array arr = {1, 2, 3, 4}; - auto result = migraphx::min_element(arr.begin(), arr.end(), migraphx::greater{}); + auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::greater{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(rotate_left_by_two) { migraphx::array arr = {1, 2, 3, 4, 5, 6}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); migraphx::array expected = {3, 4, 5, 6, 1, 2}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); @@ -609,7 +611,7 @@ TEST_CASE(rotate_left_by_two) TEST_CASE(rotate_right_by_one) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); migraphx::array expected = {5, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); @@ -617,7 +619,7 @@ TEST_CASE(rotate_right_by_one) TEST_CASE(rotate_half_array) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); migraphx::array expected = {5, 6, 7, 8, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); @@ -625,7 +627,7 @@ TEST_CASE(rotate_half_array) TEST_CASE(rotate_almost_full) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); migraphx::array expected = {5, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); @@ -633,7 +635,7 @@ TEST_CASE(rotate_almost_full) TEST_CASE(rotate_two_elements) { migraphx::array arr = {1, 2}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); migraphx::array expected = {2, 1}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); @@ -641,7 +643,7 @@ TEST_CASE(rotate_two_elements) TEST_CASE(rotate_partial_range) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; - auto result = migraphx::rotate(arr.begin() + 1, arr.begin() + 3, arr.begin() + 5); + auto *result = migraphx::rotate(arr.begin() + 1, arr.begin() + 3, arr.begin() + 5); migraphx::array expected = {1, 4, 5, 2, 3, 6, 7}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 3); @@ -649,7 +651,7 @@ TEST_CASE(rotate_partial_range) TEST_CASE(rotate_with_duplicates) { migraphx::array arr = {1, 1, 2, 2, 3, 3}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); migraphx::array expected = {2, 2, 3, 3, 1, 1}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); @@ -657,7 +659,7 @@ TEST_CASE(rotate_with_duplicates) TEST_CASE(rotate_stress_test_large_shift) { migraphx::array arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); migraphx::array expected = {7, 8, 9, 0, 1, 2, 3, 4, 5, 6}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 3); @@ -666,7 +668,7 @@ TEST_CASE(rotate_edge_case_middle_equals_first) { migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; - auto result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); EXPECT(arr == original); EXPECT(result == arr.end()); } @@ -674,7 +676,7 @@ TEST_CASE(rotate_edge_case_middle_equals_last) { migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; - auto result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); + auto *result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); EXPECT(arr == original); EXPECT(result == arr.begin()); } @@ -682,109 +684,109 @@ TEST_CASE(rotate_edge_case_middle_equals_last) TEST_CASE(upper_bound_basic) { migraphx::array arr = {1, 2, 2, 3, 4}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(upper_bound_not_found) { migraphx::array arr = {1, 2, 3, 4}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_first_element) { migraphx::array arr = {1, 2, 3, 4}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(upper_bound_empty) { empty_range arr = {}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_all_equal) { migraphx::array arr = {2, 2, 2}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_multiple_duplicates) { migraphx::array arr = {1, 2, 2, 2, 2, 3, 4, 5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.begin() + 5); } TEST_CASE(upper_bound_all_smaller) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(upper_bound_all_larger) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 10, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 10, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_single_element_match) { migraphx::array arr = {5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_single_element_smaller) { migraphx::array arr = {5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(upper_bound_single_element_larger) { migraphx::array arr = {5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_beginning_duplicates) { migraphx::array arr = {1, 1, 1, 4, 5, 6}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 1, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 1, migraphx::less{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(upper_bound_end_duplicates) { migraphx::array arr = {1, 2, 3, 5, 5, 5}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_middle_value) { migraphx::array arr = {1, 3, 5, 7, 9, 11, 13}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); EXPECT(result == arr.begin() + 4); } TEST_CASE(upper_bound_partial_range) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; - auto result = migraphx::upper_bound(arr.begin() + 2, arr.begin() + 6, 4, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin() + 2, arr.begin() + 6, 4, migraphx::less{}); EXPECT(result == arr.begin() + 4); } TEST_CASE(upper_bound_reverse_comparator) { migraphx::array arr = {5, 4, 3, 2, 1}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::greater{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::greater{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(upper_bound_large_array_power_of_two) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 8, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 8, migraphx::less{}); EXPECT(result == arr.begin() + 8); } TEST_CASE(upper_bound_stress_binary_search) { migraphx::array arr = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; - auto result = migraphx::upper_bound(arr.begin(), arr.end(), 16, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 16, migraphx::less{}); EXPECT(result == arr.begin() + 8); } TEST_CASE(upper_bound_stress_test_boundary) @@ -792,7 +794,7 @@ TEST_CASE(upper_bound_stress_test_boundary) migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; for(int i = 1; i <= 7; ++i) { - auto result = migraphx::upper_bound(arr.begin(), arr.end(), i, migraphx::less{}); + auto *result = migraphx::upper_bound(arr.begin(), arr.end(), i, migraphx::less{}); EXPECT(result == arr.begin() + i); } } @@ -912,7 +914,7 @@ TEST_CASE(merge_both_empty) empty_range arr1 = {}; empty_range arr2 = {}; empty_range result = {}; - auto end_it = migraphx::merge( + auto *end_it = migraphx::merge( arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); EXPECT(end_it == result.end()); } @@ -1072,31 +1074,13 @@ TEST_CASE(merge_stability_test) EXPECT(result == expected); } -TEST_CASE(common_mistakes_off_by_one) -{ - migraphx::array arr = {5}; - auto result = migraphx::find(arr.begin(), arr.end(), 5); - EXPECT(result == arr.begin()); - result = migraphx::find(arr.begin(), arr.end(), 10); - EXPECT(result == arr.end()); -} -TEST_CASE(common_mistakes_empty_ranges) -{ - empty_range empty = {}; - EXPECT(migraphx::is_sorted(empty.begin(), empty.end(), migraphx::less{})); - EXPECT(migraphx::all_of(empty.begin(), empty.end(), [](int) { return false; })); - EXPECT(!migraphx::any_of(empty.begin(), empty.end(), [](int) { return true; })); - EXPECT(migraphx::none_of(empty.begin(), empty.end(), [](int) { return true; })); - auto min_it = migraphx::min_element(empty.begin(), empty.end(), migraphx::less{}); - EXPECT(min_it == empty.end()); -} -TEST_CASE(common_mistakes_self_assignment) +TEST_CASE(swap_self_assignment) { int x = 42; migraphx::swap(x, x); EXPECT(x == 42); } -TEST_CASE(common_mistakes_predicate_consistency) +TEST_CASE(find_if_predicate_consistency) { migraphx::array arr = {1, 2, 3, 4}; int call_count = 0; @@ -1104,7 +1088,7 @@ TEST_CASE(common_mistakes_predicate_consistency) call_count++; return x > 2; }; - auto result = migraphx::find_if(arr.begin(), arr.end(), predicate); + auto *result = migraphx::find_if(arr.begin(), arr.end(), predicate); EXPECT(result == arr.begin() + 2); EXPECT(call_count == 3); } From 99250c30a442b1603eedfc930edec5dee389208d Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 4 Aug 2025 11:43:51 -0500 Subject: [PATCH 06/20] Format --- .../include/migraphx/kernels/algorithm.hpp | 2 +- test/gpu/kernels/algorithm.cpp | 170 +++++++++--------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp index b6cc2007061..d1fa5d0e7e1 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/algorithm.hpp @@ -281,7 +281,7 @@ constexpr Iterator upper_bound(Iterator first, Iterator last, const T& value, Co while(count > 0) { - auto *it = first; + auto* it = first; auto step = count / 2; it += step; diff --git a/test/gpu/kernels/algorithm.cpp b/test/gpu/kernels/algorithm.cpp index 13da164da61..fd570e15e21 100644 --- a/test/gpu/kernels/algorithm.cpp +++ b/test/gpu/kernels/algorithm.cpp @@ -57,15 +57,15 @@ TEST_CASE(less_functor) { migraphx::less comp; EXPECT(comp(1, 2)); - EXPECT( not comp(2, 1)); - EXPECT( not comp(5, 5)); + EXPECT(not comp(2, 1)); + EXPECT(not comp(5, 5)); } TEST_CASE(greater_functor) { migraphx::greater comp; EXPECT(comp(2, 1)); - EXPECT( not comp(1, 2)); - EXPECT( not comp(5, 5)); + EXPECT(not comp(1, 2)); + EXPECT(not comp(5, 5)); } TEST_CASE(accumulate_basic) @@ -106,7 +106,7 @@ TEST_CASE(copy_empty_range) { migraphx::array src = {1, 2, 3}; migraphx::array dst = {0, 0, 0}; - auto *result = migraphx::copy(src.begin(), src.begin(), dst.begin()); + auto* result = migraphx::copy(src.begin(), src.begin(), dst.begin()); EXPECT(result == dst.begin()); migraphx::array expected = {0, 0, 0}; EXPECT(dst == expected); @@ -123,7 +123,7 @@ TEST_CASE(copy_if_basic) { migraphx::array src = {1, 2, 3, 4, 5, 6}; migraphx::array dst = {0, 0, 0, 0, 0, 0}; - auto *end_it = + auto* end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(dst[0] == 2); EXPECT(dst[1] == 4); @@ -134,7 +134,7 @@ TEST_CASE(copy_if_none_match) { migraphx::array src = {1, 3, 5}; migraphx::array dst = {0, 0, 0}; - auto *end_it = + auto* end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(end_it == dst.begin()); migraphx::array expected = {0, 0, 0}; @@ -144,7 +144,7 @@ TEST_CASE(copy_if_all_match) { migraphx::array src = {2, 4, 6}; migraphx::array dst = {0, 0, 0}; - auto *end_it = + auto* end_it = migraphx::copy_if(src.begin(), src.end(), dst.begin(), [](int x) { return x % 2 == 0; }); EXPECT(end_it == dst.end()); EXPECT(src == dst); @@ -153,31 +153,31 @@ TEST_CASE(copy_if_all_match) TEST_CASE(is_sorted_until_sorted) { migraphx::array arr = {1, 2, 3, 4}; - auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_until_unsorted) { migraphx::array arr = {1, 2, 4, 3, 5}; - auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(is_sorted_until_empty) { empty_range arr = {}; - auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_until_single) { migraphx::array arr = {42}; - auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_until_descending) { migraphx::array arr = {4, 3, 2, 1}; - auto *result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::greater{}); + auto* result = migraphx::is_sorted_until(arr.begin(), arr.end(), migraphx::greater{}); EXPECT(result == arr.end()); } TEST_CASE(is_sorted_true) @@ -188,7 +188,7 @@ TEST_CASE(is_sorted_true) TEST_CASE(is_sorted_false) { migraphx::array arr = {1, 3, 2, 4}; - EXPECT( not migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); + EXPECT(not migraphx::is_sorted(arr.begin(), arr.end(), migraphx::less{})); } TEST_CASE(is_sorted_empty) { @@ -226,49 +226,49 @@ TEST_CASE(for_each_empty) TEST_CASE(find_if_found) { migraphx::array arr = {1, 3, 5, 7, 9}; - auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); + auto* result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); EXPECT(result == arr.begin() + 3); } TEST_CASE(find_if_not_found) { migraphx::array arr = {1, 3, 5, 7}; - auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 10; }); + auto* result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 10; }); EXPECT(result == arr.end()); } TEST_CASE(find_if_first_element) { migraphx::array arr = {10, 3, 5, 7}; - auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); + auto* result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 5; }); EXPECT(result == arr.begin()); } TEST_CASE(find_if_empty) { empty_range arr = {}; - auto *result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); + auto* result = migraphx::find_if(arr.begin(), arr.end(), [](int x) { return x > 0; }); EXPECT(result == arr.end()); } TEST_CASE(find_basic) { migraphx::array arr = {10, 20, 30, 40}; - auto *result = migraphx::find(arr.begin(), arr.end(), 30); + auto* result = migraphx::find(arr.begin(), arr.end(), 30); EXPECT(result == arr.begin() + 2); } TEST_CASE(find_not_found) { migraphx::array arr = {10, 20, 30, 40}; - auto *result = migraphx::find(arr.begin(), arr.end(), 50); + auto* result = migraphx::find(arr.begin(), arr.end(), 50); EXPECT(result == arr.end()); } TEST_CASE(find_first_element) { migraphx::array arr = {10, 20, 30, 40}; - auto *result = migraphx::find(arr.begin(), arr.end(), 10); + auto* result = migraphx::find(arr.begin(), arr.end(), 10); EXPECT(result == arr.begin()); } TEST_CASE(find_duplicates) { migraphx::array arr = {10, 20, 30, 20, 40}; - auto *result = migraphx::find(arr.begin(), arr.end(), 20); + auto* result = migraphx::find(arr.begin(), arr.end(), 20); EXPECT(result == arr.begin() + 1); } @@ -280,12 +280,12 @@ TEST_CASE(any_of_true) TEST_CASE(any_of_false) { migraphx::array arr = {1, 3, 5, 7}; - EXPECT( not migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); + EXPECT(not migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 10; })); } TEST_CASE(any_of_empty) { empty_range arr = {}; - EXPECT( not migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); + EXPECT(not migraphx::any_of(arr.begin(), arr.end(), [](int x) { return x > 0; })); } TEST_CASE(any_of_first_element) { @@ -300,7 +300,7 @@ TEST_CASE(none_of_true) TEST_CASE(none_of_false) { migraphx::array arr = {1, 3, 5, 7}; - EXPECT( not migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); + EXPECT(not migraphx::none_of(arr.begin(), arr.end(), [](int x) { return x > 5; })); } TEST_CASE(none_of_empty) { @@ -315,7 +315,7 @@ TEST_CASE(all_of_true) TEST_CASE(all_of_false) { migraphx::array arr = {2, 4, 5, 8}; - EXPECT( not migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); + EXPECT(not migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } TEST_CASE(all_of_empty) { @@ -330,49 +330,49 @@ TEST_CASE(all_of_single_true) TEST_CASE(all_of_single_false) { migraphx::array arr = {5}; - EXPECT( not migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); + EXPECT(not migraphx::all_of(arr.begin(), arr.end(), [](int x) { return x % 2 == 0; })); } TEST_CASE(search_found) { migraphx::array haystack = {1, 2, 3, 4, 3, 4}; migraphx::array needle = {3, 4}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } TEST_CASE(search_not_found) { migraphx::array haystack = {1, 2, 3, 4, 5}; migraphx::array needle = {6, 7}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_empty_needle) { migraphx::array haystack = {1, 2, 3}; empty_range needle = {}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_empty_haystack) { empty_range haystack = {}; migraphx::array needle = {1}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_exact_match) { migraphx::array haystack = {1, 2, 3}; migraphx::array needle = {1, 2, 3}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_partial_match) { migraphx::array haystack = {1, 2, 1, 2, 3}; migraphx::array needle = {1, 2, 3}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } // Additional search tests (extensive) @@ -380,91 +380,91 @@ TEST_CASE(search_overlapping_pattern) { migraphx::array haystack = {1, 2, 1, 2, 1, 2, 3, 4}; migraphx::array needle = {1, 2, 3}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } TEST_CASE(search_pattern_at_end) { migraphx::array haystack = {1, 2, 3, 4, 5, 6}; migraphx::array needle = {5, 6}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } TEST_CASE(search_pattern_at_beginning) { migraphx::array haystack = {1, 2, 3, 4, 5, 6}; migraphx::array needle = {1, 2}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_single_element_pattern) { migraphx::array haystack = {1, 3, 5, 7, 9}; migraphx::array needle = {5}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 2); } TEST_CASE(search_single_element_pattern_not_found) { migraphx::array haystack = {1, 3, 5, 7, 9}; migraphx::array needle = {4}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_repeated_elements) { migraphx::array haystack = {2, 2, 2, 2, 1, 2, 2, 3}; migraphx::array needle = {2, 2, 3}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 5); } TEST_CASE(search_partial_match_backtrack) { migraphx::array haystack = {1, 2, 3, 1, 2, 4, 1, 2, 3, 4}; migraphx::array needle = {1, 2, 3, 4}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 6); } TEST_CASE(search_multiple_false_starts) { migraphx::array haystack = {1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 5, 6}; migraphx::array needle = {1, 2, 3, 4}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 6); } TEST_CASE(search_needle_longer_than_haystack) { migraphx::array haystack = {1, 2, 3}; migraphx::array needle = {1, 2, 3, 4, 5}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.end()); } TEST_CASE(search_identical_arrays) { migraphx::array haystack = {5, 10, 15, 20}; migraphx::array needle = {5, 10, 15, 20}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_all_same_elements) { migraphx::array haystack = {3, 3, 3, 3, 3, 3}; migraphx::array needle = {3, 3, 3}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin()); } TEST_CASE(search_pattern_appears_multiple_times) { migraphx::array haystack = {1, 2, 3, 1, 2, 3, 1, 2, 3}; migraphx::array needle = {2, 3}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 1); } TEST_CASE(search_partial_range) { migraphx::array haystack = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; migraphx::array needle = {4, 5}; - auto *result = + auto* result = migraphx::search(haystack.begin() + 2, haystack.begin() + 7, needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 4); } @@ -472,14 +472,14 @@ TEST_CASE(search_stress_long_pattern) { migraphx::array haystack = {1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 1}; migraphx::array needle = {2, 3, 4, 5, 6, 7}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 5); } TEST_CASE(search_stress_worst_case_complexity) { migraphx::array haystack = {1, 1, 1, 1, 1, 1, 1, 2}; migraphx::array needle = {1, 1, 1, 1, 1, 1, 2}; - auto *result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); + auto* result = migraphx::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); EXPECT(result == haystack.begin() + 1); } @@ -528,7 +528,7 @@ TEST_CASE(equal_false) { migraphx::array a = {1, 2, 3, 4}; migraphx::array b = {1, 2, 3, 5}; - EXPECT( not migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); + EXPECT(not migraphx::equal(a.begin(), a.end(), b.begin(), [](int x, int y) { return x == y; })); } TEST_CASE(equal_empty) { @@ -572,38 +572,38 @@ TEST_CASE(iota_negative) TEST_CASE(min_element_basic) { migraphx::array arr = {3, 1, 4, 1, 5}; - auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin() + 1); } TEST_CASE(min_element_empty) { empty_range arr = {}; - auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(min_element_single) { migraphx::array arr = {42}; - auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(min_element_all_equal) { migraphx::array arr = {5, 5, 5, 5}; - auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); + auto* result = migraphx::min_element(arr.begin(), arr.end(), migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(min_element_custom_compare) { migraphx::array arr = {1, 2, 3, 4}; - auto *result = migraphx::min_element(arr.begin(), arr.end(), migraphx::greater{}); + auto* result = migraphx::min_element(arr.begin(), arr.end(), migraphx::greater{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(rotate_left_by_two) { migraphx::array arr = {1, 2, 3, 4, 5, 6}; - auto *result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); migraphx::array expected = {3, 4, 5, 6, 1, 2}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); @@ -611,7 +611,7 @@ TEST_CASE(rotate_left_by_two) TEST_CASE(rotate_right_by_one) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto *result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.end() - 1, arr.end()); migraphx::array expected = {5, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); @@ -619,7 +619,7 @@ TEST_CASE(rotate_right_by_one) TEST_CASE(rotate_half_array) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; - auto *result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); migraphx::array expected = {5, 6, 7, 8, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); @@ -627,7 +627,7 @@ TEST_CASE(rotate_half_array) TEST_CASE(rotate_almost_full) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto *result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin() + 4, arr.end()); migraphx::array expected = {5, 1, 2, 3, 4}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); @@ -635,7 +635,7 @@ TEST_CASE(rotate_almost_full) TEST_CASE(rotate_two_elements) { migraphx::array arr = {1, 2}; - auto *result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin() + 1, arr.end()); migraphx::array expected = {2, 1}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 1); @@ -643,7 +643,7 @@ TEST_CASE(rotate_two_elements) TEST_CASE(rotate_partial_range) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; - auto *result = migraphx::rotate(arr.begin() + 1, arr.begin() + 3, arr.begin() + 5); + auto* result = migraphx::rotate(arr.begin() + 1, arr.begin() + 3, arr.begin() + 5); migraphx::array expected = {1, 4, 5, 2, 3, 6, 7}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 3); @@ -651,7 +651,7 @@ TEST_CASE(rotate_partial_range) TEST_CASE(rotate_with_duplicates) { migraphx::array arr = {1, 1, 2, 2, 3, 3}; - auto *result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin() + 2, arr.end()); migraphx::array expected = {2, 2, 3, 3, 1, 1}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 4); @@ -659,7 +659,7 @@ TEST_CASE(rotate_with_duplicates) TEST_CASE(rotate_stress_test_large_shift) { migraphx::array arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto *result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin() + 7, arr.end()); migraphx::array expected = {7, 8, 9, 0, 1, 2, 3, 4, 5, 6}; EXPECT(arr == expected); EXPECT(result == arr.begin() + 3); @@ -668,7 +668,7 @@ TEST_CASE(rotate_edge_case_middle_equals_first) { migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; - auto *result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.begin(), arr.end()); EXPECT(arr == original); EXPECT(result == arr.end()); } @@ -676,7 +676,7 @@ TEST_CASE(rotate_edge_case_middle_equals_last) { migraphx::array arr = {1, 2, 3, 4}; migraphx::array original = arr; - auto *result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); + auto* result = migraphx::rotate(arr.begin(), arr.end(), arr.end()); EXPECT(arr == original); EXPECT(result == arr.begin()); } @@ -684,109 +684,109 @@ TEST_CASE(rotate_edge_case_middle_equals_last) TEST_CASE(upper_bound_basic) { migraphx::array arr = {1, 2, 2, 3, 4}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(upper_bound_not_found) { migraphx::array arr = {1, 2, 3, 4}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_first_element) { migraphx::array arr = {1, 2, 3, 4}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(upper_bound_empty) { empty_range arr = {}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_all_equal) { migraphx::array arr = {2, 2, 2}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_multiple_duplicates) { migraphx::array arr = {1, 2, 2, 2, 2, 3, 4, 5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 2, migraphx::less{}); EXPECT(result == arr.begin() + 5); } TEST_CASE(upper_bound_all_smaller) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 0, migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(upper_bound_all_larger) { migraphx::array arr = {1, 2, 3, 4, 5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 10, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 10, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_single_element_match) { migraphx::array arr = {5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_single_element_smaller) { migraphx::array arr = {5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::less{}); EXPECT(result == arr.begin()); } TEST_CASE(upper_bound_single_element_larger) { migraphx::array arr = {5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_beginning_duplicates) { migraphx::array arr = {1, 1, 1, 4, 5, 6}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 1, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 1, migraphx::less{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(upper_bound_end_duplicates) { migraphx::array arr = {1, 2, 3, 5, 5, 5}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 5, migraphx::less{}); EXPECT(result == arr.end()); } TEST_CASE(upper_bound_middle_value) { migraphx::array arr = {1, 3, 5, 7, 9, 11, 13}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 7, migraphx::less{}); EXPECT(result == arr.begin() + 4); } TEST_CASE(upper_bound_partial_range) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8}; - auto *result = migraphx::upper_bound(arr.begin() + 2, arr.begin() + 6, 4, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin() + 2, arr.begin() + 6, 4, migraphx::less{}); EXPECT(result == arr.begin() + 4); } TEST_CASE(upper_bound_reverse_comparator) { migraphx::array arr = {5, 4, 3, 2, 1}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::greater{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 3, migraphx::greater{}); EXPECT(result == arr.begin() + 3); } TEST_CASE(upper_bound_large_array_power_of_two) { migraphx::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 8, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 8, migraphx::less{}); EXPECT(result == arr.begin() + 8); } TEST_CASE(upper_bound_stress_binary_search) { migraphx::array arr = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), 16, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), 16, migraphx::less{}); EXPECT(result == arr.begin() + 8); } TEST_CASE(upper_bound_stress_test_boundary) @@ -794,7 +794,7 @@ TEST_CASE(upper_bound_stress_test_boundary) migraphx::array arr = {1, 2, 3, 4, 5, 6, 7}; for(int i = 1; i <= 7; ++i) { - auto *result = migraphx::upper_bound(arr.begin(), arr.end(), i, migraphx::less{}); + auto* result = migraphx::upper_bound(arr.begin(), arr.end(), i, migraphx::less{}); EXPECT(result == arr.begin() + i); } } @@ -914,7 +914,7 @@ TEST_CASE(merge_both_empty) empty_range arr1 = {}; empty_range arr2 = {}; empty_range result = {}; - auto *end_it = migraphx::merge( + auto* end_it = migraphx::merge( arr1.begin(), arr1.end(), arr2.begin(), arr2.end(), result.begin(), migraphx::less{}); EXPECT(end_it == result.end()); } @@ -1088,7 +1088,7 @@ TEST_CASE(find_if_predicate_consistency) call_count++; return x > 2; }; - auto *result = migraphx::find_if(arr.begin(), arr.end(), predicate); + auto* result = migraphx::find_if(arr.begin(), arr.end(), predicate); EXPECT(result == arr.begin() + 2); EXPECT(call_count == 3); } From bfd58bea6aae8d6797269354f7b980630a61d905 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 4 Aug 2025 17:28:06 -0500 Subject: [PATCH 07/20] Exclude test.hpp header --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d5ff8f8589..a857c0bd91e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -291,6 +291,7 @@ rocm_enable_cppcheck( # Disable because of too many FPs arithOperationsOnVoidPointer definePrefix:*test/include/test.hpp + definePrefix:*src/targets/gpu/kernels/include/migraphx/kernels/test.hpp ctuOneDefinitionRuleViolation:*test/* useSmartPointer:*src/api/api.cpp useSmartPointer:*make_shared_array.hpp From 35fcec786d49997ec4a9cdf64b3e2a13b15859c3 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 25 Aug 2025 18:30:22 -0500 Subject: [PATCH 08/20] Report failures and stop on expect but not on check --- src/targets/gpu/hip.cpp | 2 +- src/targets/gpu/include/migraphx/gpu/hip.hpp | 9 +++ .../kernels/include/migraphx/kernels/test.hpp | 59 ++++++++++++++----- test/gpu/kernels/main.cpp | 9 ++- test/include/test.hpp | 7 ++- 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/targets/gpu/hip.cpp b/src/targets/gpu/hip.cpp index 09979cb1250..8cb6e5b4c2f 100644 --- a/src/targets/gpu/hip.cpp +++ b/src/targets/gpu/hip.cpp @@ -148,7 +148,7 @@ static std::vector read_from_gpu(const void* x, std::size_t sz) return result; } -static std::shared_ptr write_to_gpu(const void* x, std::size_t sz, bool host = false) +std::shared_ptr write_to_gpu(const void* x, std::size_t sz, bool host) { gpu_sync(); auto result = allocate_gpu(sz, host); diff --git a/src/targets/gpu/include/migraphx/gpu/hip.hpp b/src/targets/gpu/include/migraphx/gpu/hip.hpp index 459446f2bce..ded7eadaf79 100644 --- a/src/targets/gpu/include/migraphx/gpu/hip.hpp +++ b/src/targets/gpu/include/migraphx/gpu/hip.hpp @@ -61,6 +61,15 @@ MIGRAPHX_GPU_EXPORT argument get_preallocation(context& ctx, const std::string& MIGRAPHX_GPU_EXPORT void gpu_fill(context& ctx, const argument& dst, int value = 0); +MIGRAPHX_GPU_EXPORT std::shared_ptr write_to_gpu(const void* x, std::size_t sz, bool host = false); + +template +std::shared_ptr write_to_gpu(const T& x, bool host = false) +{ + return std::static_pointer_cast(write_to_gpu(&x, sizeof(T), host)); +} + + struct hip_allocate { shape s; diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index 0680d83eea0..75ac354e74e 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -232,20 +232,50 @@ struct capture } }; -MIGRAPHX_HIP_NORETURN __device__ inline void fail() { abort(); } +struct test_manager +{ + int32_t* failures = nullptr; + + __device__ void report_failure() + { + (*failures)++; + } + + template + __device__ void + failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) + { + // TODO: Check failures across multiple lanes + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + if(not bool(x.value())) + { + if(threadIdx.x == 0) + { + println_once(func); + println_once(file, ":", line, ":"); + println_once(" FAILED: ", msg, " [ ", x, " ]"); + report_failure(); + } + f(); + } + } +}; -template -__device__ void -failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) +[[noreturn]] __device__ inline void fail() { - // TODO: Check failures across multiple lanes - // NOLINTNEXTLINE(readability-static-accessed-through-instance) - if(not bool(x.value()) and threadIdx.x == 0) + // There is no way to easily exit with no error. We can terminate the + // current wavefront without an error, but if there is more wavefronts + // than we need to fallback to a trap which throws an error in HSA + // runtime unfortunately. + auto nb = gridDim.x * gridDim.y * gridDim.z; + auto bs = blockDim.x * blockDim.y * blockDim.z; + if(nb == 1 and bs <= __builtin_amdgcn_wavefrontsize()) { - println_once(func); - println_once(file, ":", line, ":"); - println_once(" FAILED: ", msg, " [ ", x, " ]"); - f(); + __builtin_amdgcn_endpgm(); + } + else + { + __builtin_trap(); } } @@ -262,20 +292,21 @@ failed(const T& x, const char* msg, const char* func, const char* file, int line // NOLINTNEXTLINE #define CHECK(...) \ - migraphx::test::failed( \ + migraphx_private_test_manager.failed( \ TEST_CAPTURE(__VA_ARGS__), #__VA_ARGS__, TEST_PRETTY_FUNCTION, __FILE__, __LINE__, [] {}) // NOLINTNEXTLINE #define EXPECT(...) \ - migraphx::test::failed(TEST_CAPTURE(__VA_ARGS__), \ + migraphx_private_test_manager.failed(TEST_CAPTURE(__VA_ARGS__), \ #__VA_ARGS__, \ TEST_PRETTY_FUNCTION, \ __FILE__, \ __LINE__, \ &migraphx::test::fail) + // NOLINTNEXTLINE -#define TEST_CASE(...) __device__ void __VA_ARGS__() +#define TEST_CASE(...) __device__ void __VA_ARGS__([[maybe_unused]] migraphx::test::test_manager& migraphx_private_test_manager) } // namespace test } // namespace migraphx diff --git a/test/gpu/kernels/main.cpp b/test/gpu/kernels/main.cpp index 80b4556e450..491a59a9650 100644 --- a/test/gpu/kernels/main.cpp +++ b/test/gpu/kernels/main.cpp @@ -57,12 +57,13 @@ struct test_suite : std::enable_shared_from_this { std::ostringstream out; out << content << '\n'; - out << "extern \"C\" __global__ void " << options.kernel_name << "(int id) {\n"; + out << "extern \"C\" __global__ void " << options.kernel_name << "(int id, int32_t* failures) {\n"; + out << " migraphx::test::test_manager tm{failures};\n"; out << " switch(id) {\n"; for(const auto& [case_name, i] : test_cases) { auto fname = case_name.substr(name.size() + 1); - out << " case " << i << ": " << fname << "(); break;\n"; + out << " case " << i << ": " << fname << "(tm); break;\n"; } out << " default: abort();\n"; out << " }\n"; @@ -82,9 +83,11 @@ struct test_suite : std::enable_shared_from_this void run(const std::string& case_name) { + auto failures = migraphx::gpu::write_to_gpu(int32_t{0}, true); compile(); - k.launch(nullptr, options.global, options.local)(test_cases.at(case_name)); + k.launch(nullptr, options.global, options.local)(test_cases.at(case_name), failures.get()); CHECK(hipDeviceSynchronize() == hipSuccess); + test::report_failure(*failures); } }; diff --git a/test/include/test.hpp b/test/include/test.hpp index d2d9632ba45..8c9df74b9de 100644 --- a/test/include/test.hpp +++ b/test/include/test.hpp @@ -394,12 +394,17 @@ inline std::atomic& failures() return f; } +void report_failure(int n=1) +{ + failures() += n; +} + template void failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) { if(not bool(x.value())) { - failures()++; + report_failure(); std::cout << func << std::endl; std::cout << file << ":" << line << ":" << std::endl; std::cout << color::bold << color::fg_red << " FAILED: " << color::reset << msg << " " From e824891dd7f036ab2a56e2ffb1e46cef4bb78c47 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 25 Aug 2025 18:30:27 -0500 Subject: [PATCH 09/20] Format --- src/targets/gpu/include/migraphx/gpu/hip.hpp | 6 ++-- .../kernels/include/migraphx/kernels/test.hpp | 28 +++++++++---------- test/gpu/kernels/main.cpp | 3 +- test/include/test.hpp | 5 +--- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/targets/gpu/include/migraphx/gpu/hip.hpp b/src/targets/gpu/include/migraphx/gpu/hip.hpp index ded7eadaf79..055594252c2 100644 --- a/src/targets/gpu/include/migraphx/gpu/hip.hpp +++ b/src/targets/gpu/include/migraphx/gpu/hip.hpp @@ -61,15 +61,15 @@ MIGRAPHX_GPU_EXPORT argument get_preallocation(context& ctx, const std::string& MIGRAPHX_GPU_EXPORT void gpu_fill(context& ctx, const argument& dst, int value = 0); -MIGRAPHX_GPU_EXPORT std::shared_ptr write_to_gpu(const void* x, std::size_t sz, bool host = false); +MIGRAPHX_GPU_EXPORT std::shared_ptr +write_to_gpu(const void* x, std::size_t sz, bool host = false); -template +template std::shared_ptr write_to_gpu(const T& x, bool host = false) { return std::static_pointer_cast(write_to_gpu(&x, sizeof(T), host)); } - struct hip_allocate { shape s; diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index 75ac354e74e..57a8195d435 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -236,11 +236,8 @@ struct test_manager { int32_t* failures = nullptr; - __device__ void report_failure() - { - (*failures)++; - } - + __device__ void report_failure() { (*failures)++; } + template __device__ void failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) @@ -261,7 +258,7 @@ struct test_manager } }; -[[noreturn]] __device__ inline void fail() +[[noreturn]] __device__ inline void fail() { // There is no way to easily exit with no error. We can terminate the // current wavefront without an error, but if there is more wavefronts @@ -291,22 +288,23 @@ struct test_manager #endif // NOLINTNEXTLINE -#define CHECK(...) \ +#define CHECK(...) \ migraphx_private_test_manager.failed( \ TEST_CAPTURE(__VA_ARGS__), #__VA_ARGS__, TEST_PRETTY_FUNCTION, __FILE__, __LINE__, [] {}) // NOLINTNEXTLINE -#define EXPECT(...) \ +#define EXPECT(...) \ migraphx_private_test_manager.failed(TEST_CAPTURE(__VA_ARGS__), \ - #__VA_ARGS__, \ - TEST_PRETTY_FUNCTION, \ - __FILE__, \ - __LINE__, \ - &migraphx::test::fail) - + #__VA_ARGS__, \ + TEST_PRETTY_FUNCTION, \ + __FILE__, \ + __LINE__, \ + &migraphx::test::fail) // NOLINTNEXTLINE -#define TEST_CASE(...) __device__ void __VA_ARGS__([[maybe_unused]] migraphx::test::test_manager& migraphx_private_test_manager) +#define TEST_CASE(...) \ + __device__ void __VA_ARGS__( \ + [[maybe_unused]] migraphx::test::test_manager& migraphx_private_test_manager) } // namespace test } // namespace migraphx diff --git a/test/gpu/kernels/main.cpp b/test/gpu/kernels/main.cpp index 491a59a9650..5b7d5ecb896 100644 --- a/test/gpu/kernels/main.cpp +++ b/test/gpu/kernels/main.cpp @@ -57,7 +57,8 @@ struct test_suite : std::enable_shared_from_this { std::ostringstream out; out << content << '\n'; - out << "extern \"C\" __global__ void " << options.kernel_name << "(int id, int32_t* failures) {\n"; + out << "extern \"C\" __global__ void " << options.kernel_name + << "(int id, int32_t* failures) {\n"; out << " migraphx::test::test_manager tm{failures};\n"; out << " switch(id) {\n"; for(const auto& [case_name, i] : test_cases) diff --git a/test/include/test.hpp b/test/include/test.hpp index 8c9df74b9de..ff0f38131d5 100644 --- a/test/include/test.hpp +++ b/test/include/test.hpp @@ -394,10 +394,7 @@ inline std::atomic& failures() return f; } -void report_failure(int n=1) -{ - failures() += n; -} +void report_failure(int n = 1) { failures() += n; } template void failed(const T& x, const char* msg, const char* func, const char* file, int line, F f) From 0fd319c0a5965cc7dbb87d199370adbb458df88f Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 29 Aug 2025 17:02:56 +0000 Subject: [PATCH 10/20] Add parallel compilation --- test/gpu/kernels/main.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/test/gpu/kernels/main.cpp b/test/gpu/kernels/main.cpp index 5b7d5ecb896..920bae1cd79 100644 --- a/test/gpu/kernels/main.cpp +++ b/test/gpu/kernels/main.cpp @@ -3,18 +3,16 @@ #include #include #include +#include #include #include #include +#include +#include #include #include -static migraphx::src_file make_src_file(const std::string& name, const std::string& content) -{ - return {name, content}; -} - std::vector parse_cases(const std::string_view& content) { std::regex case_re(R"(TEST_CASE\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\))"); @@ -95,14 +93,30 @@ struct test_suite : std::enable_shared_from_this int main(int argc, const char* argv[]) { test::driver d{}; + std::unordered_map> suites; for(auto [name, content] : ::kernel_tests()) { auto ts = std::make_shared(name, content); for(auto&& p : ts->test_cases) { auto case_name = p.first; + suites[case_name] = ts; test::add_test_case(case_name, [ts, case_name] { ts->run(case_name); }); } } + d.on_selected_cases = [&](const std::vector& cases) { + std::unordered_set> run_suites; + for(auto&& name : cases) + { + if(suites.count(name) == 0) + continue; + run_suites.insert(suites.at(name)); + } + migraphx::par_for(run_suites.size(), 1, [&](auto i) { + auto it = run_suites.begin(); + std::advance(it, i); + (*it)->compile(); + }); + }; d.run(argc, argv); } From be87e0561f401cf57be55405949cef71e5984ddd Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 29 Aug 2025 19:14:07 +0000 Subject: [PATCH 11/20] Add array tests --- test/gpu/kernels/array.cpp | 1345 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1345 insertions(+) create mode 100644 test/gpu/kernels/array.cpp diff --git a/test/gpu/kernels/array.cpp b/test/gpu/kernels/array.cpp new file mode 100644 index 00000000000..7a3673dbdcc --- /dev/null +++ b/test/gpu/kernels/array.cpp @@ -0,0 +1,1345 @@ +#include +#include +#include + +// Test default construction +TEST_CASE(array_default_construction) +{ + migraphx::array arr; + EXPECT(arr.size() == 5); + EXPECT(arr.data() != nullptr); + EXPECT(not arr.empty()); +} + +// Test variadic constructor +TEST_CASE(array_variadic_constructor) +{ + migraphx::array arr{1, 2, 3, 4, 5}; + EXPECT(arr[0] == 1); + EXPECT(arr[1] == 2); + EXPECT(arr[2] == 3); + EXPECT(arr[3] == 4); + EXPECT(arr[4] == 5); +} + +// Test single value constructor +TEST_CASE(array_single_value_constructor) +{ + migraphx::array arr(42); + EXPECT(arr[0] == 42); + EXPECT(arr[1] == 42); + EXPECT(arr[2] == 42); + EXPECT(arr[3] == 42); +} + +// Test single value constructor with size 1 +TEST_CASE(array_single_value_constructor_size_one) +{ + migraphx::array arr(7); + EXPECT(arr[0] == 7); +} + +// Test element access with operator[] +TEST_CASE(array_element_access) +{ + migraphx::array arr{10, 20, 30}; + EXPECT(arr[0] == 10); + EXPECT(arr[1] == 20); + EXPECT(arr[2] == 30); + + arr[1] = 25; + EXPECT(arr[1] == 25); +} + +// Test const element access +TEST_CASE(array_const_element_access) +{ + const migraphx::array arr{10, 20, 30}; + EXPECT(arr[0] == 10); + EXPECT(arr[1] == 20); + EXPECT(arr[2] == 30); +} + +// Test front() and back() +TEST_CASE(array_front_back) +{ + migraphx::array arr{1, 2, 3, 4}; + EXPECT(arr.front() == 1); + EXPECT(arr.back() == 4); + + arr.front() = 10; + arr.back() = 40; + EXPECT(arr[0] == 10); + EXPECT(arr[3] == 40); +} + +// Test const front() and back() +TEST_CASE(array_const_front_back) +{ + const migraphx::array arr{1, 2, 3, 4}; + EXPECT(arr.front() == 1); + EXPECT(arr.back() == 4); +} + +// Test data() method +TEST_CASE(array_data_method) +{ + migraphx::array arr{1, 2, 3}; + int* ptr = arr.data(); + EXPECT(ptr[0] == 1); + EXPECT(ptr[1] == 2); + EXPECT(ptr[2] == 3); + + ptr[0] = 10; + EXPECT(arr[0] == 10); +} + +// Test const data() method +TEST_CASE(array_const_data_method) +{ + const migraphx::array arr{1, 2, 3}; + const int* ptr = arr.data(); + EXPECT(ptr[0] == 1); + EXPECT(ptr[1] == 2); + EXPECT(ptr[2] == 3); +} + +// Test size() method +TEST_CASE(array_size_method) +{ + // migraphx::array arr0; // Commented out due to compiler limitations + migraphx::array arr1; + migraphx::array arr5; + migraphx::array arr100; + + // EXPECT(arr0.size() == 0); // Commented out + EXPECT(arr1.size() == 1); + EXPECT(arr5.size() == 5); + EXPECT(arr100.size() == 100); +} + +// Test empty() method +TEST_CASE(array_empty_method) +{ + // migraphx::array arr0; // Commented out due to compiler limitations + migraphx::array arr1; + + // EXPECT(arr0.empty()); // Commented out + EXPECT(not arr1.empty()); +} + +// Test begin() and end() iterators +TEST_CASE(array_iterators) +{ + migraphx::array arr{1, 2, 3, 4}; + + auto it = arr.begin(); + EXPECT(*it == 1); + ++it; + EXPECT(*it == 2); + ++it; + EXPECT(*it == 3); + ++it; + EXPECT(*it == 4); + ++it; + EXPECT(it == arr.end()); +} + +// Test const iterators +TEST_CASE(array_const_iterators) +{ + const migraphx::array arr{5, 10, 15}; + + auto it = arr.begin(); + EXPECT(*it == 5); + ++it; + EXPECT(*it == 10); + ++it; + EXPECT(*it == 15); + ++it; + EXPECT(it == arr.end()); +} + +// Test iterator distance +TEST_CASE(array_iterator_distance) +{ + migraphx::array arr{1, 2, 3, 4, 5}; + EXPECT(arr.end() - arr.begin() == 5); +} + +// Test dot product +TEST_CASE(array_dot_product) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{4, 5, 6}; + + int result = a.dot(b); + EXPECT(result == 32); // 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32 +} + +// Test dot product with zero +TEST_CASE(array_dot_product_zero) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{0, 0, 0}; + + int result = a.dot(b); + EXPECT(result == 0); +} + +// Test product() method +TEST_CASE(array_product) +{ + migraphx::array arr{2, 3, 4, 5}; + int result = arr.product(); + EXPECT(result == 120); // 2 * 3 * 4 * 5 = 120 +} + +// Test product with zero +TEST_CASE(array_product_with_zero) +{ + migraphx::array arr{2, 0, 5}; + int result = arr.product(); + EXPECT(result == 0); +} + +// Test product with single element +TEST_CASE(array_product_single_element) +{ + migraphx::array arr{7}; + int result = arr.product(); + EXPECT(result == 7); +} + +// Test single() method +TEST_CASE(array_single_method) +{ + migraphx::array arr{1, 2, 3}; + int result = arr.single(10); + EXPECT(result == 123); // 1*100 + 2*10 + 3*1 = 100 + 20 + 3 = 123 +} + +// Test single() with default width +TEST_CASE(array_single_default_width) +{ + migraphx::array arr{1, 2, 3}; + int result = arr.single(); + EXPECT(result == 10203); // 1*10000 + 2*100 + 3*1 = 10000 + 200 + 3 = 10203 +} + +// Test apply() method +TEST_CASE(array_apply_method) +{ + migraphx::array arr{1, 2, 3}; + auto result = arr.apply([](int x) { return x * 2; }); + + EXPECT(result[0] == 2); + EXPECT(result[1] == 4); + EXPECT(result[2] == 6); +} + +// Test apply() with type conversion +TEST_CASE(array_apply_type_conversion) +{ + migraphx::array arr{1, 2, 3}; + auto result = arr.apply([](int x) { return static_cast(x) * 1.5; }); + + EXPECT(migraphx::float_equal(result[0], 1.5)); + EXPECT(migraphx::float_equal(result[1], 3.0)); + EXPECT(migraphx::float_equal(result[2], 4.5)); +} + +// Test reduce() method +TEST_CASE(array_reduce_method) +{ + migraphx::array arr{1, 2, 3, 4}; + int sum = arr.reduce([](int a, int b) { return a + b; }, 0); + EXPECT(sum == 10); + + int product = arr.reduce([](int a, int b) { return a * b; }, 1); + EXPECT(product == 24); +} + +// Test reduce() with custom initial value +TEST_CASE(array_reduce_custom_init) +{ + migraphx::array arr{1, 2, 3}; + int result = arr.reduce([](int a, int b) { return a + b; }, 100); + EXPECT(result == 106); // 100 + 1 + 2 + 3 = 106 +} + +// Test += operator with array +TEST_CASE(array_add_assign_array) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{4, 5, 6}; + + a += b; + EXPECT(a[0] == 5); + EXPECT(a[1] == 7); + EXPECT(a[2] == 9); +} + +// Test += operator with scalar +TEST_CASE(array_add_assign_scalar) +{ + migraphx::array arr{1, 2, 3}; + arr += 10; + + EXPECT(arr[0] == 11); + EXPECT(arr[1] == 12); + EXPECT(arr[2] == 13); +} + +// Test -= operator with array +TEST_CASE(array_sub_assign_array) +{ + migraphx::array a{5, 7, 9}; + migraphx::array b{1, 2, 3}; + + a -= b; + EXPECT(a[0] == 4); + EXPECT(a[1] == 5); + EXPECT(a[2] == 6); +} + +// Test -= operator with scalar +TEST_CASE(array_sub_assign_scalar) +{ + migraphx::array arr{10, 20, 30}; + arr -= 5; + + EXPECT(arr[0] == 5); + EXPECT(arr[1] == 15); + EXPECT(arr[2] == 25); +} + +// Test *= operator with array +TEST_CASE(array_mul_assign_array) +{ + migraphx::array a{2, 3, 4}; + migraphx::array b{3, 4, 5}; + + a *= b; + EXPECT(a[0] == 6); + EXPECT(a[1] == 12); + EXPECT(a[2] == 20); +} + +// Test *= operator with scalar +TEST_CASE(array_mul_assign_scalar) +{ + migraphx::array arr{2, 3, 4}; + arr *= 3; + + EXPECT(arr[0] == 6); + EXPECT(arr[1] == 9); + EXPECT(arr[2] == 12); +} + +// Test /= operator with array +TEST_CASE(array_div_assign_array) +{ + migraphx::array a{12, 15, 20}; + migraphx::array b{3, 5, 4}; + + a /= b; + EXPECT(a[0] == 4); + EXPECT(a[1] == 3); + EXPECT(a[2] == 5); +} + +// Test /= operator with scalar +TEST_CASE(array_div_assign_scalar) +{ + migraphx::array arr{12, 18, 24}; + arr /= 3; + + EXPECT(arr[0] == 4); + EXPECT(arr[1] == 6); + EXPECT(arr[2] == 8); +} + +// Test %= operator with array +TEST_CASE(array_mod_assign_array) +{ + migraphx::array a{10, 13, 17}; + migraphx::array b{3, 5, 7}; + + a %= b; + EXPECT(a[0] == 1); // 10 % 3 = 1 + EXPECT(a[1] == 3); // 13 % 5 = 3 + EXPECT(a[2] == 3); // 17 % 7 = 3 +} + +// Test %= operator with scalar +TEST_CASE(array_mod_assign_scalar) +{ + migraphx::array arr{10, 13, 17}; + arr %= 5; + + EXPECT(arr[0] == 0); // 10 % 5 = 0 + EXPECT(arr[1] == 3); // 13 % 5 = 3 + EXPECT(arr[2] == 2); // 17 % 5 = 2 +} + +// Test &= operator with array +TEST_CASE(array_and_assign_array) +{ + migraphx::array a{15, 12, 8}; // 1111, 1100, 1000 + migraphx::array b{7, 10, 15}; // 0111, 1010, 1111 + + a &= b; + EXPECT(a[0] == 7); // 1111 & 0111 = 0111 = 7 + EXPECT(a[1] == 8); // 1100 & 1010 = 1000 = 8 + EXPECT(a[2] == 8); // 1000 & 1111 = 1000 = 8 +} + +// Test &= operator with scalar +TEST_CASE(array_and_assign_scalar) +{ + migraphx::array arr{15, 12, 8}; // 1111, 1100, 1000 + arr &= 7; // 0111 + + EXPECT(arr[0] == 7); // 1111 & 0111 = 0111 = 7 + EXPECT(arr[1] == 4); // 1100 & 0111 = 0100 = 4 + EXPECT(arr[2] == 0); // 1000 & 0111 = 0000 = 0 +} + +// Test |= operator with array +TEST_CASE(array_or_assign_array) +{ + migraphx::array a{8, 4, 2}; // 1000, 0100, 0010 + migraphx::array b{4, 2, 1}; // 0100, 0010, 0001 + + a |= b; + EXPECT(a[0] == 12); // 1000 | 0100 = 1100 = 12 + EXPECT(a[1] == 6); // 0100 | 0010 = 0110 = 6 + EXPECT(a[2] == 3); // 0010 | 0001 = 0011 = 3 +} + +// Test |= operator with scalar +TEST_CASE(array_or_assign_scalar) +{ + migraphx::array arr{8, 4, 2}; // 1000, 0100, 0010 + arr |= 1; // 0001 + + EXPECT(arr[0] == 9); // 1000 | 0001 = 1001 = 9 + EXPECT(arr[1] == 5); // 0100 | 0001 = 0101 = 5 + EXPECT(arr[2] == 3); // 0010 | 0001 = 0011 = 3 +} + +// Test ^= operator with array +TEST_CASE(array_xor_assign_array) +{ + migraphx::array a{12, 10, 6}; // 1100, 1010, 0110 + migraphx::array b{7, 5, 3}; // 0111, 0101, 0011 + + a ^= b; + EXPECT(a[0] == 11); // 1100 ^ 0111 = 1011 = 11 + EXPECT(a[1] == 15); // 1010 ^ 0101 = 1111 = 15 + EXPECT(a[2] == 5); // 0110 ^ 0011 = 0101 = 5 +} + +// Test ^= operator with scalar +TEST_CASE(array_xor_assign_scalar) +{ + migraphx::array arr{12, 10, 6}; // 1100, 1010, 0110 + arr ^= 5; // 0101 + + EXPECT(arr[0] == 9); // 1100 ^ 0101 = 1001 = 9 + EXPECT(arr[1] == 15); // 1010 ^ 0101 = 1111 = 15 + EXPECT(arr[2] == 3); // 0110 ^ 0101 = 0011 = 3 +} + +// Test + operator with arrays +TEST_CASE(array_add_arrays) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{4, 5, 6}; + + auto result = a + b; + EXPECT(result[0] == 5); + EXPECT(result[1] == 7); + EXPECT(result[2] == 9); +} + +// Test + operator with scalar (array + scalar) +TEST_CASE(array_add_scalar_right) +{ + migraphx::array arr{1, 2, 3}; + auto result = arr + 10; + + EXPECT(result[0] == 11); + EXPECT(result[1] == 12); + EXPECT(result[2] == 13); +} + +// Test + operator with scalar (scalar + array) +TEST_CASE(array_add_scalar_left) +{ + migraphx::array arr{1, 2, 3}; + auto result = 10 + arr; + + EXPECT(result[0] == 11); + EXPECT(result[1] == 12); + EXPECT(result[2] == 13); +} + +// Test - operator with arrays +TEST_CASE(array_sub_arrays) +{ + migraphx::array a{5, 7, 9}; + migraphx::array b{1, 2, 3}; + + auto result = a - b; + EXPECT(result[0] == 4); + EXPECT(result[1] == 5); + EXPECT(result[2] == 6); +} + +// Test - operator with scalar (array - scalar) +TEST_CASE(array_sub_scalar_right) +{ + migraphx::array arr{10, 20, 30}; + auto result = arr - 5; + + EXPECT(result[0] == 5); + EXPECT(result[1] == 15); + EXPECT(result[2] == 25); +} + +// Test - operator with scalar (scalar - array) +TEST_CASE(array_sub_scalar_left) +{ + migraphx::array arr{1, 2, 3}; + auto result = 10 - arr; + + EXPECT(result[0] == 9); + EXPECT(result[1] == 8); + EXPECT(result[2] == 7); +} + +// Test * operator with arrays +TEST_CASE(array_mul_arrays) +{ + migraphx::array a{2, 3, 4}; + migraphx::array b{3, 4, 5}; + + auto result = a * b; + EXPECT(result[0] == 6); + EXPECT(result[1] == 12); + EXPECT(result[2] == 20); +} + +// Test * operator with scalar (array * scalar) +TEST_CASE(array_mul_scalar_right) +{ + migraphx::array arr{2, 3, 4}; + auto result = arr * 3; + + EXPECT(result[0] == 6); + EXPECT(result[1] == 9); + EXPECT(result[2] == 12); +} + +// Test * operator with scalar (scalar * array) +TEST_CASE(array_mul_scalar_left) +{ + migraphx::array arr{2, 3, 4}; + auto result = 3 * arr; + + EXPECT(result[0] == 6); + EXPECT(result[1] == 9); + EXPECT(result[2] == 12); +} + +// Test / operator with arrays +TEST_CASE(array_div_arrays) +{ + migraphx::array a{12, 15, 20}; + migraphx::array b{3, 5, 4}; + + auto result = a / b; + EXPECT(result[0] == 4); + EXPECT(result[1] == 3); + EXPECT(result[2] == 5); +} + +// Test / operator with scalar (array / scalar) +TEST_CASE(array_div_scalar_right) +{ + migraphx::array arr{12, 18, 24}; + auto result = arr / 3; + + EXPECT(result[0] == 4); + EXPECT(result[1] == 6); + EXPECT(result[2] == 8); +} + +// Test / operator with scalar (scalar / array) +TEST_CASE(array_div_scalar_left) +{ + migraphx::array arr{2, 3, 4}; + auto result = 12 / arr; + + EXPECT(result[0] == 6); + EXPECT(result[1] == 4); + EXPECT(result[2] == 3); +} + +// Test % operator with arrays +TEST_CASE(array_mod_arrays) +{ + migraphx::array a{10, 13, 17}; + migraphx::array b{3, 5, 7}; + + auto result = a % b; + EXPECT(result[0] == 1); // 10 % 3 = 1 + EXPECT(result[1] == 3); // 13 % 5 = 3 + EXPECT(result[2] == 3); // 17 % 7 = 3 +} + +// Test % operator with scalar (array % scalar) +TEST_CASE(array_mod_scalar_right) +{ + migraphx::array arr{10, 13, 17}; + auto result = arr % 5; + + EXPECT(result[0] == 0); // 10 % 5 = 0 + EXPECT(result[1] == 3); // 13 % 5 = 3 + EXPECT(result[2] == 2); // 17 % 5 = 2 +} + +// Test % operator with scalar (scalar % array) +TEST_CASE(array_mod_scalar_left) +{ + migraphx::array arr{3, 4, 5}; + auto result = 17 % arr; + + EXPECT(result[0] == 2); // 17 % 3 = 2 + EXPECT(result[1] == 1); // 17 % 4 = 1 + EXPECT(result[2] == 2); // 17 % 5 = 2 +} + +// Test & operator with arrays +TEST_CASE(array_and_arrays) +{ + migraphx::array a{15, 12, 8}; // 1111, 1100, 1000 + migraphx::array b{7, 10, 15}; // 0111, 1010, 1111 + + auto result = a & b; + EXPECT(result[0] == 7); // 1111 & 0111 = 0111 = 7 + EXPECT(result[1] == 8); // 1100 & 1010 = 1000 = 8 + EXPECT(result[2] == 8); // 1000 & 1111 = 1000 = 8 +} + +// Test & operator with scalar (array & scalar) +TEST_CASE(array_and_scalar_right) +{ + migraphx::array arr{15, 12, 8}; // 1111, 1100, 1000 + auto result = arr & 7; // 0111 + + EXPECT(result[0] == 7); // 1111 & 0111 = 0111 = 7 + EXPECT(result[1] == 4); // 1100 & 0111 = 0100 = 4 + EXPECT(result[2] == 0); // 1000 & 0111 = 0000 = 0 +} + +// Test & operator with scalar (scalar & array) +TEST_CASE(array_and_scalar_left) +{ + migraphx::array arr{15, 12, 8}; // 1111, 1100, 1000 + auto result = 7 & arr; // 0111 + + EXPECT(result[0] == 7); // 0111 & 1111 = 0111 = 7 + EXPECT(result[1] == 4); // 0111 & 1100 = 0100 = 4 + EXPECT(result[2] == 0); // 0111 & 1000 = 0000 = 0 +} + +// Test | operator with arrays +TEST_CASE(array_or_arrays) +{ + migraphx::array a{8, 4, 2}; // 1000, 0100, 0010 + migraphx::array b{4, 2, 1}; // 0100, 0010, 0001 + + auto result = a | b; + EXPECT(result[0] == 12); // 1000 | 0100 = 1100 = 12 + EXPECT(result[1] == 6); // 0100 | 0010 = 0110 = 6 + EXPECT(result[2] == 3); // 0010 | 0001 = 0011 = 3 +} + +// Test | operator with scalar (array | scalar) +TEST_CASE(array_or_scalar_right) +{ + migraphx::array arr{8, 4, 2}; // 1000, 0100, 0010 + auto result = arr | 1; // 0001 + + EXPECT(result[0] == 9); // 1000 | 0001 = 1001 = 9 + EXPECT(result[1] == 5); // 0100 | 0001 = 0101 = 5 + EXPECT(result[2] == 3); // 0010 | 0001 = 0011 = 3 +} + +// Test | operator with scalar (scalar | array) +TEST_CASE(array_or_scalar_left) +{ + migraphx::array arr{8, 4, 2}; // 1000, 0100, 0010 + auto result = 1 | arr; // 0001 + + EXPECT(result[0] == 9); // 0001 | 1000 = 1001 = 9 + EXPECT(result[1] == 5); // 0001 | 0100 = 0101 = 5 + EXPECT(result[2] == 3); // 0001 | 0010 = 0011 = 3 +} + +// Test ^ operator with arrays +TEST_CASE(array_xor_arrays) +{ + migraphx::array a{12, 10, 6}; // 1100, 1010, 0110 + migraphx::array b{7, 5, 3}; // 0111, 0101, 0011 + + auto result = a ^ b; + EXPECT(result[0] == 11); // 1100 ^ 0111 = 1011 = 11 + EXPECT(result[1] == 15); // 1010 ^ 0101 = 1111 = 15 + EXPECT(result[2] == 5); // 0110 ^ 0011 = 0101 = 5 +} + +// Test ^ operator with scalar (array ^ scalar) +TEST_CASE(array_xor_scalar_right) +{ + migraphx::array arr{12, 10, 6}; // 1100, 1010, 0110 + auto result = arr ^ 5; // 0101 + + EXPECT(result[0] == 9); // 1100 ^ 0101 = 1001 = 9 + EXPECT(result[1] == 15); // 1010 ^ 0101 = 1111 = 15 + EXPECT(result[2] == 3); // 0110 ^ 0101 = 0011 = 3 +} + +// Test ^ operator with scalar (scalar ^ array) +TEST_CASE(array_xor_scalar_left) +{ + migraphx::array arr{12, 10, 6}; // 1100, 1010, 0110 + auto result = 5 ^ arr; // 0101 + + EXPECT(result[0] == 9); // 0101 ^ 1100 = 1001 = 9 + EXPECT(result[1] == 15); // 0101 ^ 1010 = 1111 = 15 + EXPECT(result[2] == 3); // 0101 ^ 0110 = 0011 = 3 +} + +// Test == operator with arrays +TEST_CASE(array_equality_arrays) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{1, 2, 3}; + migraphx::array c{1, 2, 4}; + + EXPECT(a == b); + EXPECT(not(a == c)); +} + +// Test == operator with scalar (array == scalar) +TEST_CASE(array_equality_scalar_right) +{ + migraphx::array arr1{5, 5, 5}; + migraphx::array arr2{5, 5, 6}; + + EXPECT(arr1 == 5); + EXPECT(not(arr2 == 5)); +} + +// Test == operator with scalar (scalar == array) +TEST_CASE(array_equality_scalar_left) +{ + migraphx::array arr1{5, 5, 5}; + migraphx::array arr2{5, 5, 6}; + + EXPECT(5 == arr1); + EXPECT(not(5 == arr2)); +} + +// Test != operator +TEST_CASE(array_inequality) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{1, 2, 3}; + migraphx::array c{1, 2, 4}; + + EXPECT(a == b); // Test equality instead + EXPECT(not(a == c)); // Test inequality using negation of == + EXPECT(not(a == 5)); // Using negation of == instead of != + EXPECT(not(5 == a)); // Using negation of == instead of != +} + +// Test < operator (product order) +TEST_CASE(array_less_than) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{2, 3, 4}; + migraphx::array c{1, 1, 3}; + + EXPECT(a < b); // all elements of a < corresponding elements of b + EXPECT(not(a < c)); // a[1] = 2 is not < c[1] = 1 +} + +// Test > operator +TEST_CASE(array_greater_than) +{ + migraphx::array a{2, 3, 4}; + migraphx::array b{1, 2, 3}; + + EXPECT(a > b); + EXPECT(not(b > a)); +} + +// Test <= operator +TEST_CASE(array_less_equal) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{1, 2, 3}; + migraphx::array c{2, 3, 4}; + + EXPECT(a <= b); // equal + EXPECT(a <= c); // less than + EXPECT(not(c <= a)); +} + +// Test >= operator +TEST_CASE(array_greater_equal) +{ + migraphx::array a{1, 2, 3}; + migraphx::array b{1, 2, 3}; + migraphx::array c{2, 3, 4}; + + EXPECT(a >= b); // equal + EXPECT(c >= a); // greater than + EXPECT(not(a >= c)); +} + +// Test carry() method +TEST_CASE(array_carry_method) +{ + migraphx::array shape{10, 10, 10}; + migraphx::array input{5, 15, 25}; + + auto result = shape.carry(input); + // Detailed calculation: + // Start with {5, 15, 25} + // Process index 2: 25 -> 25-10-10 = 5, overflow = 2 + // Process index 1: 15+2 = 17 -> 17-10 = 7, overflow = 1 + // Process index 0: 5+1 = 6 + EXPECT(result[0] == 6); // 5 + 1 (overflow from index 1) + EXPECT(result[1] == 7); // (15 + 2) % 10 = 17 % 10 = 7 + EXPECT(result[2] == 5); // 25 % 10 = 5 +} + +// Test carry() with no overflow +TEST_CASE(array_carry_no_overflow) +{ + migraphx::array shape{10, 10, 10}; + migraphx::array input{1, 2, 3}; + + auto result = shape.carry(input); + EXPECT(result[0] == 1); + EXPECT(result[1] == 2); + EXPECT(result[2] == 3); +} + +// Test multi() method +TEST_CASE(array_multi_method) +{ + migraphx::array shape{2, 3, 4}; + + auto result = shape.multi(11); // 11 in base (2,3,4) + // 11 = 1*12 + 3*4 + 3*1 = 12 + 12 + 3 = 27? Let's check calculation + // For shape {2,3,4}, we compute multi-index for linear index 11 + + // result[2] = 11 % 4 = 3 + // temp = 11 / 4 = 2 + // result[1] = 2 % 3 = 2 + // temp = 2 / 3 = 0 + // result[0] = 0 + + EXPECT(result[0] == 0); + EXPECT(result[1] == 2); + EXPECT(result[2] == 3); +} + +// Test multi() method with simple case +TEST_CASE(array_multi_simple) +{ + migraphx::array shape{3, 4}; + + auto result = shape.multi(5); // 5 in base (3,4) + // result[1] = 5 % 4 = 1 + // temp = 5 / 4 = 1 + // result[0] = 1 + + EXPECT(result[0] == 1); + EXPECT(result[1] == 1); +} + +// Test different data types +TEST_CASE(array_different_types) +{ + migraphx::array arr_double{1.5, 2.5, 3.5}; + migraphx::array arr_float{1.0f, 2.0f, 3.0f}; + migraphx::array arr_char{'a', 'b', 'c'}; + + EXPECT(migraphx::float_equal(arr_double[0], 1.5)); + EXPECT(migraphx::float_equal(arr_float[1], 2.0f)); + EXPECT(arr_char[2] == 'c'); +} + +// Test mixed type operations +TEST_CASE(array_mixed_type_operations) +{ + migraphx::array arr_int{1, 2, 3}; + + auto result = arr_int + 1.5; // int array + double + // Should convert to double array + EXPECT(migraphx::float_equal(result[0], 2.5)); + EXPECT(migraphx::float_equal(result[1], 3.5)); + EXPECT(migraphx::float_equal(result[2], 4.5)); +} + +// Test large arrays +TEST_CASE(array_large_size) +{ + migraphx::array large_arr(42); + + EXPECT(large_arr.size() == 100); + EXPECT(large_arr[0] == 42); + EXPECT(large_arr[50] == 42); + EXPECT(large_arr[99] == 42); +} + +// Test single element array special cases +TEST_CASE(array_single_element) +{ + migraphx::array arr{42}; + + EXPECT(arr.front() == 42); + EXPECT(arr.back() == 42); + EXPECT(arr.size() == 1); + EXPECT(not arr.empty()); + EXPECT(arr.product() == 42); + + auto doubled = arr.apply([](int x) { return x * 2; }); + EXPECT(doubled[0] == 84); +} + +// Test edge cases for mathematical operations +TEST_CASE(array_math_edge_cases) +{ + // Test with zeros + migraphx::array zeros{0, 0, 0}; + EXPECT(zeros.product() == 0); + EXPECT(zeros.dot(zeros) == 0); + + // Test with ones + migraphx::array ones{1, 1, 1}; + EXPECT(ones.product() == 1); + + // Test mixed positive/negative + migraphx::array mixed{-1, 2, -3}; + EXPECT(mixed.product() == 6); // -1 * 2 * -3 = 6 +} + +// Test type conversions in operations +TEST_CASE(array_type_conversions) +{ + migraphx::array int_arr{1, 2, 3}; + migraphx::array double_arr{1.5, 2.5, 3.5}; + + // This should work due to type conversion capabilities + auto result = int_arr + double_arr; + EXPECT(migraphx::float_equal(result[0], 2.5)); + EXPECT(migraphx::float_equal(result[1], 4.5)); + EXPECT(migraphx::float_equal(result[2], 6.5)); +} + +// Test chained operations +TEST_CASE(array_chained_operations) +{ + migraphx::array arr{1, 2, 3}; + + auto result = (arr + 1) * 2 - 1; + EXPECT(result[0] == 3); // (1+1)*2-1 = 3 + EXPECT(result[1] == 5); // (2+1)*2-1 = 5 + EXPECT(result[2] == 7); // (3+1)*2-1 = 7 +} + +// Test const correctness +TEST_CASE(array_const_correctness) +{ + const migraphx::array const_arr{1, 2, 3}; + + // These should all work with const array + EXPECT(const_arr.size() == 3); + EXPECT(not const_arr.empty()); + EXPECT(const_arr.front() == 1); + EXPECT(const_arr.back() == 3); + EXPECT(const_arr[1] == 2); + EXPECT(const_arr.data()[0] == 1); + EXPECT(const_arr.begin()[0] == 1); + EXPECT(const_arr.product() == 6); + + auto applied = const_arr.apply([](int x) { return x * 2; }); + EXPECT(applied[0] == 2); +} + +// Test iterator functionality thoroughly +TEST_CASE(array_iterator_functionality) +{ + migraphx::array arr{10, 20, 30, 40, 50}; + + // Test forward iteration + int expected = 10; + for(auto it = arr.begin(); it != arr.end(); ++it) + { + EXPECT(*it == expected); + expected += 10; + } + + // Test modifying through iterator + for(auto it = arr.begin(); it != arr.end(); ++it) + { + *it += 1; + } + + EXPECT(arr[0] == 11); + EXPECT(arr[4] == 51); +} + +// Test array with bool type (special case) +TEST_CASE(array_bool_type) +{ + migraphx::array bool_arr{true, false, true, false}; + + EXPECT(bool_arr[0] == true); + EXPECT(bool_arr[1] == false); + EXPECT(bool_arr[2] == true); + EXPECT(bool_arr[3] == false); + + bool_arr[1] = true; + EXPECT(bool_arr[1] == true); +} + +// ==================== Tests for Selected Functions ==================== + +// Test array_apply function +TEST_CASE(array_apply_function) +{ + migraphx::array arr{1, 2, 3}; + + // Test with simple lambda + auto doubler = migraphx::array_apply([](int x) { return x * 2; }); + auto doubled = doubler(arr); + + EXPECT(doubled[0] == 2); + EXPECT(doubled[1] == 4); + EXPECT(doubled[2] == 6); +} + +// Test array_apply with type conversion +TEST_CASE(array_apply_function_type_conversion) +{ + migraphx::array int_arr{1, 2, 3}; + + auto int_to_float = migraphx::array_apply([](int x) { return float(x) + 0.5f; }); + auto float_result = int_to_float(int_arr); + + EXPECT(migraphx::float_equal(float_result[0], 1.5f)); + EXPECT(migraphx::float_equal(float_result[1], 2.5f)); + EXPECT(migraphx::float_equal(float_result[2], 3.5f)); +} + +// Test array_apply with complex operation +TEST_CASE(array_apply_complex_operation) +{ + migraphx::array arr{1, 2, 3, 4}; + + auto square_plus_one = migraphx::array_apply([](int x) { return x * x + 1; }); + auto result = square_plus_one(arr); + + EXPECT(result[0] == 2); // 1*1 + 1 = 2 + EXPECT(result[1] == 5); // 2*2 + 1 = 5 + EXPECT(result[2] == 10); // 3*3 + 1 = 10 + EXPECT(result[3] == 17); // 4*4 + 1 = 17 +} + +// Test make_array function +TEST_CASE(make_array_function) +{ + auto arr = migraphx::make_array(1, 2, 3, 4); + + EXPECT(arr.size() == 4); + EXPECT(arr[0] == 1); + EXPECT(arr[1] == 2); + EXPECT(arr[2] == 3); + EXPECT(arr[3] == 4); +} + +// Test make_array with type conversion +TEST_CASE(make_array_type_conversion) +{ + auto arr = migraphx::make_array(1, 2.5, 3, 4.7); + + EXPECT(arr.size() == 4); + EXPECT(arr[0] == 1); + EXPECT(arr[1] == 2); // Should be cast to int + EXPECT(arr[2] == 3); + EXPECT(arr[3] == 4); // Should be cast to int +} + +// Test make_array with single element +TEST_CASE(make_array_single_element) +{ + auto arr = migraphx::make_array(42); + + EXPECT(arr.size() == 1); + EXPECT(arr[0] == 42); +} + +// Test make_array with mixed types +TEST_CASE(make_array_mixed_types) +{ + auto arr = migraphx::make_array(1.0, 2, 3.5f); + + EXPECT(arr.size() == 3); + EXPECT(migraphx::float_equal(arr[0], 1.0)); + EXPECT(migraphx::float_equal(arr[1], 2.0)); + EXPECT(migraphx::float_equal(arr[2], 3.5)); +} + +// Test integral_const_array basic functionality +TEST_CASE(integral_const_array_basic) +{ + migraphx::integral_const_array const_arr; + + EXPECT(const_arr.size() == 3); + EXPECT(const_arr[0] == 1); + EXPECT(const_arr[1] == 2); + EXPECT(const_arr[2] == 3); +} + +// Test integral_const_array base() method +TEST_CASE(integral_const_array_base) +{ + migraphx::integral_const_array const_arr; + auto base_arr = const_arr.base(); + + EXPECT(base_arr.size() == 3); + EXPECT(base_arr[0] == 5); + EXPECT(base_arr[1] == 10); + EXPECT(base_arr[2] == 15); +} + +// Test generate_array function +TEST_CASE(generate_array_function) +{ + auto arr = migraphx::generate_array(migraphx::_c<4>, [](auto i) { return static_cast(i * 2); }); + + EXPECT(arr.size() == 4); + EXPECT(arr[0] == 0); // 0 * 2 = 0 + EXPECT(arr[1] == 2); // 1 * 2 = 2 + EXPECT(arr[2] == 4); // 2 * 2 = 4 + EXPECT(arr[3] == 6); // 3 * 2 = 6 +} + +// Test generate_array with more complex generator +TEST_CASE(generate_array_complex_generator) +{ + auto arr = migraphx::generate_array(migraphx::_c<3>, [](auto i) { return static_cast((i + 1) * (i + 1)); }); + + EXPECT(arr.size() == 3); + EXPECT(arr[0] == 1); // (0+1)^2 = 1 + EXPECT(arr[1] == 4); // (1+1)^2 = 4 + EXPECT(arr[2] == 9); // (2+1)^2 = 9 +} + +// Test generate_array with single element +TEST_CASE(generate_array_single_element) +{ + auto arr = migraphx::generate_array(migraphx::_c<1>, [](auto /* i */) { return 42; }); + + EXPECT(arr.size() == 1); + EXPECT(arr[0] == 42); +} + +// Test unpack function with integral_const_array +TEST_CASE(unpack_function) +{ + migraphx::integral_const_array const_arr; + + auto result = migraphx::unpack(const_arr, [](auto... values) { + return (values + ...); // C++17 fold expression to sum all values + }); + + EXPECT(result == 6); // 1 + 2 + 3 = 6 +} + +// Test unpack with different operation +TEST_CASE(unpack_product) +{ + migraphx::integral_const_array const_arr; + + auto result = migraphx::unpack(const_arr, [](auto... values) { + return (values * ...); // Product of all values + }); + + EXPECT(result == 24); // 2 * 3 * 4 = 24 +} + +// Test unpack with single value +TEST_CASE(unpack_single_value) +{ + migraphx::integral_const_array const_arr; + + auto result = migraphx::unpack(const_arr, [](auto value) { + return value * 2; + }); + + EXPECT(result == 84); +} + +// Test transform function (single array) +TEST_CASE(transform_single_array) +{ + migraphx::integral_const_array const_arr; + + auto transformed = migraphx::transform(const_arr, [](auto x) { return x * 2; }); + + EXPECT(transformed.size() == 3); + EXPECT(transformed[0] == 2); + EXPECT(transformed[1] == 4); + EXPECT(transformed[2] == 6); +} + +// Test transform function with different operation +TEST_CASE(transform_square) +{ + migraphx::integral_const_array const_arr; + + auto squared = migraphx::transform(const_arr, [](auto x) { return x * x; }); + + EXPECT(squared.size() == 4); + EXPECT(squared[0] == 1); + EXPECT(squared[1] == 4); + EXPECT(squared[2] == 9); + EXPECT(squared[3] == 16); +} + +// Test transform_i function (with index) +TEST_CASE(transform_i_function) +{ + migraphx::integral_const_array const_arr; + + auto transformed = migraphx::transform_i(const_arr, [](auto value, auto index) { + return value + index; + }); + + EXPECT(transformed.size() == 3); + EXPECT(transformed[0] == 10); // 10 + 0 = 10 + EXPECT(transformed[1] == 21); // 20 + 1 = 21 + EXPECT(transformed[2] == 32); // 30 + 2 = 32 +} + +// Test transform_i with index multiplication +TEST_CASE(transform_i_multiply_index) +{ + migraphx::integral_const_array const_arr; + + auto transformed = migraphx::transform_i(const_arr, [](auto value, auto index) { + return value * (index + 1); + }); + + EXPECT(transformed.size() == 3); + EXPECT(transformed[0] == 5); // 5 * (0+1) = 5 + EXPECT(transformed[1] == 12); // 6 * (1+1) = 12 + EXPECT(transformed[2] == 21); // 7 * (2+1) = 21 +} + +// Test transform with two arrays +TEST_CASE(transform_two_arrays) +{ + migraphx::integral_const_array arr1; + migraphx::integral_const_array arr2; + + auto result = migraphx::transform(arr1, arr2, [](auto x, auto y) { return x + y; }); + + EXPECT(result.size() == 3); + EXPECT(result[0] == 5); // 1 + 4 = 5 + EXPECT(result[1] == 7); // 2 + 5 = 7 + EXPECT(result[2] == 9); // 3 + 6 = 9 +} + +// Test transform with two arrays and multiplication +TEST_CASE(transform_two_arrays_multiply) +{ + migraphx::integral_const_array arr1; + migraphx::integral_const_array arr2; + + auto result = migraphx::transform(arr1, arr2, [](auto x, auto y) { return x * y; }); + + EXPECT(result.size() == 3); + EXPECT(result[0] == 10); // 2 * 5 = 10 + EXPECT(result[1] == 18); // 3 * 6 = 18 + EXPECT(result[2] == 28); // 4 * 7 = 28 +} + +// Test index_ints type alias +TEST_CASE(index_ints_type_alias) +{ + migraphx::index_ints<1, 2, 3, 4> indices; + + EXPECT(indices.size() == 4); + EXPECT(indices[0] == 1); + EXPECT(indices[1] == 2); + EXPECT(indices[2] == 3); + EXPECT(indices[3] == 4); +} + +// Test edge case: empty operations +TEST_CASE(utility_functions_edge_cases) +{ + // Test single element arrays + migraphx::integral_const_array single; + auto transformed_single = migraphx::transform(single, [](auto x) { return x * 2; }); + EXPECT(transformed_single[0] == 84); + + // Test with zero values + migraphx::integral_const_array zeros; + auto transformed_zeros = migraphx::transform(zeros, [](auto x) { return x + 1; }); + EXPECT(transformed_zeros[0] == 1); + EXPECT(transformed_zeros[1] == 1); + EXPECT(transformed_zeros[2] == 1); +} + +// Test complex function composition +TEST_CASE(function_composition_complex) +{ + // Create initial array + auto initial = migraphx::make_array(1, 2, 3); + + // Apply multiple transformations + auto applier1 = migraphx::array_apply([](int x) { return x * 2; }); + auto applier2 = migraphx::array_apply([](int x) { return x + 1; }); + + auto step1 = applier1(initial); + auto final_result = applier2(step1); + + EXPECT(final_result[0] == 3); // (1*2)+1 = 3 + EXPECT(final_result[1] == 5); // (2*2)+1 = 5 + EXPECT(final_result[2] == 7); // (3*2)+1 = 7 +} + +// Test type safety and consistency +TEST_CASE(type_safety_consistency) +{ + // Ensure make_array preserves type correctly + auto int_arr = migraphx::make_array(1, 2, 3); + auto float_arr = migraphx::make_array(1.0f, 2.0f, 3.0f); + + // Test that the values are correct regardless of exact type implementation + EXPECT(int_arr[0] == 1); + EXPECT(migraphx::float_equal(float_arr[0], 1.0f)); +} From 25b9bc0ff0e4179559da82054f69ec9b68c9066a Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 29 Aug 2025 19:14:12 +0000 Subject: [PATCH 12/20] Format --- test/gpu/kernels/array.cpp | 322 ++++++++++++++++++------------------- 1 file changed, 160 insertions(+), 162 deletions(-) diff --git a/test/gpu/kernels/array.cpp b/test/gpu/kernels/array.cpp index 7a3673dbdcc..6b56331cbbf 100644 --- a/test/gpu/kernels/array.cpp +++ b/test/gpu/kernels/array.cpp @@ -46,7 +46,7 @@ TEST_CASE(array_element_access) EXPECT(arr[0] == 10); EXPECT(arr[1] == 20); EXPECT(arr[2] == 30); - + arr[1] = 25; EXPECT(arr[1] == 25); } @@ -66,9 +66,9 @@ TEST_CASE(array_front_back) migraphx::array arr{1, 2, 3, 4}; EXPECT(arr.front() == 1); EXPECT(arr.back() == 4); - + arr.front() = 10; - arr.back() = 40; + arr.back() = 40; EXPECT(arr[0] == 10); EXPECT(arr[3] == 40); } @@ -89,7 +89,7 @@ TEST_CASE(array_data_method) EXPECT(ptr[0] == 1); EXPECT(ptr[1] == 2); EXPECT(ptr[2] == 3); - + ptr[0] = 10; EXPECT(arr[0] == 10); } @@ -111,7 +111,7 @@ TEST_CASE(array_size_method) migraphx::array arr1; migraphx::array arr5; migraphx::array arr100; - + // EXPECT(arr0.size() == 0); // Commented out EXPECT(arr1.size() == 1); EXPECT(arr5.size() == 5); @@ -123,7 +123,7 @@ TEST_CASE(array_empty_method) { // migraphx::array arr0; // Commented out due to compiler limitations migraphx::array arr1; - + // EXPECT(arr0.empty()); // Commented out EXPECT(not arr1.empty()); } @@ -132,7 +132,7 @@ TEST_CASE(array_empty_method) TEST_CASE(array_iterators) { migraphx::array arr{1, 2, 3, 4}; - + auto it = arr.begin(); EXPECT(*it == 1); ++it; @@ -149,7 +149,7 @@ TEST_CASE(array_iterators) TEST_CASE(array_const_iterators) { const migraphx::array arr{5, 10, 15}; - + auto it = arr.begin(); EXPECT(*it == 5); ++it; @@ -172,7 +172,7 @@ TEST_CASE(array_dot_product) { migraphx::array a{1, 2, 3}; migraphx::array b{4, 5, 6}; - + int result = a.dot(b); EXPECT(result == 32); // 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32 } @@ -182,7 +182,7 @@ TEST_CASE(array_dot_product_zero) { migraphx::array a{1, 2, 3}; migraphx::array b{0, 0, 0}; - + int result = a.dot(b); EXPECT(result == 0); } @@ -232,7 +232,7 @@ TEST_CASE(array_apply_method) { migraphx::array arr{1, 2, 3}; auto result = arr.apply([](int x) { return x * 2; }); - + EXPECT(result[0] == 2); EXPECT(result[1] == 4); EXPECT(result[2] == 6); @@ -243,7 +243,7 @@ TEST_CASE(array_apply_type_conversion) { migraphx::array arr{1, 2, 3}; auto result = arr.apply([](int x) { return static_cast(x) * 1.5; }); - + EXPECT(migraphx::float_equal(result[0], 1.5)); EXPECT(migraphx::float_equal(result[1], 3.0)); EXPECT(migraphx::float_equal(result[2], 4.5)); @@ -255,7 +255,7 @@ TEST_CASE(array_reduce_method) migraphx::array arr{1, 2, 3, 4}; int sum = arr.reduce([](int a, int b) { return a + b; }, 0); EXPECT(sum == 10); - + int product = arr.reduce([](int a, int b) { return a * b; }, 1); EXPECT(product == 24); } @@ -273,7 +273,7 @@ TEST_CASE(array_add_assign_array) { migraphx::array a{1, 2, 3}; migraphx::array b{4, 5, 6}; - + a += b; EXPECT(a[0] == 5); EXPECT(a[1] == 7); @@ -285,7 +285,7 @@ TEST_CASE(array_add_assign_scalar) { migraphx::array arr{1, 2, 3}; arr += 10; - + EXPECT(arr[0] == 11); EXPECT(arr[1] == 12); EXPECT(arr[2] == 13); @@ -296,7 +296,7 @@ TEST_CASE(array_sub_assign_array) { migraphx::array a{5, 7, 9}; migraphx::array b{1, 2, 3}; - + a -= b; EXPECT(a[0] == 4); EXPECT(a[1] == 5); @@ -308,7 +308,7 @@ TEST_CASE(array_sub_assign_scalar) { migraphx::array arr{10, 20, 30}; arr -= 5; - + EXPECT(arr[0] == 5); EXPECT(arr[1] == 15); EXPECT(arr[2] == 25); @@ -319,7 +319,7 @@ TEST_CASE(array_mul_assign_array) { migraphx::array a{2, 3, 4}; migraphx::array b{3, 4, 5}; - + a *= b; EXPECT(a[0] == 6); EXPECT(a[1] == 12); @@ -331,7 +331,7 @@ TEST_CASE(array_mul_assign_scalar) { migraphx::array arr{2, 3, 4}; arr *= 3; - + EXPECT(arr[0] == 6); EXPECT(arr[1] == 9); EXPECT(arr[2] == 12); @@ -342,7 +342,7 @@ TEST_CASE(array_div_assign_array) { migraphx::array a{12, 15, 20}; migraphx::array b{3, 5, 4}; - + a /= b; EXPECT(a[0] == 4); EXPECT(a[1] == 3); @@ -354,7 +354,7 @@ TEST_CASE(array_div_assign_scalar) { migraphx::array arr{12, 18, 24}; arr /= 3; - + EXPECT(arr[0] == 4); EXPECT(arr[1] == 6); EXPECT(arr[2] == 8); @@ -365,7 +365,7 @@ TEST_CASE(array_mod_assign_array) { migraphx::array a{10, 13, 17}; migraphx::array b{3, 5, 7}; - + a %= b; EXPECT(a[0] == 1); // 10 % 3 = 1 EXPECT(a[1] == 3); // 13 % 5 = 3 @@ -377,7 +377,7 @@ TEST_CASE(array_mod_assign_scalar) { migraphx::array arr{10, 13, 17}; arr %= 5; - + EXPECT(arr[0] == 0); // 10 % 5 = 0 EXPECT(arr[1] == 3); // 13 % 5 = 3 EXPECT(arr[2] == 2); // 17 % 5 = 2 @@ -388,19 +388,19 @@ TEST_CASE(array_and_assign_array) { migraphx::array a{15, 12, 8}; // 1111, 1100, 1000 migraphx::array b{7, 10, 15}; // 0111, 1010, 1111 - + a &= b; - EXPECT(a[0] == 7); // 1111 & 0111 = 0111 = 7 - EXPECT(a[1] == 8); // 1100 & 1010 = 1000 = 8 - EXPECT(a[2] == 8); // 1000 & 1111 = 1000 = 8 + EXPECT(a[0] == 7); // 1111 & 0111 = 0111 = 7 + EXPECT(a[1] == 8); // 1100 & 1010 = 1000 = 8 + EXPECT(a[2] == 8); // 1000 & 1111 = 1000 = 8 } // Test &= operator with scalar TEST_CASE(array_and_assign_scalar) { migraphx::array arr{15, 12, 8}; // 1111, 1100, 1000 - arr &= 7; // 0111 - + arr &= 7; // 0111 + EXPECT(arr[0] == 7); // 1111 & 0111 = 0111 = 7 EXPECT(arr[1] == 4); // 1100 & 0111 = 0100 = 4 EXPECT(arr[2] == 0); // 1000 & 0111 = 0000 = 0 @@ -411,7 +411,7 @@ TEST_CASE(array_or_assign_array) { migraphx::array a{8, 4, 2}; // 1000, 0100, 0010 migraphx::array b{4, 2, 1}; // 0100, 0010, 0001 - + a |= b; EXPECT(a[0] == 12); // 1000 | 0100 = 1100 = 12 EXPECT(a[1] == 6); // 0100 | 0010 = 0110 = 6 @@ -422,8 +422,8 @@ TEST_CASE(array_or_assign_array) TEST_CASE(array_or_assign_scalar) { migraphx::array arr{8, 4, 2}; // 1000, 0100, 0010 - arr |= 1; // 0001 - + arr |= 1; // 0001 + EXPECT(arr[0] == 9); // 1000 | 0001 = 1001 = 9 EXPECT(arr[1] == 5); // 0100 | 0001 = 0101 = 5 EXPECT(arr[2] == 3); // 0010 | 0001 = 0011 = 3 @@ -434,7 +434,7 @@ TEST_CASE(array_xor_assign_array) { migraphx::array a{12, 10, 6}; // 1100, 1010, 0110 migraphx::array b{7, 5, 3}; // 0111, 0101, 0011 - + a ^= b; EXPECT(a[0] == 11); // 1100 ^ 0111 = 1011 = 11 EXPECT(a[1] == 15); // 1010 ^ 0101 = 1111 = 15 @@ -445,8 +445,8 @@ TEST_CASE(array_xor_assign_array) TEST_CASE(array_xor_assign_scalar) { migraphx::array arr{12, 10, 6}; // 1100, 1010, 0110 - arr ^= 5; // 0101 - + arr ^= 5; // 0101 + EXPECT(arr[0] == 9); // 1100 ^ 0101 = 1001 = 9 EXPECT(arr[1] == 15); // 1010 ^ 0101 = 1111 = 15 EXPECT(arr[2] == 3); // 0110 ^ 0101 = 0011 = 3 @@ -457,7 +457,7 @@ TEST_CASE(array_add_arrays) { migraphx::array a{1, 2, 3}; migraphx::array b{4, 5, 6}; - + auto result = a + b; EXPECT(result[0] == 5); EXPECT(result[1] == 7); @@ -469,7 +469,7 @@ TEST_CASE(array_add_scalar_right) { migraphx::array arr{1, 2, 3}; auto result = arr + 10; - + EXPECT(result[0] == 11); EXPECT(result[1] == 12); EXPECT(result[2] == 13); @@ -480,7 +480,7 @@ TEST_CASE(array_add_scalar_left) { migraphx::array arr{1, 2, 3}; auto result = 10 + arr; - + EXPECT(result[0] == 11); EXPECT(result[1] == 12); EXPECT(result[2] == 13); @@ -491,7 +491,7 @@ TEST_CASE(array_sub_arrays) { migraphx::array a{5, 7, 9}; migraphx::array b{1, 2, 3}; - + auto result = a - b; EXPECT(result[0] == 4); EXPECT(result[1] == 5); @@ -503,7 +503,7 @@ TEST_CASE(array_sub_scalar_right) { migraphx::array arr{10, 20, 30}; auto result = arr - 5; - + EXPECT(result[0] == 5); EXPECT(result[1] == 15); EXPECT(result[2] == 25); @@ -514,7 +514,7 @@ TEST_CASE(array_sub_scalar_left) { migraphx::array arr{1, 2, 3}; auto result = 10 - arr; - + EXPECT(result[0] == 9); EXPECT(result[1] == 8); EXPECT(result[2] == 7); @@ -525,7 +525,7 @@ TEST_CASE(array_mul_arrays) { migraphx::array a{2, 3, 4}; migraphx::array b{3, 4, 5}; - + auto result = a * b; EXPECT(result[0] == 6); EXPECT(result[1] == 12); @@ -537,7 +537,7 @@ TEST_CASE(array_mul_scalar_right) { migraphx::array arr{2, 3, 4}; auto result = arr * 3; - + EXPECT(result[0] == 6); EXPECT(result[1] == 9); EXPECT(result[2] == 12); @@ -548,7 +548,7 @@ TEST_CASE(array_mul_scalar_left) { migraphx::array arr{2, 3, 4}; auto result = 3 * arr; - + EXPECT(result[0] == 6); EXPECT(result[1] == 9); EXPECT(result[2] == 12); @@ -559,7 +559,7 @@ TEST_CASE(array_div_arrays) { migraphx::array a{12, 15, 20}; migraphx::array b{3, 5, 4}; - + auto result = a / b; EXPECT(result[0] == 4); EXPECT(result[1] == 3); @@ -571,7 +571,7 @@ TEST_CASE(array_div_scalar_right) { migraphx::array arr{12, 18, 24}; auto result = arr / 3; - + EXPECT(result[0] == 4); EXPECT(result[1] == 6); EXPECT(result[2] == 8); @@ -582,7 +582,7 @@ TEST_CASE(array_div_scalar_left) { migraphx::array arr{2, 3, 4}; auto result = 12 / arr; - + EXPECT(result[0] == 6); EXPECT(result[1] == 4); EXPECT(result[2] == 3); @@ -593,7 +593,7 @@ TEST_CASE(array_mod_arrays) { migraphx::array a{10, 13, 17}; migraphx::array b{3, 5, 7}; - + auto result = a % b; EXPECT(result[0] == 1); // 10 % 3 = 1 EXPECT(result[1] == 3); // 13 % 5 = 3 @@ -605,7 +605,7 @@ TEST_CASE(array_mod_scalar_right) { migraphx::array arr{10, 13, 17}; auto result = arr % 5; - + EXPECT(result[0] == 0); // 10 % 5 = 0 EXPECT(result[1] == 3); // 13 % 5 = 3 EXPECT(result[2] == 2); // 17 % 5 = 2 @@ -616,7 +616,7 @@ TEST_CASE(array_mod_scalar_left) { migraphx::array arr{3, 4, 5}; auto result = 17 % arr; - + EXPECT(result[0] == 2); // 17 % 3 = 2 EXPECT(result[1] == 1); // 17 % 4 = 1 EXPECT(result[2] == 2); // 17 % 5 = 2 @@ -627,7 +627,7 @@ TEST_CASE(array_and_arrays) { migraphx::array a{15, 12, 8}; // 1111, 1100, 1000 migraphx::array b{7, 10, 15}; // 0111, 1010, 1111 - + auto result = a & b; EXPECT(result[0] == 7); // 1111 & 0111 = 0111 = 7 EXPECT(result[1] == 8); // 1100 & 1010 = 1000 = 8 @@ -638,8 +638,8 @@ TEST_CASE(array_and_arrays) TEST_CASE(array_and_scalar_right) { migraphx::array arr{15, 12, 8}; // 1111, 1100, 1000 - auto result = arr & 7; // 0111 - + auto result = arr & 7; // 0111 + EXPECT(result[0] == 7); // 1111 & 0111 = 0111 = 7 EXPECT(result[1] == 4); // 1100 & 0111 = 0100 = 4 EXPECT(result[2] == 0); // 1000 & 0111 = 0000 = 0 @@ -649,8 +649,8 @@ TEST_CASE(array_and_scalar_right) TEST_CASE(array_and_scalar_left) { migraphx::array arr{15, 12, 8}; // 1111, 1100, 1000 - auto result = 7 & arr; // 0111 - + auto result = 7 & arr; // 0111 + EXPECT(result[0] == 7); // 0111 & 1111 = 0111 = 7 EXPECT(result[1] == 4); // 0111 & 1100 = 0100 = 4 EXPECT(result[2] == 0); // 0111 & 1000 = 0000 = 0 @@ -661,7 +661,7 @@ TEST_CASE(array_or_arrays) { migraphx::array a{8, 4, 2}; // 1000, 0100, 0010 migraphx::array b{4, 2, 1}; // 0100, 0010, 0001 - + auto result = a | b; EXPECT(result[0] == 12); // 1000 | 0100 = 1100 = 12 EXPECT(result[1] == 6); // 0100 | 0010 = 0110 = 6 @@ -672,8 +672,8 @@ TEST_CASE(array_or_arrays) TEST_CASE(array_or_scalar_right) { migraphx::array arr{8, 4, 2}; // 1000, 0100, 0010 - auto result = arr | 1; // 0001 - + auto result = arr | 1; // 0001 + EXPECT(result[0] == 9); // 1000 | 0001 = 1001 = 9 EXPECT(result[1] == 5); // 0100 | 0001 = 0101 = 5 EXPECT(result[2] == 3); // 0010 | 0001 = 0011 = 3 @@ -683,8 +683,8 @@ TEST_CASE(array_or_scalar_right) TEST_CASE(array_or_scalar_left) { migraphx::array arr{8, 4, 2}; // 1000, 0100, 0010 - auto result = 1 | arr; // 0001 - + auto result = 1 | arr; // 0001 + EXPECT(result[0] == 9); // 0001 | 1000 = 1001 = 9 EXPECT(result[1] == 5); // 0001 | 0100 = 0101 = 5 EXPECT(result[2] == 3); // 0001 | 0010 = 0011 = 3 @@ -695,7 +695,7 @@ TEST_CASE(array_xor_arrays) { migraphx::array a{12, 10, 6}; // 1100, 1010, 0110 migraphx::array b{7, 5, 3}; // 0111, 0101, 0011 - + auto result = a ^ b; EXPECT(result[0] == 11); // 1100 ^ 0111 = 1011 = 11 EXPECT(result[1] == 15); // 1010 ^ 0101 = 1111 = 15 @@ -706,8 +706,8 @@ TEST_CASE(array_xor_arrays) TEST_CASE(array_xor_scalar_right) { migraphx::array arr{12, 10, 6}; // 1100, 1010, 0110 - auto result = arr ^ 5; // 0101 - + auto result = arr ^ 5; // 0101 + EXPECT(result[0] == 9); // 1100 ^ 0101 = 1001 = 9 EXPECT(result[1] == 15); // 1010 ^ 0101 = 1111 = 15 EXPECT(result[2] == 3); // 0110 ^ 0101 = 0011 = 3 @@ -717,8 +717,8 @@ TEST_CASE(array_xor_scalar_right) TEST_CASE(array_xor_scalar_left) { migraphx::array arr{12, 10, 6}; // 1100, 1010, 0110 - auto result = 5 ^ arr; // 0101 - + auto result = 5 ^ arr; // 0101 + EXPECT(result[0] == 9); // 0101 ^ 1100 = 1001 = 9 EXPECT(result[1] == 15); // 0101 ^ 1010 = 1111 = 15 EXPECT(result[2] == 3); // 0101 ^ 0110 = 0011 = 3 @@ -730,7 +730,7 @@ TEST_CASE(array_equality_arrays) migraphx::array a{1, 2, 3}; migraphx::array b{1, 2, 3}; migraphx::array c{1, 2, 4}; - + EXPECT(a == b); EXPECT(not(a == c)); } @@ -740,7 +740,7 @@ TEST_CASE(array_equality_scalar_right) { migraphx::array arr1{5, 5, 5}; migraphx::array arr2{5, 5, 6}; - + EXPECT(arr1 == 5); EXPECT(not(arr2 == 5)); } @@ -750,7 +750,7 @@ TEST_CASE(array_equality_scalar_left) { migraphx::array arr1{5, 5, 5}; migraphx::array arr2{5, 5, 6}; - + EXPECT(5 == arr1); EXPECT(not(5 == arr2)); } @@ -761,7 +761,7 @@ TEST_CASE(array_inequality) migraphx::array a{1, 2, 3}; migraphx::array b{1, 2, 3}; migraphx::array c{1, 2, 4}; - + EXPECT(a == b); // Test equality instead EXPECT(not(a == c)); // Test inequality using negation of == EXPECT(not(a == 5)); // Using negation of == instead of != @@ -774,7 +774,7 @@ TEST_CASE(array_less_than) migraphx::array a{1, 2, 3}; migraphx::array b{2, 3, 4}; migraphx::array c{1, 1, 3}; - + EXPECT(a < b); // all elements of a < corresponding elements of b EXPECT(not(a < c)); // a[1] = 2 is not < c[1] = 1 } @@ -784,7 +784,7 @@ TEST_CASE(array_greater_than) { migraphx::array a{2, 3, 4}; migraphx::array b{1, 2, 3}; - + EXPECT(a > b); EXPECT(not(b > a)); } @@ -795,7 +795,7 @@ TEST_CASE(array_less_equal) migraphx::array a{1, 2, 3}; migraphx::array b{1, 2, 3}; migraphx::array c{2, 3, 4}; - + EXPECT(a <= b); // equal EXPECT(a <= c); // less than EXPECT(not(c <= a)); @@ -807,7 +807,7 @@ TEST_CASE(array_greater_equal) migraphx::array a{1, 2, 3}; migraphx::array b{1, 2, 3}; migraphx::array c{2, 3, 4}; - + EXPECT(a >= b); // equal EXPECT(c >= a); // greater than EXPECT(not(a >= c)); @@ -818,16 +818,16 @@ TEST_CASE(array_carry_method) { migraphx::array shape{10, 10, 10}; migraphx::array input{5, 15, 25}; - + auto result = shape.carry(input); // Detailed calculation: // Start with {5, 15, 25} // Process index 2: 25 -> 25-10-10 = 5, overflow = 2 - // Process index 1: 15+2 = 17 -> 17-10 = 7, overflow = 1 + // Process index 1: 15+2 = 17 -> 17-10 = 7, overflow = 1 // Process index 0: 5+1 = 6 - EXPECT(result[0] == 6); // 5 + 1 (overflow from index 1) - EXPECT(result[1] == 7); // (15 + 2) % 10 = 17 % 10 = 7 - EXPECT(result[2] == 5); // 25 % 10 = 5 + EXPECT(result[0] == 6); // 5 + 1 (overflow from index 1) + EXPECT(result[1] == 7); // (15 + 2) % 10 = 17 % 10 = 7 + EXPECT(result[2] == 5); // 25 % 10 = 5 } // Test carry() with no overflow @@ -835,7 +835,7 @@ TEST_CASE(array_carry_no_overflow) { migraphx::array shape{10, 10, 10}; migraphx::array input{1, 2, 3}; - + auto result = shape.carry(input); EXPECT(result[0] == 1); EXPECT(result[1] == 2); @@ -846,17 +846,17 @@ TEST_CASE(array_carry_no_overflow) TEST_CASE(array_multi_method) { migraphx::array shape{2, 3, 4}; - + auto result = shape.multi(11); // 11 in base (2,3,4) // 11 = 1*12 + 3*4 + 3*1 = 12 + 12 + 3 = 27? Let's check calculation // For shape {2,3,4}, we compute multi-index for linear index 11 - + // result[2] = 11 % 4 = 3 // temp = 11 / 4 = 2 // result[1] = 2 % 3 = 2 // temp = 2 / 3 = 0 // result[0] = 0 - + EXPECT(result[0] == 0); EXPECT(result[1] == 2); EXPECT(result[2] == 3); @@ -866,12 +866,12 @@ TEST_CASE(array_multi_method) TEST_CASE(array_multi_simple) { migraphx::array shape{3, 4}; - + auto result = shape.multi(5); // 5 in base (3,4) // result[1] = 5 % 4 = 1 // temp = 5 / 4 = 1 // result[0] = 1 - + EXPECT(result[0] == 1); EXPECT(result[1] == 1); } @@ -882,7 +882,7 @@ TEST_CASE(array_different_types) migraphx::array arr_double{1.5, 2.5, 3.5}; migraphx::array arr_float{1.0f, 2.0f, 3.0f}; migraphx::array arr_char{'a', 'b', 'c'}; - + EXPECT(migraphx::float_equal(arr_double[0], 1.5)); EXPECT(migraphx::float_equal(arr_float[1], 2.0f)); EXPECT(arr_char[2] == 'c'); @@ -892,7 +892,7 @@ TEST_CASE(array_different_types) TEST_CASE(array_mixed_type_operations) { migraphx::array arr_int{1, 2, 3}; - + auto result = arr_int + 1.5; // int array + double // Should convert to double array EXPECT(migraphx::float_equal(result[0], 2.5)); @@ -904,7 +904,7 @@ TEST_CASE(array_mixed_type_operations) TEST_CASE(array_large_size) { migraphx::array large_arr(42); - + EXPECT(large_arr.size() == 100); EXPECT(large_arr[0] == 42); EXPECT(large_arr[50] == 42); @@ -915,13 +915,13 @@ TEST_CASE(array_large_size) TEST_CASE(array_single_element) { migraphx::array arr{42}; - + EXPECT(arr.front() == 42); EXPECT(arr.back() == 42); EXPECT(arr.size() == 1); EXPECT(not arr.empty()); EXPECT(arr.product() == 42); - + auto doubled = arr.apply([](int x) { return x * 2; }); EXPECT(doubled[0] == 84); } @@ -933,11 +933,11 @@ TEST_CASE(array_math_edge_cases) migraphx::array zeros{0, 0, 0}; EXPECT(zeros.product() == 0); EXPECT(zeros.dot(zeros) == 0); - + // Test with ones migraphx::array ones{1, 1, 1}; EXPECT(ones.product() == 1); - + // Test mixed positive/negative migraphx::array mixed{-1, 2, -3}; EXPECT(mixed.product() == 6); // -1 * 2 * -3 = 6 @@ -948,7 +948,7 @@ TEST_CASE(array_type_conversions) { migraphx::array int_arr{1, 2, 3}; migraphx::array double_arr{1.5, 2.5, 3.5}; - + // This should work due to type conversion capabilities auto result = int_arr + double_arr; EXPECT(migraphx::float_equal(result[0], 2.5)); @@ -960,7 +960,7 @@ TEST_CASE(array_type_conversions) TEST_CASE(array_chained_operations) { migraphx::array arr{1, 2, 3}; - + auto result = (arr + 1) * 2 - 1; EXPECT(result[0] == 3); // (1+1)*2-1 = 3 EXPECT(result[1] == 5); // (2+1)*2-1 = 5 @@ -971,7 +971,7 @@ TEST_CASE(array_chained_operations) TEST_CASE(array_const_correctness) { const migraphx::array const_arr{1, 2, 3}; - + // These should all work with const array EXPECT(const_arr.size() == 3); EXPECT(not const_arr.empty()); @@ -981,7 +981,7 @@ TEST_CASE(array_const_correctness) EXPECT(const_arr.data()[0] == 1); EXPECT(const_arr.begin()[0] == 1); EXPECT(const_arr.product() == 6); - + auto applied = const_arr.apply([](int x) { return x * 2; }); EXPECT(applied[0] == 2); } @@ -990,7 +990,7 @@ TEST_CASE(array_const_correctness) TEST_CASE(array_iterator_functionality) { migraphx::array arr{10, 20, 30, 40, 50}; - + // Test forward iteration int expected = 10; for(auto it = arr.begin(); it != arr.end(); ++it) @@ -998,13 +998,13 @@ TEST_CASE(array_iterator_functionality) EXPECT(*it == expected); expected += 10; } - + // Test modifying through iterator for(auto it = arr.begin(); it != arr.end(); ++it) { *it += 1; } - + EXPECT(arr[0] == 11); EXPECT(arr[4] == 51); } @@ -1013,12 +1013,12 @@ TEST_CASE(array_iterator_functionality) TEST_CASE(array_bool_type) { migraphx::array bool_arr{true, false, true, false}; - + EXPECT(bool_arr[0] == true); EXPECT(bool_arr[1] == false); EXPECT(bool_arr[2] == true); EXPECT(bool_arr[3] == false); - + bool_arr[1] = true; EXPECT(bool_arr[1] == true); } @@ -1029,11 +1029,11 @@ TEST_CASE(array_bool_type) TEST_CASE(array_apply_function) { migraphx::array arr{1, 2, 3}; - + // Test with simple lambda auto doubler = migraphx::array_apply([](int x) { return x * 2; }); auto doubled = doubler(arr); - + EXPECT(doubled[0] == 2); EXPECT(doubled[1] == 4); EXPECT(doubled[2] == 6); @@ -1043,10 +1043,10 @@ TEST_CASE(array_apply_function) TEST_CASE(array_apply_function_type_conversion) { migraphx::array int_arr{1, 2, 3}; - + auto int_to_float = migraphx::array_apply([](int x) { return float(x) + 0.5f; }); auto float_result = int_to_float(int_arr); - + EXPECT(migraphx::float_equal(float_result[0], 1.5f)); EXPECT(migraphx::float_equal(float_result[1], 2.5f)); EXPECT(migraphx::float_equal(float_result[2], 3.5f)); @@ -1056,10 +1056,10 @@ TEST_CASE(array_apply_function_type_conversion) TEST_CASE(array_apply_complex_operation) { migraphx::array arr{1, 2, 3, 4}; - + auto square_plus_one = migraphx::array_apply([](int x) { return x * x + 1; }); - auto result = square_plus_one(arr); - + auto result = square_plus_one(arr); + EXPECT(result[0] == 2); // 1*1 + 1 = 2 EXPECT(result[1] == 5); // 2*2 + 1 = 5 EXPECT(result[2] == 10); // 3*3 + 1 = 10 @@ -1070,7 +1070,7 @@ TEST_CASE(array_apply_complex_operation) TEST_CASE(make_array_function) { auto arr = migraphx::make_array(1, 2, 3, 4); - + EXPECT(arr.size() == 4); EXPECT(arr[0] == 1); EXPECT(arr[1] == 2); @@ -1082,19 +1082,19 @@ TEST_CASE(make_array_function) TEST_CASE(make_array_type_conversion) { auto arr = migraphx::make_array(1, 2.5, 3, 4.7); - + EXPECT(arr.size() == 4); EXPECT(arr[0] == 1); - EXPECT(arr[1] == 2); // Should be cast to int + EXPECT(arr[1] == 2); // Should be cast to int EXPECT(arr[2] == 3); - EXPECT(arr[3] == 4); // Should be cast to int + EXPECT(arr[3] == 4); // Should be cast to int } // Test make_array with single element TEST_CASE(make_array_single_element) { auto arr = migraphx::make_array(42); - + EXPECT(arr.size() == 1); EXPECT(arr[0] == 42); } @@ -1103,7 +1103,7 @@ TEST_CASE(make_array_single_element) TEST_CASE(make_array_mixed_types) { auto arr = migraphx::make_array(1.0, 2, 3.5f); - + EXPECT(arr.size() == 3); EXPECT(migraphx::float_equal(arr[0], 1.0)); EXPECT(migraphx::float_equal(arr[1], 2.0)); @@ -1114,7 +1114,7 @@ TEST_CASE(make_array_mixed_types) TEST_CASE(integral_const_array_basic) { migraphx::integral_const_array const_arr; - + EXPECT(const_arr.size() == 3); EXPECT(const_arr[0] == 1); EXPECT(const_arr[1] == 2); @@ -1126,7 +1126,7 @@ TEST_CASE(integral_const_array_base) { migraphx::integral_const_array const_arr; auto base_arr = const_arr.base(); - + EXPECT(base_arr.size() == 3); EXPECT(base_arr[0] == 5); EXPECT(base_arr[1] == 10); @@ -1136,31 +1136,33 @@ TEST_CASE(integral_const_array_base) // Test generate_array function TEST_CASE(generate_array_function) { - auto arr = migraphx::generate_array(migraphx::_c<4>, [](auto i) { return static_cast(i * 2); }); - + auto arr = migraphx::generate_array(migraphx::_c<4>, + [](auto i) { return static_cast(i * 2); }); + EXPECT(arr.size() == 4); - EXPECT(arr[0] == 0); // 0 * 2 = 0 - EXPECT(arr[1] == 2); // 1 * 2 = 2 - EXPECT(arr[2] == 4); // 2 * 2 = 4 - EXPECT(arr[3] == 6); // 3 * 2 = 6 + EXPECT(arr[0] == 0); // 0 * 2 = 0 + EXPECT(arr[1] == 2); // 1 * 2 = 2 + EXPECT(arr[2] == 4); // 2 * 2 = 4 + EXPECT(arr[3] == 6); // 3 * 2 = 6 } // Test generate_array with more complex generator TEST_CASE(generate_array_complex_generator) { - auto arr = migraphx::generate_array(migraphx::_c<3>, [](auto i) { return static_cast((i + 1) * (i + 1)); }); - + auto arr = migraphx::generate_array( + migraphx::_c<3>, [](auto i) { return static_cast((i + 1) * (i + 1)); }); + EXPECT(arr.size() == 3); - EXPECT(arr[0] == 1); // (0+1)^2 = 1 - EXPECT(arr[1] == 4); // (1+1)^2 = 4 - EXPECT(arr[2] == 9); // (2+1)^2 = 9 + EXPECT(arr[0] == 1); // (0+1)^2 = 1 + EXPECT(arr[1] == 4); // (1+1)^2 = 4 + EXPECT(arr[2] == 9); // (2+1)^2 = 9 } // Test generate_array with single element TEST_CASE(generate_array_single_element) { auto arr = migraphx::generate_array(migraphx::_c<1>, [](auto /* i */) { return 42; }); - + EXPECT(arr.size() == 1); EXPECT(arr[0] == 42); } @@ -1169,11 +1171,11 @@ TEST_CASE(generate_array_single_element) TEST_CASE(unpack_function) { migraphx::integral_const_array const_arr; - + auto result = migraphx::unpack(const_arr, [](auto... values) { return (values + ...); // C++17 fold expression to sum all values }); - + EXPECT(result == 6); // 1 + 2 + 3 = 6 } @@ -1181,11 +1183,11 @@ TEST_CASE(unpack_function) TEST_CASE(unpack_product) { migraphx::integral_const_array const_arr; - + auto result = migraphx::unpack(const_arr, [](auto... values) { return (values * ...); // Product of all values }); - + EXPECT(result == 24); // 2 * 3 * 4 = 24 } @@ -1193,11 +1195,9 @@ TEST_CASE(unpack_product) TEST_CASE(unpack_single_value) { migraphx::integral_const_array const_arr; - - auto result = migraphx::unpack(const_arr, [](auto value) { - return value * 2; - }); - + + auto result = migraphx::unpack(const_arr, [](auto value) { return value * 2; }); + EXPECT(result == 84); } @@ -1205,9 +1205,9 @@ TEST_CASE(unpack_single_value) TEST_CASE(transform_single_array) { migraphx::integral_const_array const_arr; - + auto transformed = migraphx::transform(const_arr, [](auto x) { return x * 2; }); - + EXPECT(transformed.size() == 3); EXPECT(transformed[0] == 2); EXPECT(transformed[1] == 4); @@ -1218,9 +1218,9 @@ TEST_CASE(transform_single_array) TEST_CASE(transform_square) { migraphx::integral_const_array const_arr; - + auto squared = migraphx::transform(const_arr, [](auto x) { return x * x; }); - + EXPECT(squared.size() == 4); EXPECT(squared[0] == 1); EXPECT(squared[1] == 4); @@ -1232,11 +1232,10 @@ TEST_CASE(transform_square) TEST_CASE(transform_i_function) { migraphx::integral_const_array const_arr; - - auto transformed = migraphx::transform_i(const_arr, [](auto value, auto index) { - return value + index; - }); - + + auto transformed = + migraphx::transform_i(const_arr, [](auto value, auto index) { return value + index; }); + EXPECT(transformed.size() == 3); EXPECT(transformed[0] == 10); // 10 + 0 = 10 EXPECT(transformed[1] == 21); // 20 + 1 = 21 @@ -1247,11 +1246,10 @@ TEST_CASE(transform_i_function) TEST_CASE(transform_i_multiply_index) { migraphx::integral_const_array const_arr; - - auto transformed = migraphx::transform_i(const_arr, [](auto value, auto index) { - return value * (index + 1); - }); - + + auto transformed = migraphx::transform_i( + const_arr, [](auto value, auto index) { return value * (index + 1); }); + EXPECT(transformed.size() == 3); EXPECT(transformed[0] == 5); // 5 * (0+1) = 5 EXPECT(transformed[1] == 12); // 6 * (1+1) = 12 @@ -1263,9 +1261,9 @@ TEST_CASE(transform_two_arrays) { migraphx::integral_const_array arr1; migraphx::integral_const_array arr2; - + auto result = migraphx::transform(arr1, arr2, [](auto x, auto y) { return x + y; }); - + EXPECT(result.size() == 3); EXPECT(result[0] == 5); // 1 + 4 = 5 EXPECT(result[1] == 7); // 2 + 5 = 7 @@ -1277,9 +1275,9 @@ TEST_CASE(transform_two_arrays_multiply) { migraphx::integral_const_array arr1; migraphx::integral_const_array arr2; - + auto result = migraphx::transform(arr1, arr2, [](auto x, auto y) { return x * y; }); - + EXPECT(result.size() == 3); EXPECT(result[0] == 10); // 2 * 5 = 10 EXPECT(result[1] == 18); // 3 * 6 = 18 @@ -1290,7 +1288,7 @@ TEST_CASE(transform_two_arrays_multiply) TEST_CASE(index_ints_type_alias) { migraphx::index_ints<1, 2, 3, 4> indices; - + EXPECT(indices.size() == 4); EXPECT(indices[0] == 1); EXPECT(indices[1] == 2); @@ -1305,7 +1303,7 @@ TEST_CASE(utility_functions_edge_cases) migraphx::integral_const_array single; auto transformed_single = migraphx::transform(single, [](auto x) { return x * 2; }); EXPECT(transformed_single[0] == 84); - + // Test with zero values migraphx::integral_const_array zeros; auto transformed_zeros = migraphx::transform(zeros, [](auto x) { return x + 1; }); @@ -1319,14 +1317,14 @@ TEST_CASE(function_composition_complex) { // Create initial array auto initial = migraphx::make_array(1, 2, 3); - + // Apply multiple transformations auto applier1 = migraphx::array_apply([](int x) { return x * 2; }); auto applier2 = migraphx::array_apply([](int x) { return x + 1; }); - - auto step1 = applier1(initial); + + auto step1 = applier1(initial); auto final_result = applier2(step1); - + EXPECT(final_result[0] == 3); // (1*2)+1 = 3 EXPECT(final_result[1] == 5); // (2*2)+1 = 5 EXPECT(final_result[2] == 7); // (3*2)+1 = 7 @@ -1336,9 +1334,9 @@ TEST_CASE(function_composition_complex) TEST_CASE(type_safety_consistency) { // Ensure make_array preserves type correctly - auto int_arr = migraphx::make_array(1, 2, 3); + auto int_arr = migraphx::make_array(1, 2, 3); auto float_arr = migraphx::make_array(1.0f, 2.0f, 3.0f); - + // Test that the values are correct regardless of exact type implementation EXPECT(int_arr[0] == 1); EXPECT(migraphx::float_equal(float_arr[0], 1.0f)); From 83729a78eaa77e0cc07b42a3f473e355d86c32bd Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 29 Aug 2025 20:45:50 +0000 Subject: [PATCH 13/20] Add shape tests --- src/targets/gpu/kernels/include/migraphx/kernels/array.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp index 623d4d8ddbd..0551b6f0282 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp @@ -128,7 +128,7 @@ struct array template {} and ...))> - constexpr array(Ts... xs) : d{xs...} + constexpr array(Ts... xs) : d{static_cast(xs)...} { } From 8995591830f701c5831a3cc7a5b2524498eed6a4 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 30 Aug 2025 00:24:27 +0000 Subject: [PATCH 14/20] Update standard shape calculation --- .../include/migraphx/kernels/shape.hpp | 54 +++++++++++++++++-- .../kernels/include/migraphx/kernels/test.hpp | 6 +-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp index 4e80ff2cc22..3efd80a564c 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp @@ -68,13 +68,57 @@ struct shape : equality_comparable> } constexpr auto skips() const { - return return_c([] { - auto lstrides = Strides{}; - return none_of(lstrides.begin(), lstrides.end(), [](auto x) { return x == 1; }); - }); + if constexpr(decltype(this->elements()){} == 1) { + return false_type{}; + } + else { + return return_c([] { + auto lstrides = Strides{}; + return none_of(lstrides.begin(), lstrides.end(), [](auto x) { return x == 1; }); + }); + } } - constexpr auto standard() const { return packed() and not transposed(); } + constexpr auto standard() const + { + if constexpr(decltype(this->elements()){} == 1) { + return true_type{}; + } + else { + return return_c([] { + constexpr auto n = decltype(this->elements()){}; + struct state { + bool ok = true; + index_int expected = decltype(n){}; + }; + auto reduce = [](state acc, array x) -> state { + index_int len = x[0]; + index_int stride = x[1]; + if(not acc.ok) + return acc; + if(len == 1) + return acc; + if (acc.expected % len != 0) + return {false}; + acc.expected /= len; + if(stride != acc.expected) + return {false}; + return acc; + }; + auto ldims = Lens{}; + auto lstrides = Strides{}; + return inner_product( + ldims.begin(), + ldims.end(), + lstrides.begin(), + state{}, + reduce, + MIGRAPHX_LIFT(make_array)) + .ok; + }); + } + + } constexpr index_int index(index_array x) const { return x.dot(strides); } diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index 57a8195d435..bf93b780220 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -248,9 +248,9 @@ struct test_manager { if(threadIdx.x == 0) { - println_once(func); - println_once(file, ":", line, ":"); - println_once(" FAILED: ", msg, " [ ", x, " ]"); + migraphx::cout() << func << '\n'; + migraphx::cout() << file << ':' << line << ':' << '\n'; + migraphx::cout() << " FAILED: " << msg << " [ " << x << " ]" << '\n'; report_failure(); } f(); From c9c886c01bcfe81292091df86cfcd57003a56e16 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 30 Aug 2025 00:24:31 +0000 Subject: [PATCH 15/20] Format --- .../include/migraphx/kernels/shape.hpp | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp index 3efd80a564c..d5dc2a7adec 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp @@ -68,10 +68,12 @@ struct shape : equality_comparable> } constexpr auto skips() const { - if constexpr(decltype(this->elements()){} == 1) { + if constexpr(decltype(this->elements()){} == 1) + { return false_type{}; } - else { + else + { return return_c([] { auto lstrides = Strides{}; return none_of(lstrides.begin(), lstrides.end(), [](auto x) { return x == 1; }); @@ -81,14 +83,17 @@ struct shape : equality_comparable> constexpr auto standard() const { - if constexpr(decltype(this->elements()){} == 1) { + if constexpr(decltype(this->elements()){} == 1) + { return true_type{}; } - else { + else + { return return_c([] { constexpr auto n = decltype(this->elements()){}; - struct state { - bool ok = true; + struct state + { + bool ok = true; index_int expected = decltype(n){}; }; auto reduce = [](state acc, array x) -> state { @@ -98,26 +103,24 @@ struct shape : equality_comparable> return acc; if(len == 1) return acc; - if (acc.expected % len != 0) + if(acc.expected % len != 0) return {false}; acc.expected /= len; if(stride != acc.expected) return {false}; return acc; }; - auto ldims = Lens{}; + auto ldims = Lens{}; auto lstrides = Strides{}; - return inner_product( - ldims.begin(), - ldims.end(), - lstrides.begin(), - state{}, - reduce, - MIGRAPHX_LIFT(make_array)) + return inner_product(ldims.begin(), + ldims.end(), + lstrides.begin(), + state{}, + reduce, + MIGRAPHX_LIFT(make_array)) .ok; - }); + }); } - } constexpr index_int index(index_array x) const { return x.dot(strides); } From 57d61b5fc8ad2d22c555526dab186d73c0bc2095 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 9 Sep 2025 13:56:49 +0000 Subject: [PATCH 16/20] Fix null --- src/targets/gpu/kernels/include/migraphx/kernels/test.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index bf93b780220..a5f4bbad019 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -187,7 +187,7 @@ struct lhs_expression friend constexpr Stream& operator<<(Stream& s, const lhs_expression& self) { const char* op = Operator::as_string(); - if(op != nullptr or *op != '\0') + if(op != nullptr and *op != '\0') s << Operator::as_string() << " "; print_stream(s, self.lhs); return s; From fdbad614f469942119d7314bff1b5d32cd80d95b Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 9 Sep 2025 16:50:11 +0000 Subject: [PATCH 17/20] Fix tidy warnings --- .../gpu/kernels/include/migraphx/kernels/array.hpp | 9 ++++----- .../gpu/kernels/include/migraphx/kernels/shape.hpp | 5 +---- .../gpu/kernels/include/migraphx/kernels/test.hpp | 9 +++++++-- .../gpu/kernels/include/migraphx/kernels/type_traits.hpp | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp index 0551b6f0282..14637398690 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -122,7 +123,7 @@ template struct array { using value_type = T; - T d[N]; + T d[N] = {{0}}; constexpr array() = default; @@ -135,8 +136,7 @@ struct array template {} and (N > 1))> constexpr explicit array(U x) { - for(index_int i = 0; i < N; i++) - d[i] = x; + fill(this->begin(), this->end(), x); } constexpr T& operator[](index_int i) @@ -195,8 +195,7 @@ struct array constexpr auto apply(F f) const { array result; - for(index_int i = 0; i < N; i++) - result[i] = f(d[i]); + transform(this->begin(), this->end(), result.begin(), f); return result; } diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp index d5dc2a7adec..ed6a334a1ce 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp @@ -132,10 +132,7 @@ struct shape : equality_comparable> MIGRAPHX_ASSERT(i >= elements() or i == compute_index(i)); return i; } - else - { - return compute_index(i); - } + return compute_index(i); } constexpr index_int compute_index(index_int i) const diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index a5f4bbad019..5d5c7b0b116 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -236,7 +236,7 @@ struct test_manager { int32_t* failures = nullptr; - __device__ void report_failure() { (*failures)++; } + __device__ void report_failure() const { (*failures)++; } template __device__ void @@ -276,8 +276,13 @@ struct test_manager } } +#ifdef CPPCHECK +// NOLINTNEXTLINE +#define TEST_CAPTURE(...) __VA_ARGS__ +#else // NOLINTNEXTLINE #define TEST_CAPTURE(...) migraphx::test::capture{}->*__VA_ARGS__ +#endif #ifdef _WIN32 // NOLINTNEXTLINE @@ -303,7 +308,7 @@ struct test_manager // NOLINTNEXTLINE #define TEST_CASE(...) \ - __device__ void __VA_ARGS__( \ + __device__ [[maybe_unused]] static void __VA_ARGS__( \ [[maybe_unused]] migraphx::test::test_manager& migraphx_private_test_manager) } // namespace test diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/type_traits.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/type_traits.hpp index 5b5776cb06a..55924018a8c 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/type_traits.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/type_traits.hpp @@ -262,7 +262,7 @@ constexpr T numeric_max() return __FLT_MAX__; else if constexpr(is_same{}) return __FLT16_MAX__; - else if constexpr(is_same{}) + else if constexpr(is_same{}) // cppcheck-suppress UnnecessaryElseStatement { unsigned short us = 0x7f7f; // Max +ve number encoding in BF16 return __builtin_bit_cast(T, us); From 7884aaaa6012f3b2a871706d155b992c7607f22b Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 9 Sep 2025 16:50:17 +0000 Subject: [PATCH 18/20] format --- src/targets/gpu/kernels/include/migraphx/kernels/array.hpp | 2 +- src/targets/gpu/kernels/include/migraphx/kernels/test.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp index 14637398690..f22ec1f4b11 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/array.hpp @@ -123,7 +123,7 @@ template struct array { using value_type = T; - T d[N] = {{0}}; + T d[N] = {{0}}; constexpr array() = default; diff --git a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp index 5d5c7b0b116..5c617cef83c 100644 --- a/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp +++ b/src/targets/gpu/kernels/include/migraphx/kernels/test.hpp @@ -307,7 +307,7 @@ struct test_manager &migraphx::test::fail) // NOLINTNEXTLINE -#define TEST_CASE(...) \ +#define TEST_CASE(...) \ __device__ [[maybe_unused]] static void __VA_ARGS__( \ [[maybe_unused]] migraphx::test::test_manager& migraphx_private_test_manager) From f89a512c05e265480eb23a426619f1cad2f71e04 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 9 Oct 2025 16:20:36 -0700 Subject: [PATCH 19/20] Format --- src/include/migraphx/operation.hpp | 19 +++++++++++-------- src/include/migraphx/pass.hpp | 5 +++-- src/simplify_reshapes.cpp | 7 +++---- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/include/migraphx/operation.hpp b/src/include/migraphx/operation.hpp index 86fbe6ecd98..317e1e94340 100644 --- a/src/include/migraphx/operation.hpp +++ b/src/include/migraphx/operation.hpp @@ -130,8 +130,9 @@ auto operator==(const T& x, const U& y) -> decltype(x.name() == y.name()) } // namespace operation_operators template -auto compute_shape_op(rank<3>, const T& x, const std::vector& inputs) - -> decltype(x.compute_shape(inputs)) +auto compute_shape_op(rank<3>, + const T& x, + const std::vector& inputs) -> decltype(x.compute_shape(inputs)) { return x.compute_shape(inputs); } @@ -148,8 +149,9 @@ auto compute_shape_op(rank<2>, const T& x, const std::vector& inputs) } template -auto compute_shape_op(rank<1>, const T& x, const std::vector& inputs) - -> decltype(x.compute_shape(inputs, {})) +auto compute_shape_op(rank<1>, + const T& x, + const std::vector& inputs) -> decltype(x.compute_shape(inputs, {})) { return x.compute_shape(inputs, {}); } @@ -386,8 +388,9 @@ auto is_context_free_op(rank<0>, const T&, const shape&, const std::vector std::false_type; template -auto is_context_free_op(const T& x) -> decltype(is_context_free_op( - rank<1>{}, x, std::declval(), std::declval>())) +auto is_context_free_op(const T& x) + -> decltype(is_context_free_op( + rank<1>{}, x, std::declval(), std::declval>())) { return {}; } @@ -1427,8 +1430,8 @@ inline shape compute_shape(const operation& op, const std::vector& inputs } template -inline auto compute_shape(const T& op, const std::vector& inputs) - -> decltype(op.compute_shape(inputs)) +inline auto compute_shape(const T& op, + const std::vector& inputs) -> decltype(op.compute_shape(inputs)) { return op.compute_shape(inputs); } diff --git a/src/include/migraphx/pass.hpp b/src/include/migraphx/pass.hpp index 8efe5f5dea1..493abebd407 100644 --- a/src/include/migraphx/pass.hpp +++ b/src/include/migraphx/pass.hpp @@ -62,8 +62,9 @@ MIGRAPHX_EXPORT module& get_module(module_pass_manager& mpm); namespace detail { template -auto module_pass_manager_apply(rank<1>, const T& x, module_pass_manager& mpm) - -> decltype(x.apply(get_module(mpm))) +auto module_pass_manager_apply(rank<1>, + const T& x, + module_pass_manager& mpm) -> decltype(x.apply(get_module(mpm))) { return x.apply(get_module(mpm)); } diff --git a/src/simplify_reshapes.cpp b/src/simplify_reshapes.cpp index b98b51b74ce..d1c724aa282 100644 --- a/src/simplify_reshapes.cpp +++ b/src/simplify_reshapes.cpp @@ -159,10 +159,9 @@ struct find_op_shape_transform_op auto matcher() const { - auto reshapes = match::name(shape_transform_ops()); - auto match_op = match::any_of(match::reduce(), match::pointwise()); - auto x_op = - match_op(match::none_of(fusable_split())); + auto reshapes = match::name(shape_transform_ops()); + auto match_op = match::any_of(match::reduce(), match::pointwise()); + auto x_op = match_op(match::none_of(fusable_split())); auto reshapes_x_op = reshapes(match::arg(0)(match::skip(reshapes())(x_op.bind("x")))); return match_op(match::any_of[match::inputs()](reshapes_x_op.bind("input"))); } From 7a2584d4aaebf971a3d9244fabddf2e748d874bc Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 10 Oct 2025 05:58:24 -0700 Subject: [PATCH 20/20] Add interface keyword --- src/targets/gpu/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/targets/gpu/CMakeLists.txt b/src/targets/gpu/CMakeLists.txt index c14fb5a0a5a..ee725b1d638 100644 --- a/src/targets/gpu/CMakeLists.txt +++ b/src/targets/gpu/CMakeLists.txt @@ -114,7 +114,7 @@ target_compile_definitions(compile_migraphx_gpu_kernels INTERFACE -DMIGRAPHX_WAV target_include_directories(compile_migraphx_gpu_kernels INTERFACE $) target_link_libraries(compile_migraphx_gpu_kernels INTERFACE compile_for_gpu) if(MIGRAPHX_USE_COMPOSABLEKERNEL) - target_link_libraries(compile_migraphx_gpu_kernels composable_kernel::jit_library) + target_link_libraries(compile_migraphx_gpu_kernels INTERFACE composable_kernel::jit_library) endif() add_library(migraphx_gpu_kernel_file_check EXCLUDE_FROM_ALL)