blob: b820b6069eba90fad9325b825c0a5fad2052694e [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 Vanik931a3b12021-05-20 13:27:13 -070017#include "iree/hal/api.h"
Ben Vanikd2f24f02021-06-21 09:13:53 -070018#include "iree/modules/check/module.h"
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080019#include "iree/testing/gtest.h"
Ben Vanik371a8652020-08-09 01:36:48 -070020#include "iree/testing/status_matchers.h"
Ben Vanikbcec0b52022-08-06 08:45:46 -070021#include "iree/tooling/context_util.h"
Ben Vanik7859d632022-10-24 14:37:28 -070022#include "iree/tooling/device_util.h"
Ben Vanik931a3b12021-05-20 13:27:13 -070023#include "iree/vm/api.h"
Ben Vanikcf49d692023-02-24 20:24:09 -080024#include "iree/vm/bytecode/module.h"
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080025
Ben Vanikebeb5fc2021-04-24 09:40:50 -070026IREE_FLAG(
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080027 bool, expect_failure, false,
28 "Whether running module is expected to fail. If set, failing "
29 "statuses from function evaluation are logged and ignored and all "
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080030 "evaluations succeeding is considered an error and will return a failure. "
31 "Mostly useful for testing the binary doesn't crash for failing tests.");
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080032
33namespace iree {
34namespace {
35
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080036class CheckModuleTest : public ::testing::Test {
37 public:
38 explicit CheckModuleTest(iree_vm_instance_t* instance,
Ben Vanik9461d3b2023-04-18 16:39:25 -070039 const iree_tooling_module_list_t* module_list,
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080040 iree_vm_function_t function)
Ben Vanikbcec0b52022-08-06 08:45:46 -070041 : instance_(instance), function_(function) {
Ben Vanik9461d3b2023-04-18 16:39:25 -070042 iree_tooling_module_list_clone(module_list, &module_list_);
Ben Vanikbcec0b52022-08-06 08:45:46 -070043 }
Ben Vanik9461d3b2023-04-18 16:39:25 -070044 ~CheckModuleTest() { iree_tooling_module_list_reset(&module_list_); }
Ben Vanikbcec0b52022-08-06 08:45:46 -070045
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080046 void SetUp() override {
Ben Vanik007109f2022-08-03 07:26:50 -070047 IREE_CHECK_OK(iree_tooling_create_context_from_flags(
Ben Vanik9461d3b2023-04-18 16:39:25 -070048 instance_, module_list_.count, module_list_.values,
Ben Vanik007109f2022-08-03 07:26:50 -070049 /*default_device_uri=*/iree_string_view_empty(),
Ben Vanik7859d632022-10-24 14:37:28 -070050 iree_vm_instance_allocator(instance_), &context_, &device_,
51 /*out_device_allocator=*/NULL));
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080052 }
Ben Vanikbcec0b52022-08-06 08:45:46 -070053
Ben Vanik7859d632022-10-24 14:37:28 -070054 void TearDown() override {
55 iree_vm_context_release(context_);
56 iree_hal_device_release(device_);
57 }
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080058
59 void TestBody() override {
Ben Vanik7859d632022-10-24 14:37:28 -070060 IREE_ASSERT_OK(iree_hal_begin_profiling_from_flags(device_));
Ben Vanikbcec0b52022-08-06 08:45:46 -070061 IREE_EXPECT_OK(iree_vm_invoke(context_, function_,
62 IREE_VM_INVOCATION_FLAG_NONE,
63 /*policy=*/nullptr,
64 /*inputs=*/nullptr, /*outputs=*/nullptr,
65 iree_vm_instance_allocator(instance_)));
Ben Vanik7859d632022-10-24 14:37:28 -070066 IREE_ASSERT_OK(iree_hal_end_profiling_from_flags(device_));
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080067 }
68
69 private:
70 iree_vm_instance_t* instance_ = nullptr;
Ben Vanik9461d3b2023-04-18 16:39:25 -070071 iree_tooling_module_list_t module_list_;
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080072 iree_vm_function_t function_;
73
74 iree_vm_context_t* context_ = nullptr;
Ben Vanik7859d632022-10-24 14:37:28 -070075 iree_hal_device_t* device_ = nullptr;
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -080076};
77
Ben Vanik9461d3b2023-04-18 16:39:25 -070078iree_status_t Run(iree_allocator_t host_allocator, int* out_exit_code) {
Ben Vanikab989fc2021-02-03 10:30:08 -080079 *out_exit_code = 1;
Ben Vanik2b26f8b2020-04-01 12:10:06 -070080
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080081 iree_vm_instance_t* instance = nullptr;
Ben Vanikbcec0b52022-08-06 08:45:46 -070082 IREE_RETURN_IF_ERROR(iree_tooling_create_instance(host_allocator, &instance),
83 "creating instance");
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080084
Ben Vanikbcec0b52022-08-06 08:45:46 -070085 iree_vm_module_t* check_module = nullptr;
Ben Vanik9aa83ed2022-08-06 12:55:34 -070086 IREE_RETURN_IF_ERROR(
87 iree_check_module_create(instance, host_allocator, &check_module));
Ben Vanikbcec0b52022-08-06 08:45:46 -070088
Ben Vanik007109f2022-08-03 07:26:50 -070089 // Resolve all system modules required by the user and check modules.
Ben Vanik9461d3b2023-04-18 16:39:25 -070090 iree_tooling_module_list_t module_list;
91 iree_tooling_module_list_initialize(&module_list);
92 IREE_RETURN_IF_ERROR(
93 iree_tooling_module_list_push_back(&module_list, check_module));
94 IREE_RETURN_IF_ERROR(iree_tooling_load_modules_from_flags(
95 instance, host_allocator, &module_list));
96 iree_vm_module_t* main_module = iree_tooling_module_list_back(&module_list);
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -080097
Ben Vanikbcec0b52022-08-06 08:45:46 -070098 auto module_signature = iree_vm_module_signature(main_module);
Ben Vanik7f3a7e32020-11-14 14:16:07 -080099 for (iree_host_size_t ordinal = 0;
100 ordinal < module_signature.export_function_count; ++ordinal) {
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800101 iree_vm_function_t function;
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700102 IREE_RETURN_IF_ERROR(
103 iree_vm_module_lookup_function_by_ordinal(
Ben Vanikbcec0b52022-08-06 08:45:46 -0700104 main_module, IREE_VM_FUNCTION_LINKAGE_EXPORT, ordinal, &function),
Scott Todd60b07642023-06-15 09:41:01 -0700105 "looking up function export %" PRIhsz, ordinal);
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700106 iree_string_view_t function_name = iree_vm_function_name(&function);
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800107
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700108 if (iree_string_view_starts_with(function_name,
Ben Vanik1ead6482021-05-01 17:44:00 -0700109 iree_make_cstring_view("__")) ||
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700110 iree_string_view_find_char(function_name, '$', 0) !=
Ben Vanik1ead6482021-05-01 17:44:00 -0700111 IREE_STRING_VIEW_NPOS) {
Stella Laurenzo7a4a8522020-03-23 18:19:44 -0700112 // Skip internal or special functions.
113 continue;
114 }
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800115
Ben Vanik5a58aa42021-05-07 12:46:29 -0700116 iree_vm_function_signature_t signature =
117 iree_vm_function_signature(&function);
118 iree_host_size_t argument_count = 0;
119 iree_host_size_t result_count = 0;
120 IREE_RETURN_IF_ERROR(iree_vm_function_call_count_arguments_and_results(
121 &signature, &argument_count, &result_count));
122 if (argument_count || result_count) {
Ben Vanikbb7607f2021-02-03 11:58:09 -0800123 return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
124 "expected function with no inputs or outputs, "
125 "but export '%.*s' has signature '%.*s'",
Ben Vanik6c4dd5b2021-10-05 15:29:23 -0700126 (int)function_name.size, function_name.data,
Ben Vanik5a58aa42021-05-07 12:46:29 -0700127 (int)signature.calling_convention.size,
128 signature.calling_convention.data);
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800129 }
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800130
Ben Vanikbcec0b52022-08-06 08:45:46 -0700131 iree_string_view_t module_name = iree_vm_module_name(main_module);
132 ::testing::RegisterTest(module_name.data, function_name.data, nullptr,
133 std::to_string(ordinal).c_str(), __FILE__, __LINE__,
134 [=]() -> CheckModuleTest* {
Ben Vanik9461d3b2023-04-18 16:39:25 -0700135 return new CheckModuleTest(instance, &module_list,
Ben Vanikbcec0b52022-08-06 08:45:46 -0700136 function);
137 });
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800138 }
Ben Vanikab989fc2021-02-03 10:30:08 -0800139 *out_exit_code = RUN_ALL_TESTS();
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800140
Ben Vanik9461d3b2023-04-18 16:39:25 -0700141 iree_tooling_module_list_reset(&module_list);
Ben Vanik28384642020-05-19 10:23:49 -0700142 iree_vm_module_release(check_module);
Ben Vanik28384642020-05-19 10:23:49 -0700143 iree_vm_instance_release(instance);
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800144
Ben Vanik5a266192021-05-01 15:22:06 -0700145 return iree_ok_status();
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800146}
147
148} // namespace
149
150extern "C" int main(int argc, char** argv) {
Ben Vanik7ed4f4b2023-06-14 13:33:54 -0700151 IREE_TRACE_APP_ENTER();
152
Ben Vanik1cb2f7a2021-04-26 16:32:53 -0700153 // Pass through flags to gtest (allowing --help to fall through).
154 iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_UNDEFINED_OK |
155 IREE_FLAGS_PARSE_MODE_CONTINUE_AFTER_HELP,
156 &argc, &argv);
Scott Todd54706352020-08-19 17:06:22 -0700157 ::testing::InitGoogleTest(&argc, argv);
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800158
Ben Vanikcc436802023-06-10 08:53:52 -0700159 IREE_TRACE_ZONE_BEGIN_NAMED(z0, "iree-check-module");
Ben Vanikab989fc2021-02-03 10:30:08 -0800160 int exit_code = 1;
Ben Vanik9461d3b2023-04-18 16:39:25 -0700161 iree_status_t status = Run(iree_allocator_system(), &exit_code);
Ben Vanik14308b12023-06-13 10:22:28 -0700162 exit_code = iree_status_is_ok(status) ? exit_code : EXIT_FAILURE;
Ben Vanikcc436802023-06-10 08:53:52 -0700163 IREE_TRACE_ZONE_END(z0);
Ben Vanik7ed4f4b2023-06-14 13:33:54 -0700164
Ben Vanik14308b12023-06-13 10:22:28 -0700165 IREE_TRACE_APP_EXIT(exit_code);
Ben Vanikcc436802023-06-10 08:53:52 -0700166
Ben Vanikebeb5fc2021-04-24 09:40:50 -0700167 if (FLAG_expect_failure) {
Ben Vanik14308b12023-06-13 10:22:28 -0700168 if (exit_code == 0) {
bjacob1cb92dd2022-09-26 16:21:02 +0000169 printf("Test passed but expected failure\n");
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800170 return 1;
171 }
bjacob1cb92dd2022-09-26 16:21:02 +0000172 printf("Test failed as expected\n");
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800173 return 0;
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800174 }
Geoffrey Martin-Noblec9db8582020-03-04 14:16:46 -0800175
Ben Vanik14308b12023-06-13 10:22:28 -0700176 if (exit_code != 0) {
bjacob1cb92dd2022-09-26 16:21:02 +0000177 printf("Test failed\n%s\n", Status(std::move(status)).ToString().c_str());
Thomasf1aa6f42021-04-05 19:53:56 -0700178 }
179
Ben Vanik14308b12023-06-13 10:22:28 -0700180 return exit_code;
Geoffrey Martin-Noble94d7b6e2020-02-20 13:43:10 -0800181}
182
183} // namespace iree