| // Copyright 2019 The IREE Authors |
| // |
| // Licensed under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| // Tests covering the dispatch logic for individual ops. |
| // |
| // iree/vm/test/*.mlir contains the functions used here for testing. We |
| // avoid defining the IR inline here so that we can run this test on platforms |
| // that we can't run the full MLIR compiler stack on. |
| |
| #include "iree/base/api.h" |
| #include "iree/testing/gtest.h" |
| #include "iree/vm/api.h" |
| #include "iree/vm/bytecode/module.h" |
| |
| // Compiled module embedded here to avoid file IO: |
| #include "iree/vm/test/all_bytecode_modules.h" |
| |
| namespace { |
| |
| struct TestParams { |
| const struct iree_file_toc_t& module_file; |
| std::string function_name; |
| }; |
| |
| std::ostream& operator<<(std::ostream& os, const TestParams& params) { |
| std::string name{params.module_file.name}; |
| auto name_sv = iree_make_string_view(name.data(), name.size()); |
| iree_string_view_replace_char(name_sv, ':', '_'); |
| iree_string_view_replace_char(name_sv, '.', '_'); |
| return os << name << "_" << params.function_name; |
| } |
| |
| std::vector<TestParams> GetModuleTestParams() { |
| std::vector<TestParams> test_params; |
| |
| iree_vm_instance_t* instance = NULL; |
| IREE_CHECK_OK(iree_vm_instance_create(IREE_VM_TYPE_CAPACITY_DEFAULT, |
| iree_allocator_system(), &instance)); |
| |
| const struct iree_file_toc_t* module_file_toc = |
| all_bytecode_modules_c_create(); |
| for (size_t i = 0; i < all_bytecode_modules_c_size(); ++i) { |
| const auto& module_file = module_file_toc[i]; |
| iree_vm_module_t* module = nullptr; |
| IREE_CHECK_OK(iree_vm_bytecode_module_create( |
| instance, |
| iree_const_byte_span_t{ |
| reinterpret_cast<const uint8_t*>(module_file.data), |
| static_cast<iree_host_size_t>(module_file.size)}, |
| iree_allocator_null(), iree_allocator_system(), &module)); |
| iree_vm_module_signature_t signature = iree_vm_module_signature(module); |
| test_params.reserve(test_params.size() + signature.export_function_count); |
| for (int i = 0; i < signature.export_function_count; ++i) { |
| iree_vm_function_t function; |
| IREE_CHECK_OK(iree_vm_module_lookup_function_by_ordinal( |
| module, IREE_VM_FUNCTION_LINKAGE_EXPORT, i, &function)); |
| iree_string_view_t function_name = iree_vm_function_name(&function); |
| test_params.push_back( |
| {module_file, std::string(function_name.data, function_name.size)}); |
| } |
| iree_vm_module_release(module); |
| } |
| |
| iree_vm_instance_release(instance); |
| |
| return test_params; |
| } |
| |
| class VMBytecodeDispatchTest |
| : public ::testing::Test, |
| public ::testing::WithParamInterface<TestParams> { |
| protected: |
| virtual void SetUp() { |
| const auto& test_params = GetParam(); |
| |
| IREE_CHECK_OK(iree_vm_instance_create(IREE_VM_TYPE_CAPACITY_DEFAULT, |
| iree_allocator_system(), &instance_)); |
| |
| IREE_CHECK_OK(iree_vm_bytecode_module_create( |
| instance_, |
| iree_const_byte_span_t{ |
| reinterpret_cast<const uint8_t*>(test_params.module_file.data), |
| static_cast<iree_host_size_t>(test_params.module_file.size)}, |
| iree_allocator_null(), iree_allocator_system(), &bytecode_module_)); |
| |
| std::vector<iree_vm_module_t*> modules = {bytecode_module_}; |
| IREE_CHECK_OK(iree_vm_context_create_with_modules( |
| instance_, IREE_VM_CONTEXT_FLAG_NONE, modules.size(), modules.data(), |
| iree_allocator_system(), &context_)); |
| } |
| |
| virtual void TearDown() { |
| iree_vm_module_release(bytecode_module_); |
| iree_vm_context_release(context_); |
| iree_vm_instance_release(instance_); |
| } |
| |
| iree_status_t RunFunction(const char* function_name) { |
| iree_vm_function_t function; |
| IREE_CHECK_OK(iree_vm_module_lookup_function_by_name( |
| bytecode_module_, IREE_VM_FUNCTION_LINKAGE_EXPORT, |
| iree_make_cstring_view(function_name), &function)); |
| |
| iree_vm_invocation_flags_t flags = IREE_VM_INVOCATION_FLAG_NONE; |
| // NOTE: adding this bit makes it easy to debug issues on stdout: |
| // flags |= IREE_VM_INVOCATION_FLAG_TRACE_EXECUTION; |
| return iree_vm_invoke(context_, function, flags, |
| /*policy=*/nullptr, /*inputs=*/nullptr, |
| /*outputs=*/nullptr, iree_allocator_system()); |
| } |
| |
| iree_vm_instance_t* instance_ = nullptr; |
| iree_vm_context_t* context_ = nullptr; |
| iree_vm_module_t* bytecode_module_ = nullptr; |
| }; |
| |
| TEST_P(VMBytecodeDispatchTest, Check) { |
| const auto& test_params = GetParam(); |
| bool expect_failure = test_params.function_name.find("fail_") == 0; |
| |
| iree_status_t status = RunFunction(test_params.function_name.c_str()); |
| if (iree_status_is_ok(status)) { |
| if (expect_failure) { |
| GTEST_FAIL() << "Function expected failure but succeeded"; |
| } else { |
| GTEST_SUCCEED(); |
| } |
| } else { |
| if (expect_failure) { |
| iree_status_ignore(status); |
| GTEST_SUCCEED(); |
| } else { |
| GTEST_FAIL() << "Function expected success but failed with error: " |
| << iree::Status(std::move(status)).ToString(); |
| } |
| } |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(VMIRFunctions, VMBytecodeDispatchTest, |
| ::testing::ValuesIn(GetModuleTestParams()), |
| ::testing::PrintToStringParamName()); |
| |
| } // namespace |