From 32c7346e3071add399cfe81b03bebf0f9c54b730 Mon Sep 17 00:00:00 2001 From: Jiacheng Huang Date: Fri, 3 Jul 2026 13:09:52 +0800 Subject: [PATCH] Add platform-adaptive runtime tests --- src/native/cambricon/runtime_.h | 12 +- tests/CMakeLists.txt | 161 ++++++++++++++++++++++++-- tests/install_consumer_smoke.cc | 60 ++++++---- tests/test_cpu_runtime.cc | 87 -------------- tests/test_native_runtime.cc | 193 ++++++++++++++++++++++++++++++++ tests/test_nvidia_runtime.cc | 93 --------------- tests/test_runtime_dispatch.cc | 178 +++++++++++++++-------------- 7 files changed, 485 insertions(+), 299 deletions(-) delete mode 100644 tests/test_cpu_runtime.cc create mode 100644 tests/test_native_runtime.cc delete mode 100644 tests/test_nvidia_runtime.cc diff --git a/src/native/cambricon/runtime_.h b/src/native/cambricon/runtime_.h index 927e2c5..d655cd9 100644 --- a/src/native/cambricon/runtime_.h +++ b/src/native/cambricon/runtime_.h @@ -5,6 +5,7 @@ #include #include +#include #include "native/cambricon/device_.h" #include "runtime.h" @@ -20,7 +21,11 @@ struct Runtime static constexpr Device::Type kDeviceType = Device::Type::kCambricon; +#ifdef CNRT_RET_SUCCESS static constexpr Error kSuccess = CNRT_RET_SUCCESS; +#else + static constexpr Error kSuccess = cnrtSuccess; +#endif static constexpr auto SetDevice = cnrtSetDevice; @@ -48,7 +53,12 @@ struct Runtime static constexpr auto MemcpyAsync = [](void* dst, const void* src, std::size_t size, auto kind, Stream stream) { - return cnrtMemcpyAsync(dst, const_cast(src), size, kind, stream); + if constexpr (std::is_invocable_v) { + return cnrtMemcpyAsync(dst, const_cast(src), size, kind, stream); + } else { + return cnrtMemcpyAsync(dst, const_cast(src), size, stream, kind); + } }; static constexpr auto kMemcpyHostToHost = cnrtMemcpyHostToHost; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f24954c..88b3fc0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,11 +4,82 @@ function(add_infini_rt_test target) add_test(NAME ${target} COMMAND ${target}) endfunction() +function(add_infini_rt_backend_runtime_test backend device_type runtime_header + expect_async_memcpy_success) + string(TOLOWER "${backend}" backend_lower) + set(target "test_${backend_lower}_runtime") + add_infini_rt_test(${target} test_native_runtime.cc) + target_compile_definitions(${target} + PRIVATE + "INFINI_RT_TEST_BACKEND_NAME=\"${backend}\"" + "INFINI_RT_TEST_DEVICE_TYPE=${device_type}" + "INFINI_RT_TEST_RUNTIME_HEADER=\"${runtime_header}\"" + "INFINI_RT_TEST_EXPECT_ASYNC_MEMCPY_SUCCESS=${expect_async_memcpy_success}") +endfunction() + add_infini_rt_test(test_smoke test_smoke.cc) add_infini_rt_test(test_core test_core.cc) -if(WITH_CPU OR WITH_NVIDIA) +set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND OFF) + +if(WITH_CPU) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + CPU infini::rt::Device::Type::kCpu infini/rt/cpu/runtime_.h 0) +endif() + +if(WITH_NVIDIA) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + NVIDIA infini::rt::Device::Type::kNvidia + infini/rt/nvidia/runtime_.h 1) +endif() + +if(WITH_ILUVATAR) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + ILUVATAR infini::rt::Device::Type::kIluvatar + infini/rt/iluvatar/runtime_.h 1) +endif() + +if(WITH_HYGON) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + HYGON infini::rt::Device::Type::kHygon + infini/rt/hygon/runtime_.h 1) +endif() + +if(WITH_METAX) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + METAX infini::rt::Device::Type::kMetax + infini/rt/metax/runtime_.h 1) +endif() + +if(WITH_MOORE) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + MOORE infini::rt::Device::Type::kMoore + infini/rt/moore/runtime_.h 1) +endif() + +if(WITH_CAMBRICON) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + CAMBRICON infini::rt::Device::Type::kCambricon + infini/rt/cambricon/runtime_.h 1) +endif() + +if(WITH_ASCEND) + set(INFINI_RT_TEST_HAS_RUNTIME_BACKEND ON) + add_infini_rt_backend_runtime_test( + ASCEND infini::rt::Device::Type::kAscend + infini/rt/ascend/runtime_.h 1) +endif() + +if(INFINI_RT_TEST_HAS_RUNTIME_BACKEND) add_infini_rt_test(test_runtime_dispatch test_runtime_dispatch.cc) + if(WITH_CPU) target_compile_definitions(test_runtime_dispatch PRIVATE INFINI_RT_TEST_WITH_CPU=1) @@ -17,14 +88,30 @@ if(WITH_CPU OR WITH_NVIDIA) target_compile_definitions(test_runtime_dispatch PRIVATE INFINI_RT_TEST_WITH_NVIDIA=1) endif() -endif() - -if(WITH_CPU) - add_infini_rt_test(test_cpu_runtime test_cpu_runtime.cc) -endif() - -if(WITH_NVIDIA) - add_infini_rt_test(test_nvidia_runtime test_nvidia_runtime.cc) + if(WITH_ILUVATAR) + target_compile_definitions(test_runtime_dispatch + PRIVATE INFINI_RT_TEST_WITH_ILUVATAR=1) + endif() + if(WITH_HYGON) + target_compile_definitions(test_runtime_dispatch + PRIVATE INFINI_RT_TEST_WITH_HYGON=1) + endif() + if(WITH_METAX) + target_compile_definitions(test_runtime_dispatch + PRIVATE INFINI_RT_TEST_WITH_METAX=1) + endif() + if(WITH_MOORE) + target_compile_definitions(test_runtime_dispatch + PRIVATE INFINI_RT_TEST_WITH_MOORE=1) + endif() + if(WITH_CAMBRICON) + target_compile_definitions(test_runtime_dispatch + PRIVATE INFINI_RT_TEST_WITH_CAMBRICON=1) + endif() + if(WITH_ASCEND) + target_compile_definitions(test_runtime_dispatch + PRIVATE INFINI_RT_TEST_WITH_ASCEND=1) + endif() endif() set(INFINI_RT_TEST_INSTALL_PREFIX @@ -35,8 +122,7 @@ set(INFINI_RT_TEST_EXTRA_LIBRARY_DIRS "") set(INFINI_RT_TEST_EXTRA_INCLUDE_DIRS "") set(INFINI_RT_TEST_CONSUMER_BACKEND NONE) -if(WITH_NVIDIA) - set(INFINI_RT_TEST_CONSUMER_BACKEND NVIDIA) +if(WITH_NVIDIA OR WITH_ILUVATAR OR WITH_HYGON) if(CUDAToolkit_INCLUDE_DIRS) list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIRS}) @@ -44,6 +130,59 @@ if(WITH_NVIDIA) list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) endif() + + if(CUDAToolkit_LIBRARY_DIR) + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${CUDAToolkit_LIBRARY_DIR}") + endif() + if(CUDAToolkit_TARGET_DIR) + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${CUDAToolkit_TARGET_DIR}/lib64") + endif() + if(CUDAToolkit_ROOT_DIR) + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${CUDAToolkit_ROOT_DIR}/lib64") + endif() +endif() + +if(WITH_NVIDIA) + set(INFINI_RT_TEST_CONSUMER_BACKEND NVIDIA) +elseif(WITH_ILUVATAR) + set(INFINI_RT_TEST_CONSUMER_BACKEND ILUVATAR) +elseif(WITH_HYGON) + set(INFINI_RT_TEST_CONSUMER_BACKEND HYGON) + if(HYGON_CUDA_ROOT) + list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS + "${HYGON_CUDA_ROOT}/include") + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${HYGON_CUDA_ROOT}/lib64") + endif() +elseif(WITH_METAX) + set(INFINI_RT_TEST_CONSUMER_BACKEND METAX) + list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS + "${MACA_PATH}/include") + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${MACA_PATH}/lib") +elseif(WITH_MOORE) + set(INFINI_RT_TEST_CONSUMER_BACKEND MOORE) + list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS + "${MUSA_ROOT}/include") + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${MUSA_ROOT}/lib") +elseif(WITH_CAMBRICON) + set(INFINI_RT_TEST_CONSUMER_BACKEND CAMBRICON) + list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS + "${NEUWARE_HOME}/include") + list(APPEND INFINI_RT_TEST_EXTRA_LIBRARY_DIRS + "${NEUWARE_HOME}/lib" + "${NEUWARE_HOME}/lib64") +elseif(WITH_ASCEND) + # The install-consumer smoke checks Ascend public headers and linkage. + # Runtime behavior is covered by test_ascend_runtime and dispatch tests. + list(APPEND INFINI_RT_TEST_EXTRA_INCLUDE_DIRS + "${ASCEND_HOME}/include" + "${ASCEND_HOME}/include/aclnn" + "${ASCEND_HOME}/include/aclnnop") elseif(WITH_CPU) set(INFINI_RT_TEST_CONSUMER_BACKEND CPU) endif() diff --git a/tests/install_consumer_smoke.cc b/tests/install_consumer_smoke.cc index 0684763..6b72130 100644 --- a/tests/install_consumer_smoke.cc +++ b/tests/install_consumer_smoke.cc @@ -19,13 +19,39 @@ int main() { return 1; } -#if defined(INFINI_RT_CONSUMER_BACKEND_CPU) || \ - defined(INFINI_RT_CONSUMER_BACKEND_NVIDIA) +#if defined(INFINI_RT_CONSUMER_BACKEND_CPU) || \ + defined(INFINI_RT_CONSUMER_BACKEND_NVIDIA) || \ + defined(INFINI_RT_CONSUMER_BACKEND_ILUVATAR) || \ + defined(INFINI_RT_CONSUMER_BACKEND_HYGON) || \ + defined(INFINI_RT_CONSUMER_BACKEND_METAX) || \ + defined(INFINI_RT_CONSUMER_BACKEND_MOORE) || \ + defined(INFINI_RT_CONSUMER_BACKEND_CAMBRICON) || \ + defined(INFINI_RT_CONSUMER_BACKEND_ASCEND) namespace runtime = infini::rt::runtime; #if defined(INFINI_RT_CONSUMER_BACKEND_CPU) constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kCpu; -#else + constexpr bool kExpectAsyncMemcpySuccess = false; +#elif defined(INFINI_RT_CONSUMER_BACKEND_NVIDIA) constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kNvidia; + constexpr bool kExpectAsyncMemcpySuccess = true; +#elif defined(INFINI_RT_CONSUMER_BACKEND_ILUVATAR) + constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kIluvatar; + constexpr bool kExpectAsyncMemcpySuccess = true; +#elif defined(INFINI_RT_CONSUMER_BACKEND_HYGON) + constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kHygon; + constexpr bool kExpectAsyncMemcpySuccess = true; +#elif defined(INFINI_RT_CONSUMER_BACKEND_METAX) + constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kMetax; + constexpr bool kExpectAsyncMemcpySuccess = true; +#elif defined(INFINI_RT_CONSUMER_BACKEND_MOORE) + constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kMoore; + constexpr bool kExpectAsyncMemcpySuccess = true; +#elif defined(INFINI_RT_CONSUMER_BACKEND_CAMBRICON) + constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kCambricon; + constexpr bool kExpectAsyncMemcpySuccess = true; +#elif defined(INFINI_RT_CONSUMER_BACKEND_ASCEND) + constexpr auto kExpectedDeviceType = infini::rt::Device::Type::kAscend; + constexpr bool kExpectAsyncMemcpySuccess = true; #endif infini::rt::set_runtime_device_type(kExpectedDeviceType); if (infini::rt::runtime_device_type() != kExpectedDeviceType) { @@ -35,8 +61,13 @@ int main() { std::array input{1, 2, 3, 4}; std::array output{}; void* ptr = nullptr; + int device_count = 0; + if (runtime::GetDeviceCount(&device_count) != runtime::kSuccess || + device_count <= 0) { + return 0; + } if (runtime::SetDevice(0) != runtime::kSuccess) { - return 1; + return 0; } int current_device = -1; if (runtime::GetDevice(¤t_device) != runtime::kSuccess) { @@ -45,13 +76,6 @@ int main() { if (current_device != 0) { return 1; } - int device_count = 0; - if (runtime::GetDeviceCount(&device_count) != runtime::kSuccess) { - return 1; - } - if (device_count <= 0) { - return 1; - } if (runtime::Malloc(&ptr, input.size()) != runtime::kSuccess) { return 1; } @@ -62,19 +86,15 @@ int main() { runtime::kMemcpyHostToDevice) != runtime::kSuccess) { return 1; } -#if defined(INFINI_RT_CONSUMER_BACKEND_CPU) - if (runtime::MemcpyAsync(ptr, input.data(), input.size(), - runtime::kMemcpyHostToDevice, - nullptr) == runtime::kSuccess) { + runtime::Stream stream{}; + const auto async_status = runtime::MemcpyAsync( + ptr, input.data(), input.size(), runtime::kMemcpyHostToDevice, stream); + if (kExpectAsyncMemcpySuccess && async_status != runtime::kSuccess) { return 1; } -#else - if (runtime::MemcpyAsync(ptr, input.data(), input.size(), - runtime::kMemcpyHostToDevice, - nullptr) != runtime::kSuccess) { + if (!kExpectAsyncMemcpySuccess && async_status == runtime::kSuccess) { return 1; } -#endif if (runtime::DeviceSynchronize() != runtime::kSuccess) { return 1; } diff --git a/tests/test_cpu_runtime.cc b/tests/test_cpu_runtime.cc deleted file mode 100644 index e066c85..0000000 --- a/tests/test_cpu_runtime.cc +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "test_helper.h" - -namespace { - -using CpuRuntime = infini::rt::runtime::Runtime; - -void TestMallocAndFree(infini::rt::test::TestContext* context) { - void* ptr = nullptr; - CpuRuntime::Malloc(&ptr, 16); - - context->Expect(ptr != nullptr, "CPU runtime should allocate memory."); - - CpuRuntime::Free(ptr); -} - -void TestMemcpyRoundTrip(infini::rt::test::TestContext* context) { - std::array input{0, 1, 2, 3, 4, 5, 6, 7}; - std::array output{}; - void* ptr = nullptr; - - CpuRuntime::Malloc(&ptr, input.size()); - context->Expect(ptr != nullptr, "CPU runtime should allocate copy memory."); - if (ptr == nullptr) { - return; - } - - CpuRuntime::Memcpy(ptr, input.data(), input.size(), - CpuRuntime::kMemcpyHostToDevice); - CpuRuntime::Memcpy(output.data(), ptr, output.size(), - CpuRuntime::kMemcpyDeviceToHost); - CpuRuntime::Free(ptr); - - context->ExpectEqual(output, input, - "CPU runtime should copy data through runtime memory."); -} - -void TestMemcpyAsyncUnsupported(infini::rt::test::TestContext* context) { - std::array input{1}; - std::array output{}; - - context->Expect( - CpuRuntime::MemcpyAsync(output.data(), input.data(), input.size(), - CpuRuntime::kMemcpyHostToHost, - nullptr) != CpuRuntime::kSuccess, - "CPU runtime should not report async memcpy success."); -} - -void TestMemset(infini::rt::test::TestContext* context) { - std::array output{}; - void* ptr = nullptr; - - CpuRuntime::Malloc(&ptr, output.size()); - context->Expect(ptr != nullptr, "CPU runtime should allocate memset memory."); - if (ptr == nullptr) { - return; - } - - CpuRuntime::Memset(ptr, 0x5A, output.size()); - CpuRuntime::Memcpy(output.data(), ptr, output.size(), - CpuRuntime::kMemcpyDeviceToHost); - CpuRuntime::Free(ptr); - - for (const auto value : output) { - context->ExpectEqual(value, static_cast(0x5A), - "CPU runtime should fill memory with memset."); - } -} - -} // namespace - -int main() { - infini::rt::test::TestContext context; - - TestMallocAndFree(&context); - TestMemcpyRoundTrip(&context); - TestMemcpyAsyncUnsupported(&context); - TestMemset(&context); - - return context.ExitCode(); -} diff --git a/tests/test_native_runtime.cc b/tests/test_native_runtime.cc new file mode 100644 index 0000000..cdd39cb --- /dev/null +++ b/tests/test_native_runtime.cc @@ -0,0 +1,193 @@ +#include +#include INFINI_RT_TEST_RUNTIME_HEADER + +#include +#include +#include +#include + +#include "test_helper.h" + +namespace { + +using Runtime = infini::rt::runtime::Runtime; + +constexpr bool kExpectAsyncMemcpySuccess = + INFINI_RT_TEST_EXPECT_ASYNC_MEMCPY_SUCCESS != 0; + +void ExpectSuccess(infini::rt::test::TestContext* context, + typename Runtime::Error status, const char* message) { + context->Expect(status == Runtime::kSuccess, message); +} + +void ExpectFailure(infini::rt::test::TestContext* context, + typename Runtime::Error status, const char* message) { + context->Expect(status != Runtime::kSuccess, message); +} + +bool SelectDevice() { + int device_count = 0; + if (Runtime::GetDeviceCount(&device_count) != Runtime::kSuccess || + device_count <= 0) { + std::cout << INFINI_RT_TEST_BACKEND_NAME + << " runtime skipped: no available device." << std::endl; + return false; + } + + if (Runtime::SetDevice(0) != Runtime::kSuccess) { + std::cout << INFINI_RT_TEST_BACKEND_NAME + << " runtime skipped: device 0 is not available." << std::endl; + return false; + } + + return true; +} + +void TestDevice(infini::rt::test::TestContext* context) { + int current_device = -1; + ExpectSuccess(context, Runtime::GetDevice(¤t_device), + INFINI_RT_TEST_BACKEND_NAME + " runtime should get the current device."); + context->ExpectEqual(current_device, 0, + INFINI_RT_TEST_BACKEND_NAME + " runtime should keep the current device."); + + int device_count = 0; + ExpectSuccess(context, Runtime::GetDeviceCount(&device_count), + INFINI_RT_TEST_BACKEND_NAME + " runtime should get the device count."); + context->Expect(device_count > 0, INFINI_RT_TEST_BACKEND_NAME + " runtime should report at least one device."); +} + +void TestMallocAndFree(infini::rt::test::TestContext* context) { + void* ptr = nullptr; + ExpectSuccess(context, Runtime::Malloc(&ptr, 16), + INFINI_RT_TEST_BACKEND_NAME " runtime should allocate memory."); + context->Expect(ptr != nullptr, INFINI_RT_TEST_BACKEND_NAME + " runtime allocation should produce a pointer."); + if (ptr != nullptr) { + ExpectSuccess(context, Runtime::Free(ptr), + INFINI_RT_TEST_BACKEND_NAME " runtime should free memory."); + } +} + +void TestMemcpyRoundTrip(infini::rt::test::TestContext* context) { + std::array input{0, 1, 2, 3, 4, 5, 6, 7}; + std::array output{}; + void* ptr = nullptr; + + ExpectSuccess(context, Runtime::Malloc(&ptr, input.size()), + INFINI_RT_TEST_BACKEND_NAME + " runtime should allocate copy memory."); + if (ptr == nullptr) { + return; + } + + ExpectSuccess(context, + Runtime::Memcpy(ptr, input.data(), input.size(), + Runtime::kMemcpyHostToDevice), + INFINI_RT_TEST_BACKEND_NAME + " runtime should copy host data to runtime memory."); + ExpectSuccess(context, + Runtime::Memcpy(output.data(), ptr, output.size(), + Runtime::kMemcpyDeviceToHost), + INFINI_RT_TEST_BACKEND_NAME + " runtime should copy runtime memory to host."); + ExpectSuccess(context, Runtime::Free(ptr), + INFINI_RT_TEST_BACKEND_NAME + " runtime should free copy memory."); + + context->ExpectEqual(output, input, + INFINI_RT_TEST_BACKEND_NAME + " runtime should preserve copied bytes."); +} + +void TestMemcpyAsync(infini::rt::test::TestContext* context) { + std::array input{8, 9, 10, 11}; + std::array output{}; + void* ptr = nullptr; + + ExpectSuccess(context, Runtime::Malloc(&ptr, input.size()), + INFINI_RT_TEST_BACKEND_NAME + " runtime should allocate async copy memory."); + if (ptr == nullptr) { + return; + } + + typename Runtime::Stream stream{}; + const auto async_status = Runtime::MemcpyAsync( + ptr, input.data(), input.size(), Runtime::kMemcpyHostToDevice, stream); + + if constexpr (kExpectAsyncMemcpySuccess) { + ExpectSuccess(context, async_status, + INFINI_RT_TEST_BACKEND_NAME + " runtime should support async host-to-device copy."); + ExpectSuccess(context, Runtime::DeviceSynchronize(), + INFINI_RT_TEST_BACKEND_NAME + " runtime should synchronize async host-to-device copy."); + ExpectSuccess(context, + Runtime::Memcpy(output.data(), ptr, output.size(), + Runtime::kMemcpyDeviceToHost), + INFINI_RT_TEST_BACKEND_NAME + " runtime should copy async data back to host."); + context->ExpectEqual(output, input, + INFINI_RT_TEST_BACKEND_NAME + " runtime should preserve async copied bytes."); + } else { + ExpectFailure(context, async_status, + INFINI_RT_TEST_BACKEND_NAME + " runtime should not report async memcpy success."); + } + + ExpectSuccess(context, Runtime::Free(ptr), + INFINI_RT_TEST_BACKEND_NAME + " runtime should free async copy memory."); +} + +void TestMemset(infini::rt::test::TestContext* context) { + std::array output{}; + void* ptr = nullptr; + + ExpectSuccess(context, Runtime::Malloc(&ptr, output.size()), + INFINI_RT_TEST_BACKEND_NAME + " runtime should allocate memset memory."); + if (ptr == nullptr) { + return; + } + + ExpectSuccess(context, Runtime::Memset(ptr, 0x5A, output.size()), + INFINI_RT_TEST_BACKEND_NAME " runtime should fill memory."); + ExpectSuccess(context, + Runtime::Memcpy(output.data(), ptr, output.size(), + Runtime::kMemcpyDeviceToHost), + INFINI_RT_TEST_BACKEND_NAME + " runtime should copy filled memory to host."); + ExpectSuccess(context, Runtime::Free(ptr), + INFINI_RT_TEST_BACKEND_NAME + " runtime should free memset memory."); + + for (const auto value : output) { + context->ExpectEqual(value, static_cast(0x5A), + INFINI_RT_TEST_BACKEND_NAME + " runtime should preserve filled bytes."); + } +} + +} // namespace + +int main() { + infini::rt::test::TestContext context; + + if (!SelectDevice()) { + return context.ExitCode(); + } + + TestDevice(&context); + TestMallocAndFree(&context); + TestMemcpyRoundTrip(&context); + TestMemcpyAsync(&context); + TestMemset(&context); + + return context.ExitCode(); +} diff --git a/tests/test_nvidia_runtime.cc b/tests/test_nvidia_runtime.cc deleted file mode 100644 index fa10858..0000000 --- a/tests/test_nvidia_runtime.cc +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "test_helper.h" - -namespace { - -using NvidiaRuntime = - infini::rt::runtime::Runtime; - -void ExpectCudaSuccess(infini::rt::test::TestContext* context, - cudaError_t status, const char* message) { - context->Expect(status == cudaSuccess, message); -} - -void TestMallocAndFree(infini::rt::test::TestContext* context) { - void* ptr = nullptr; - ExpectCudaSuccess(context, NvidiaRuntime::Malloc(&ptr, 16), - "NVIDIA runtime should allocate device memory."); - context->Expect(ptr != nullptr, - "NVIDIA runtime allocation should produce a pointer."); - if (ptr != nullptr) { - ExpectCudaSuccess(context, NvidiaRuntime::Free(ptr), - "NVIDIA runtime should free device memory."); - } -} - -void TestMemcpyRoundTrip(infini::rt::test::TestContext* context) { - std::array input{0, 1, 2, 3, 4, 5, 6, 7}; - std::array output{}; - void* ptr = nullptr; - - ExpectCudaSuccess(context, NvidiaRuntime::Malloc(&ptr, input.size()), - "NVIDIA runtime should allocate copy memory."); - if (ptr == nullptr) { - return; - } - - ExpectCudaSuccess(context, - NvidiaRuntime::Memcpy(ptr, input.data(), input.size(), - NvidiaRuntime::kMemcpyHostToDevice), - "NVIDIA runtime should copy host data to device memory."); - ExpectCudaSuccess(context, - NvidiaRuntime::Memcpy(output.data(), ptr, output.size(), - NvidiaRuntime::kMemcpyDeviceToHost), - "NVIDIA runtime should copy device data to host memory."); - ExpectCudaSuccess(context, NvidiaRuntime::Free(ptr), - "NVIDIA runtime should free copy memory."); - - context->ExpectEqual( - output, input, "NVIDIA runtime should copy data through device memory."); -} - -void TestMemset(infini::rt::test::TestContext* context) { - std::array output{}; - void* ptr = nullptr; - - ExpectCudaSuccess(context, NvidiaRuntime::Malloc(&ptr, output.size()), - "NVIDIA runtime should allocate memset memory."); - if (ptr == nullptr) { - return; - } - - ExpectCudaSuccess(context, NvidiaRuntime::Memset(ptr, 0x5A, output.size()), - "NVIDIA runtime should memset device memory."); - ExpectCudaSuccess(context, - NvidiaRuntime::Memcpy(output.data(), ptr, output.size(), - NvidiaRuntime::kMemcpyDeviceToHost), - "NVIDIA runtime should copy memset data to host memory."); - ExpectCudaSuccess(context, NvidiaRuntime::Free(ptr), - "NVIDIA runtime should free memset memory."); - - for (const auto value : output) { - context->ExpectEqual(value, static_cast(0x5A), - "NVIDIA runtime should fill memory with memset."); - } -} - -} // namespace - -int main() { - infini::rt::test::TestContext context; - - TestMallocAndFree(&context); - TestMemcpyRoundTrip(&context); - TestMemset(&context); - - return context.ExitCode(); -} diff --git a/tests/test_runtime_dispatch.cc b/tests/test_runtime_dispatch.cc index 4d6e15f..3264b98 100644 --- a/tests/test_runtime_dispatch.cc +++ b/tests/test_runtime_dispatch.cc @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include "test_helper.h" @@ -11,135 +14,111 @@ namespace { namespace runtime = infini::rt::runtime; void ExpectSuccess(infini::rt::test::TestContext* context, - runtime::Error status, const char* message) { + runtime::Error status, std::string_view message) { context->Expect(status == runtime::kSuccess, message); } -#if defined(INFINI_RT_TEST_WITH_CPU) -void TestCpuDispatch(infini::rt::test::TestContext* context) { - infini::rt::set_runtime_device_type(infini::rt::Device::Type::kCpu); - context->Expect( - infini::rt::runtime_device_type() == infini::rt::Device::Type::kCpu, - "Runtime dispatch should report CPU dispatch."); +void ExpectFailure(infini::rt::test::TestContext* context, + runtime::Error status, std::string_view message) { + context->Expect(status != runtime::kSuccess, message); +} - std::array input{1, 2, 3, 4}; - std::array output{}; - void* ptr = nullptr; +std::string Message(std::string_view backend_name, std::string_view message) { + return std::string{backend_name} + " dispatch should " + + std::string{message} + "."; +} - ExpectSuccess(context, runtime::SetDevice(0), - "CPU dispatch should set device 0."); - int current_device = -1; - ExpectSuccess(context, runtime::GetDevice(¤t_device), - "CPU dispatch should get the current device."); - context->ExpectEqual(current_device, 0, - "CPU dispatch should keep the current device."); +bool SelectDevice(infini::rt::test::TestContext* context, + infini::rt::Device::Type device_type, + const char* backend_name) { + infini::rt::set_runtime_device_type(device_type); + if (!context->Expect(infini::rt::runtime_device_type() == device_type, + Message(backend_name, "report the selected backend"))) { + return false; + } int device_count = 0; - ExpectSuccess(context, runtime::GetDeviceCount(&device_count), - "CPU dispatch should get the device count."); - context->Expect(device_count > 0, - "CPU dispatch should report at least one device."); - - ExpectSuccess(context, runtime::Malloc(&ptr, input.size()), - "CPU dispatch should allocate memory."); - if (ptr == nullptr) { - return; + if (runtime::GetDeviceCount(&device_count) != runtime::kSuccess || + device_count <= 0) { + std::cout << backend_name << " dispatch skipped: no available device." + << std::endl; + return false; } - ExpectSuccess(context, - runtime::Memcpy(ptr, input.data(), input.size(), - runtime::kMemcpyHostToDevice), - "CPU dispatch should copy host data to runtime memory."); - context->Expect(runtime::MemcpyAsync(ptr, input.data(), input.size(), - runtime::kMemcpyHostToDevice, - nullptr) != runtime::kSuccess, - "CPU dispatch should not report async memcpy success."); - ExpectSuccess(context, - runtime::Memcpy(output.data(), ptr, output.size(), - runtime::kMemcpyDeviceToHost), - "CPU dispatch should copy runtime memory to host."); - - context->ExpectEqual(output, input, - "CPU dispatch should preserve copied bytes."); - - ExpectSuccess(context, runtime::Memset(ptr, 0x5A, output.size()), - "CPU dispatch should fill runtime memory."); - ExpectSuccess(context, - runtime::Memcpy(output.data(), ptr, output.size(), - runtime::kMemcpyDeviceToHost), - "CPU dispatch should copy filled memory to host."); - for (const auto value : output) { - context->ExpectEqual(value, static_cast(0x5A), - "CPU dispatch should preserve filled bytes."); + if (runtime::SetDevice(0) != runtime::kSuccess) { + std::cout << backend_name << " dispatch skipped: device 0 is not available." + << std::endl; + return false; } - ExpectSuccess(context, runtime::Free(ptr), - "CPU dispatch should free memory."); + return true; } -#endif -#if defined(INFINI_RT_TEST_WITH_NVIDIA) -void TestNvidiaDispatch(infini::rt::test::TestContext* context) { - infini::rt::set_runtime_device_type(infini::rt::Device::Type::kNvidia); - context->Expect( - infini::rt::runtime_device_type() == infini::rt::Device::Type::kNvidia, - "Runtime dispatch should report NVIDIA dispatch."); +void TestDispatch(infini::rt::test::TestContext* context, + infini::rt::Device::Type device_type, + const char* backend_name, bool expect_async_memcpy_success) { + if (!SelectDevice(context, device_type, backend_name)) { + return; + } - std::array input{5, 6, 7, 8}; + std::array input{1, 2, 3, 4}; std::array output{}; void* ptr = nullptr; - ExpectSuccess(context, runtime::SetDevice(0), - "NVIDIA dispatch should set device 0."); int current_device = -1; ExpectSuccess(context, runtime::GetDevice(¤t_device), - "NVIDIA dispatch should get the current device."); + Message(backend_name, "get the current device")); context->ExpectEqual(current_device, 0, - "NVIDIA dispatch should keep the current device."); - - int device_count = 0; - ExpectSuccess(context, runtime::GetDeviceCount(&device_count), - "NVIDIA dispatch should get the device count."); - context->Expect(device_count > 0, - "NVIDIA dispatch should report at least one device."); + Message(backend_name, "keep the current device")); ExpectSuccess(context, runtime::Malloc(&ptr, input.size()), - "NVIDIA dispatch should allocate memory."); + Message(backend_name, "allocate memory")); if (ptr == nullptr) { return; } ExpectSuccess(context, - runtime::MemcpyAsync(ptr, input.data(), input.size(), - runtime::kMemcpyHostToDevice, nullptr), - "NVIDIA dispatch should support async host-to-device copy."); - ExpectSuccess(context, runtime::DeviceSynchronize(), - "NVIDIA dispatch should synchronize the device."); + runtime::Memcpy(ptr, input.data(), input.size(), + runtime::kMemcpyHostToDevice), + Message(backend_name, "copy host data to runtime memory")); + + runtime::Stream stream{}; + const auto async_status = runtime::MemcpyAsync( + ptr, input.data(), input.size(), runtime::kMemcpyHostToDevice, stream); + if (expect_async_memcpy_success) { + ExpectSuccess(context, async_status, + Message(backend_name, "support async host-to-device copy")); + ExpectSuccess(context, runtime::DeviceSynchronize(), + Message(backend_name, "synchronize async copy")); + } else { + ExpectFailure(context, async_status, + Message(backend_name, "not report async memcpy success")); + } + ExpectSuccess(context, runtime::Memcpy(output.data(), ptr, output.size(), runtime::kMemcpyDeviceToHost), - "NVIDIA dispatch should copy device data to host."); + Message(backend_name, "copy runtime memory to host")); context->ExpectEqual(output, input, - "NVIDIA dispatch should preserve copied bytes."); + Message(backend_name, "preserve copied bytes")); ExpectSuccess(context, runtime::Memset(ptr, 0x5A, output.size()), - "NVIDIA dispatch should fill runtime memory."); + Message(backend_name, "fill runtime memory")); ExpectSuccess(context, runtime::DeviceSynchronize(), - "NVIDIA dispatch should synchronize filled memory."); + Message(backend_name, "synchronize filled memory")); ExpectSuccess(context, runtime::Memcpy(output.data(), ptr, output.size(), runtime::kMemcpyDeviceToHost), - "NVIDIA dispatch should copy filled memory to host."); + Message(backend_name, "copy filled memory to host")); for (const auto value : output) { context->ExpectEqual(value, static_cast(0x5A), - "NVIDIA dispatch should preserve filled bytes."); + Message(backend_name, "preserve filled bytes")); } ExpectSuccess(context, runtime::Free(ptr), - "NVIDIA dispatch should free memory."); + Message(backend_name, "free memory")); } -#endif } // namespace @@ -147,11 +126,36 @@ int main() { infini::rt::test::TestContext context; #if defined(INFINI_RT_TEST_WITH_CPU) - TestCpuDispatch(&context); + TestDispatch(&context, infini::rt::Device::Type::kCpu, "CPU", false); #endif #if defined(INFINI_RT_TEST_WITH_NVIDIA) - TestNvidiaDispatch(&context); + TestDispatch(&context, infini::rt::Device::Type::kNvidia, "NVIDIA", true); +#endif + +#if defined(INFINI_RT_TEST_WITH_ILUVATAR) + TestDispatch(&context, infini::rt::Device::Type::kIluvatar, "ILUVATAR", true); +#endif + +#if defined(INFINI_RT_TEST_WITH_HYGON) + TestDispatch(&context, infini::rt::Device::Type::kHygon, "HYGON", true); +#endif + +#if defined(INFINI_RT_TEST_WITH_METAX) + TestDispatch(&context, infini::rt::Device::Type::kMetax, "METAX", true); +#endif + +#if defined(INFINI_RT_TEST_WITH_MOORE) + TestDispatch(&context, infini::rt::Device::Type::kMoore, "MOORE", true); +#endif + +#if defined(INFINI_RT_TEST_WITH_CAMBRICON) + TestDispatch(&context, infini::rt::Device::Type::kCambricon, "CAMBRICON", + true); +#endif + +#if defined(INFINI_RT_TEST_WITH_ASCEND) + TestDispatch(&context, infini::rt::Device::Type::kAscend, "ASCEND", true); #endif return context.ExitCode();