blob: f7bf455a427fd3f1a8e386b3410492ab1b837a0e [file] [log] [blame]
Geoffrey Martin-Noble552d3f82021-05-25 17:56:09 -07001// Copyright 2020 The IREE Authors
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -08002//
Geoffrey Martin-Noble552d3f82021-05-25 17:56:09 -07003// 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-Noble94d7b6e2020-02-20 13:43:10 -08006
Ben Vanik5a58aa42021-05-07 12:46:29 -07007#include <array>
Ben Vanik931a3b12021-05-20 13:27:13 -07008#include <cstdio>
Ben Vanik931a3b12021-05-20 13:27:13 -07009#include <iterator>
10#include <string>
11#include <type_traits>
12#include <utility>
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080013
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080014#include "iree/base/api.h"
Ben Vanik5507c6e2021-02-02 21:27:08 -080015#include "iree/base/internal/file_io.h"
Ben Vanike28d2532021-02-03 13:44:24 -080016#include "iree/base/internal/flags.h"
Ben Vanik58fbb7b2021-06-21 11:04:08 -070017#include "iree/base/status_cc.h"
Ben Vanik2b26f8b2020-04-01 12:10:06 -070018#include "iree/base/target_platform.h"
19#include "iree/base/tracing.h"
Ben Vanik931a3b12021-05-20 13:27:13 -070020#include "iree/hal/api.h"
Ben Vanikd2f24f02021-06-21 09:13:53 -070021#include "iree/modules/check/module.h"
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080022#include "iree/testing/gtest.h"
Ben Vanik371a8652020-08-09 01:36:48 -070023#include "iree/testing/status_matchers.h"
Ben Vanikbcec0b52022-08-06 08:45:46 -070024#include "iree/tooling/context_util.h"
Ben Vanik097d8262022-06-09 11:35:04 -070025#include "iree/tooling/vm_util.h"
Ben Vanik931a3b12021-05-20 13:27:13 -070026#include "iree/vm/api.h"
Ben Vanikb9b794b2021-06-19 20:11:08 -070027#include "iree/vm/bytecode_module.h"
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080028
Ben Vanikebeb5fc2021-04-24 09:40:50 -070029IREE_FLAG(
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080030 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-Noblec9db8582020-03-04 14:16:46 -080033 "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-Noble94d7b6e2020-02-20 13:43:10 -080035
36namespace iree {
37namespace {
38
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080039class CheckModuleTest : public ::testing::Test {
40 public:
41 explicit CheckModuleTest(iree_vm_instance_t* instance,
Ben Vanikbcec0b52022-08-06 08:45:46 -070042 const iree_tooling_module_list_t* modules,
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080043 iree_vm_function_t function)
Ben Vanikbcec0b52022-08-06 08:45:46 -070044 : instance_(instance), function_(function) {
45 iree_tooling_module_list_clone(modules, &modules_);
46 }
47 ~CheckModuleTest() { iree_tooling_module_list_reset(&modules_); }
48
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080049 void SetUp() override {
Ben Vanik007109f2022-08-03 07:26:50 -070050 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-Noblec9db8582020-03-04 14:16:46 -080055 }
Ben Vanikbcec0b52022-08-06 08:45:46 -070056
Ben Vanik28384642020-05-19 10:23:49 -070057 void TearDown() override { iree_vm_context_release(context_); }
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080058
59 void TestBody() override {
Ben Vanikbcec0b52022-08-06 08:45:46 -070060 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-Noblec9db8582020-03-04 14:16:46 -080065 }
66
67 private:
68 iree_vm_instance_t* instance_ = nullptr;
Ben Vanikbcec0b52022-08-06 08:45:46 -070069 iree_tooling_module_list_t modules_;
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080070 iree_vm_function_t function_;
71
72 iree_vm_context_t* context_ = nullptr;
73};
74
Ben Vanikbcec0b52022-08-06 08:45:46 -070075iree_status_t Run(std::string module_file_path, iree_allocator_t host_allocator,
76 int* out_exit_code) {
Ben Vanik2b26f8b2020-04-01 12:10:06 -070077 IREE_TRACE_SCOPE0("iree-check-module");
Ben Vanikab989fc2021-02-03 10:30:08 -080078 *out_exit_code = 1;
Ben Vanik2b26f8b2020-04-01 12:10:06 -070079
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080080 iree_vm_instance_t* instance = nullptr;
Ben Vanikbcec0b52022-08-06 08:45:46 -070081 IREE_RETURN_IF_ERROR(iree_tooling_create_instance(host_allocator, &instance),
82 "creating instance");
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080083
Ben Vanikbcec0b52022-08-06 08:45:46 -070084 iree_vm_module_t* check_module = nullptr;
Ben Vanik9aa83ed2022-08-06 12:55:34 -070085 IREE_RETURN_IF_ERROR(
86 iree_check_module_create(instance, host_allocator, &check_module));
Ben Vanikbcec0b52022-08-06 08:45:46 -070087
88 // TODO(benvanik): use --module_file= flag in order to reuse
89 // iree_tooling_load_module_from_flags.
Ben Vanik35bc9a12022-03-09 09:05:58 -080090 iree_file_contents_t* flatbuffer_contents = NULL;
Han-Chung Wang8255d342020-10-05 07:32:51 -070091 if (module_file_path == "-") {
bjacob1cb92dd2022-09-26 16:21:02 +000092 printf("Reading module contents from stdin...\n");
Ben Vanikbcec0b52022-08-06 08:45:46 -070093 IREE_RETURN_IF_ERROR(
94 iree_stdin_read_contents(host_allocator, &flatbuffer_contents));
Ben Vanik2b26f8b2020-04-01 12:10:06 -070095 } else {
Ben Vanikbcec0b52022-08-06 08:45:46 -070096 IREE_RETURN_IF_ERROR(iree_file_read_contents(
97 module_file_path.c_str(), host_allocator, &flatbuffer_contents));
Ben Vanik2b26f8b2020-04-01 12:10:06 -070098 }
Ben Vanikbcec0b52022-08-06 08:45:46 -070099 iree_vm_module_t* main_module = nullptr;
Ben Vanikb9b794b2021-06-19 20:11:08 -0700100 IREE_RETURN_IF_ERROR(iree_vm_bytecode_module_create(
Ben Vanik9aa83ed2022-08-06 12:55:34 -0700101 instance, flatbuffer_contents->const_buffer,
Ben Vanikbcec0b52022-08-06 08:45:46 -0700102 iree_file_contents_deallocator(flatbuffer_contents), host_allocator,
103 &main_module));
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800104
Ben Vanik007109f2022-08-03 07:26:50 -0700105 // 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-Noble94d7b6e2020-02-20 13:43:10 -0800113
Ben Vanikbcec0b52022-08-06 08:45:46 -0700114 auto module_signature = iree_vm_module_signature(main_module);
Ben Vanik7f3a7e32020-11-14 14:16:07 -0800115 for (iree_host_size_t ordinal = 0;
116 ordinal < module_signature.export_function_count; ++ordinal) {
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800117 iree_vm_function_t function;
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700118 IREE_RETURN_IF_ERROR(
119 iree_vm_module_lookup_function_by_ordinal(
Ben Vanikbcec0b52022-08-06 08:45:46 -0700120 main_module, IREE_VM_FUNCTION_LINKAGE_EXPORT, ordinal, &function),
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700121 "looking up function export %zu", ordinal);
122 iree_string_view_t function_name = iree_vm_function_name(&function);
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800123
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700124 if (iree_string_view_starts_with(function_name,
Ben Vanik1ead6482021-05-01 17:44:00 -0700125 iree_make_cstring_view("__")) ||
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700126 iree_string_view_find_char(function_name, '$', 0) !=
Ben Vanik1ead6482021-05-01 17:44:00 -0700127 IREE_STRING_VIEW_NPOS) {
Stella Laurenzo7a4a8522020-03-23 18:19:44 -0700128 // Skip internal or special functions.
129 continue;
130 }
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800131
Ben Vanik5a58aa42021-05-07 12:46:29 -0700132 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 Vanikbb7607f2021-02-03 11:58:09 -0800139 return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
140 "expected function with no inputs or outputs, "
141 "but export '%.*s' has signature '%.*s'",
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700142 (int)function_name.size, function_name.data,
Ben Vanik5a58aa42021-05-07 12:46:29 -0700143 (int)signature.calling_convention.size,
144 signature.calling_convention.data);
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800145 }
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800146
Ben Vanikbcec0b52022-08-06 08:45:46 -0700147 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-Noblec9db8582020-03-04 14:16:46 -0800154 }
Ben Vanikab989fc2021-02-03 10:30:08 -0800155 *out_exit_code = RUN_ALL_TESTS();
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800156
Ben Vanikbcec0b52022-08-06 08:45:46 -0700157 iree_tooling_module_list_reset(&modules);
Ben Vanik28384642020-05-19 10:23:49 -0700158 iree_vm_module_release(check_module);
Ben Vanikbcec0b52022-08-06 08:45:46 -0700159 iree_vm_module_release(main_module);
Ben Vanik28384642020-05-19 10:23:49 -0700160 iree_vm_instance_release(instance);
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800161
Ben Vanik5a266192021-05-01 15:22:06 -0700162 return iree_ok_status();
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800163}
164
165} // namespace
166
167extern "C" int main(int argc, char** argv) {
Ben Vanik1cb2f7a2021-04-26 16:32:53 -0700168 // 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 Todd54706352020-08-19 17:06:22 -0700172 ::testing::InitGoogleTest(&argc, argv);
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800173
Ben Vanik2b26f8b2020-04-01 12:10:06 -0700174 if (argc < 2) {
bjacob1cb92dd2022-09-26 16:21:02 +0000175 fprintf(stderr,
176 "A binary module file path to run (or - for stdin) must be passed");
Ben Vanik2b26f8b2020-04-01 12:10:06 -0700177 return -1;
178 }
Han-Chung Wang8255d342020-10-05 07:32:51 -0700179 auto module_file_path = std::string(argv[1]);
Ben Vanik2b26f8b2020-04-01 12:10:06 -0700180
Ben Vanikab989fc2021-02-03 10:30:08 -0800181 int exit_code = 1;
Ben Vanikbcec0b52022-08-06 08:45:46 -0700182 iree_status_t status =
183 Run(std::move(module_file_path), iree_allocator_system(), &exit_code);
Ben Vanik524c8e72021-05-01 15:48:44 -0700184 int ret = iree_status_is_ok(status) ? exit_code : 1;
Ben Vanikebeb5fc2021-04-24 09:40:50 -0700185 if (FLAG_expect_failure) {
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800186 if (ret == 0) {
bjacob1cb92dd2022-09-26 16:21:02 +0000187 printf("Test passed but expected failure\n");
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800188 return 1;
189 }
bjacob1cb92dd2022-09-26 16:21:02 +0000190 printf("Test failed as expected\n");
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800191 return 0;
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800192 }
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800193
Thomasf1aa6f42021-04-05 19:53:56 -0700194 if (ret != 0) {
bjacob1cb92dd2022-09-26 16:21:02 +0000195 printf("Test failed\n%s\n", Status(std::move(status)).ToString().c_str());
Thomasf1aa6f42021-04-05 19:53:56 -0700196 }
197
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800198 return ret;
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800199}
200
201} // namespace iree