Geoffrey Martin-Noble | 552d3f8 | 2021-05-25 17:56:09 -0700 | [diff] [blame] | 1 | // Copyright 2020 The IREE Authors |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 2 | // |
Geoffrey Martin-Noble | 552d3f8 | 2021-05-25 17:56:09 -0700 | [diff] [blame] | 3 | // Licensed under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 6 | |
Ben Vanik | 5a58aa4 | 2021-05-07 12:46:29 -0700 | [diff] [blame] | 7 | #include <array> |
Ben Vanik | 931a3b1 | 2021-05-20 13:27:13 -0700 | [diff] [blame] | 8 | #include <cstdio> |
Ben Vanik | 931a3b1 | 2021-05-20 13:27:13 -0700 | [diff] [blame] | 9 | #include <iterator> |
| 10 | #include <string> |
| 11 | #include <type_traits> |
| 12 | #include <utility> |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 13 | |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 14 | #include "iree/base/api.h" |
Ben Vanik | 5507c6e | 2021-02-02 21:27:08 -0800 | [diff] [blame] | 15 | #include "iree/base/internal/file_io.h" |
Ben Vanik | e28d253 | 2021-02-03 13:44:24 -0800 | [diff] [blame] | 16 | #include "iree/base/internal/flags.h" |
Ben Vanik | 58fbb7b | 2021-06-21 11:04:08 -0700 | [diff] [blame] | 17 | #include "iree/base/status_cc.h" |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 18 | #include "iree/base/target_platform.h" |
| 19 | #include "iree/base/tracing.h" |
Ben Vanik | 931a3b1 | 2021-05-20 13:27:13 -0700 | [diff] [blame] | 20 | #include "iree/hal/api.h" |
Ben Vanik | d2f24f0 | 2021-06-21 09:13:53 -0700 | [diff] [blame] | 21 | #include "iree/modules/check/module.h" |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 22 | #include "iree/testing/gtest.h" |
Ben Vanik | 371a865 | 2020-08-09 01:36:48 -0700 | [diff] [blame] | 23 | #include "iree/testing/status_matchers.h" |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 24 | #include "iree/tooling/context_util.h" |
Ben Vanik | 097d826 | 2022-06-09 11:35:04 -0700 | [diff] [blame] | 25 | #include "iree/tooling/vm_util.h" |
Ben Vanik | 931a3b1 | 2021-05-20 13:27:13 -0700 | [diff] [blame] | 26 | #include "iree/vm/api.h" |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 27 | #include "iree/vm/bytecode_module.h" |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 28 | |
Ben Vanik | ebeb5fc | 2021-04-24 09:40:50 -0700 | [diff] [blame] | 29 | IREE_FLAG( |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 30 | bool, expect_failure, false, |
| 31 | "Whether running module is expected to fail. If set, failing " |
| 32 | "statuses from function evaluation are logged and ignored and all " |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 33 | "evaluations succeeding is considered an error and will return a failure. " |
| 34 | "Mostly useful for testing the binary doesn't crash for failing tests."); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 35 | |
| 36 | namespace iree { |
| 37 | namespace { |
| 38 | |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 39 | class CheckModuleTest : public ::testing::Test { |
| 40 | public: |
| 41 | explicit CheckModuleTest(iree_vm_instance_t* instance, |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 42 | const iree_tooling_module_list_t* modules, |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 43 | iree_vm_function_t function) |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 44 | : instance_(instance), function_(function) { |
| 45 | iree_tooling_module_list_clone(modules, &modules_); |
| 46 | } |
| 47 | ~CheckModuleTest() { iree_tooling_module_list_reset(&modules_); } |
| 48 | |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 49 | void SetUp() override { |
Ben Vanik | 007109f | 2022-08-03 07:26:50 -0700 | [diff] [blame] | 50 | IREE_CHECK_OK(iree_tooling_create_context_from_flags( |
| 51 | instance_, modules_.count, modules_.values, |
| 52 | /*default_device_uri=*/iree_string_view_empty(), |
| 53 | iree_vm_instance_allocator(instance_), &context_, |
| 54 | /*out_device=*/NULL, /*out_device_allocator=*/NULL)); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 55 | } |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 56 | |
Ben Vanik | 2838464 | 2020-05-19 10:23:49 -0700 | [diff] [blame] | 57 | void TearDown() override { iree_vm_context_release(context_); } |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 58 | |
| 59 | void TestBody() override { |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 60 | IREE_EXPECT_OK(iree_vm_invoke(context_, function_, |
| 61 | IREE_VM_INVOCATION_FLAG_NONE, |
| 62 | /*policy=*/nullptr, |
| 63 | /*inputs=*/nullptr, /*outputs=*/nullptr, |
| 64 | iree_vm_instance_allocator(instance_))); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | private: |
| 68 | iree_vm_instance_t* instance_ = nullptr; |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 69 | iree_tooling_module_list_t modules_; |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 70 | iree_vm_function_t function_; |
| 71 | |
| 72 | iree_vm_context_t* context_ = nullptr; |
| 73 | }; |
| 74 | |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 75 | iree_status_t Run(std::string module_file_path, iree_allocator_t host_allocator, |
| 76 | int* out_exit_code) { |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 77 | IREE_TRACE_SCOPE0("iree-check-module"); |
Ben Vanik | ab989fc | 2021-02-03 10:30:08 -0800 | [diff] [blame] | 78 | *out_exit_code = 1; |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 79 | |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 80 | iree_vm_instance_t* instance = nullptr; |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 81 | IREE_RETURN_IF_ERROR(iree_tooling_create_instance(host_allocator, &instance), |
| 82 | "creating instance"); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 83 | |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 84 | iree_vm_module_t* check_module = nullptr; |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 85 | IREE_RETURN_IF_ERROR( |
| 86 | iree_check_module_create(instance, host_allocator, &check_module)); |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 87 | |
| 88 | // TODO(benvanik): use --module_file= flag in order to reuse |
| 89 | // iree_tooling_load_module_from_flags. |
Ben Vanik | 35bc9a1 | 2022-03-09 09:05:58 -0800 | [diff] [blame] | 90 | iree_file_contents_t* flatbuffer_contents = NULL; |
Han-Chung Wang | 8255d34 | 2020-10-05 07:32:51 -0700 | [diff] [blame] | 91 | if (module_file_path == "-") { |
bjacob | 1cb92dd | 2022-09-26 16:21:02 +0000 | [diff] [blame^] | 92 | printf("Reading module contents from stdin...\n"); |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 93 | IREE_RETURN_IF_ERROR( |
| 94 | iree_stdin_read_contents(host_allocator, &flatbuffer_contents)); |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 95 | } else { |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 96 | IREE_RETURN_IF_ERROR(iree_file_read_contents( |
| 97 | module_file_path.c_str(), host_allocator, &flatbuffer_contents)); |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 98 | } |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 99 | iree_vm_module_t* main_module = nullptr; |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 100 | IREE_RETURN_IF_ERROR(iree_vm_bytecode_module_create( |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 101 | instance, flatbuffer_contents->const_buffer, |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 102 | iree_file_contents_deallocator(flatbuffer_contents), host_allocator, |
| 103 | &main_module)); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 104 | |
Ben Vanik | 007109f | 2022-08-03 07:26:50 -0700 | [diff] [blame] | 105 | // Resolve all system modules required by the user and check modules. |
| 106 | iree_vm_module_t* user_modules[2] = {check_module, main_module}; |
| 107 | iree_tooling_module_list_t modules; |
| 108 | iree_tooling_module_list_initialize(&modules); |
| 109 | IREE_RETURN_IF_ERROR(iree_tooling_resolve_modules( |
| 110 | instance, IREE_ARRAYSIZE(user_modules), user_modules, |
| 111 | /*default_device_uri=*/iree_string_view_empty(), host_allocator, &modules, |
| 112 | /*out_device=*/NULL, /*out_device_allocator=*/NULL)); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 113 | |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 114 | auto module_signature = iree_vm_module_signature(main_module); |
Ben Vanik | 7f3a7e3 | 2020-11-14 14:16:07 -0800 | [diff] [blame] | 115 | for (iree_host_size_t ordinal = 0; |
| 116 | ordinal < module_signature.export_function_count; ++ordinal) { |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 117 | iree_vm_function_t function; |
Ben Vanik | 6c4dd5b | 2021-10-05 15:29:23 -0700 | [diff] [blame] | 118 | IREE_RETURN_IF_ERROR( |
| 119 | iree_vm_module_lookup_function_by_ordinal( |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 120 | main_module, IREE_VM_FUNCTION_LINKAGE_EXPORT, ordinal, &function), |
Ben Vanik | 6c4dd5b | 2021-10-05 15:29:23 -0700 | [diff] [blame] | 121 | "looking up function export %zu", ordinal); |
| 122 | iree_string_view_t function_name = iree_vm_function_name(&function); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 123 | |
Ben Vanik | 6c4dd5b | 2021-10-05 15:29:23 -0700 | [diff] [blame] | 124 | if (iree_string_view_starts_with(function_name, |
Ben Vanik | 1ead648 | 2021-05-01 17:44:00 -0700 | [diff] [blame] | 125 | iree_make_cstring_view("__")) || |
Ben Vanik | 6c4dd5b | 2021-10-05 15:29:23 -0700 | [diff] [blame] | 126 | iree_string_view_find_char(function_name, '$', 0) != |
Ben Vanik | 1ead648 | 2021-05-01 17:44:00 -0700 | [diff] [blame] | 127 | IREE_STRING_VIEW_NPOS) { |
Stella Laurenzo | 7a4a852 | 2020-03-23 18:19:44 -0700 | [diff] [blame] | 128 | // Skip internal or special functions. |
| 129 | continue; |
| 130 | } |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 131 | |
Ben Vanik | 5a58aa4 | 2021-05-07 12:46:29 -0700 | [diff] [blame] | 132 | iree_vm_function_signature_t signature = |
| 133 | iree_vm_function_signature(&function); |
| 134 | iree_host_size_t argument_count = 0; |
| 135 | iree_host_size_t result_count = 0; |
| 136 | IREE_RETURN_IF_ERROR(iree_vm_function_call_count_arguments_and_results( |
| 137 | &signature, &argument_count, &result_count)); |
| 138 | if (argument_count || result_count) { |
Ben Vanik | bb7607f | 2021-02-03 11:58:09 -0800 | [diff] [blame] | 139 | return iree_make_status(IREE_STATUS_INVALID_ARGUMENT, |
| 140 | "expected function with no inputs or outputs, " |
| 141 | "but export '%.*s' has signature '%.*s'", |
Ben Vanik | 6c4dd5b | 2021-10-05 15:29:23 -0700 | [diff] [blame] | 142 | (int)function_name.size, function_name.data, |
Ben Vanik | 5a58aa4 | 2021-05-07 12:46:29 -0700 | [diff] [blame] | 143 | (int)signature.calling_convention.size, |
| 144 | signature.calling_convention.data); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 145 | } |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 146 | |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 147 | iree_string_view_t module_name = iree_vm_module_name(main_module); |
| 148 | ::testing::RegisterTest(module_name.data, function_name.data, nullptr, |
| 149 | std::to_string(ordinal).c_str(), __FILE__, __LINE__, |
| 150 | [=]() -> CheckModuleTest* { |
| 151 | return new CheckModuleTest(instance, &modules, |
| 152 | function); |
| 153 | }); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 154 | } |
Ben Vanik | ab989fc | 2021-02-03 10:30:08 -0800 | [diff] [blame] | 155 | *out_exit_code = RUN_ALL_TESTS(); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 156 | |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 157 | iree_tooling_module_list_reset(&modules); |
Ben Vanik | 2838464 | 2020-05-19 10:23:49 -0700 | [diff] [blame] | 158 | iree_vm_module_release(check_module); |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 159 | iree_vm_module_release(main_module); |
Ben Vanik | 2838464 | 2020-05-19 10:23:49 -0700 | [diff] [blame] | 160 | iree_vm_instance_release(instance); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 161 | |
Ben Vanik | 5a26619 | 2021-05-01 15:22:06 -0700 | [diff] [blame] | 162 | return iree_ok_status(); |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | } // namespace |
| 166 | |
| 167 | extern "C" int main(int argc, char** argv) { |
Ben Vanik | 1cb2f7a | 2021-04-26 16:32:53 -0700 | [diff] [blame] | 168 | // Pass through flags to gtest (allowing --help to fall through). |
| 169 | iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_UNDEFINED_OK | |
| 170 | IREE_FLAGS_PARSE_MODE_CONTINUE_AFTER_HELP, |
| 171 | &argc, &argv); |
Scott Todd | 5470635 | 2020-08-19 17:06:22 -0700 | [diff] [blame] | 172 | ::testing::InitGoogleTest(&argc, argv); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 173 | |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 174 | if (argc < 2) { |
bjacob | 1cb92dd | 2022-09-26 16:21:02 +0000 | [diff] [blame^] | 175 | fprintf(stderr, |
| 176 | "A binary module file path to run (or - for stdin) must be passed"); |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 177 | return -1; |
| 178 | } |
Han-Chung Wang | 8255d34 | 2020-10-05 07:32:51 -0700 | [diff] [blame] | 179 | auto module_file_path = std::string(argv[1]); |
Ben Vanik | 2b26f8b | 2020-04-01 12:10:06 -0700 | [diff] [blame] | 180 | |
Ben Vanik | ab989fc | 2021-02-03 10:30:08 -0800 | [diff] [blame] | 181 | int exit_code = 1; |
Ben Vanik | bcec0b5 | 2022-08-06 08:45:46 -0700 | [diff] [blame] | 182 | iree_status_t status = |
| 183 | Run(std::move(module_file_path), iree_allocator_system(), &exit_code); |
Ben Vanik | 524c8e7 | 2021-05-01 15:48:44 -0700 | [diff] [blame] | 184 | int ret = iree_status_is_ok(status) ? exit_code : 1; |
Ben Vanik | ebeb5fc | 2021-04-24 09:40:50 -0700 | [diff] [blame] | 185 | if (FLAG_expect_failure) { |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 186 | if (ret == 0) { |
bjacob | 1cb92dd | 2022-09-26 16:21:02 +0000 | [diff] [blame^] | 187 | printf("Test passed but expected failure\n"); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 188 | return 1; |
| 189 | } |
bjacob | 1cb92dd | 2022-09-26 16:21:02 +0000 | [diff] [blame^] | 190 | printf("Test failed as expected\n"); |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 191 | return 0; |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 192 | } |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 193 | |
Thomas | f1aa6f4 | 2021-04-05 19:53:56 -0700 | [diff] [blame] | 194 | if (ret != 0) { |
bjacob | 1cb92dd | 2022-09-26 16:21:02 +0000 | [diff] [blame^] | 195 | printf("Test failed\n%s\n", Status(std::move(status)).ToString().c_str()); |
Thomas | f1aa6f4 | 2021-04-05 19:53:56 -0700 | [diff] [blame] | 196 | } |
| 197 | |
Geoffrey Martin-Noble | c9db858 | 2020-03-04 14:16:46 -0800 | [diff] [blame] | 198 | return ret; |
Geoffrey Martin-Noble | 94d7b6e | 2020-02-20 13:43:10 -0800 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | } // namespace iree |