blob: e8670c5baf29860eecf66a8e66073ceff1d15552 [file] [log] [blame]
Kojo Acquah31357022021-07-16 15:55:31 -07001// Copyright 2021 The IREE Authors
2//
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
6
7// A example of static library loading in IREE. See the README.md for more info.
Stella Laurenzo7f2972c2022-03-19 14:09:43 -07008// Note: this demo requires artifacts from iree-compile before it will run.
Kojo Acquah31357022021-07-16 15:55:31 -07009
Ben Vanik325b0442022-06-06 17:14:30 -070010#include "iree/hal/drivers/local_sync/sync_device.h"
Kojo Acquah31357022021-07-16 15:55:31 -070011#include "iree/hal/local/loaders/static_library_loader.h"
Kojo Acquah31357022021-07-16 15:55:31 -070012#include "iree/modules/hal/module.h"
13#include "iree/runtime/api.h"
Kojo Acquah31357022021-07-16 15:55:31 -070014
Simon Camphausen9928f892021-11-24 17:40:19 +010015extern const iree_hal_executable_library_header_t**
16simple_mul_dispatch_0_library_query(
Ben Vanik6e015be2022-02-28 22:01:53 -080017 iree_hal_executable_library_version_t max_version,
18 const iree_hal_executable_environment_v0_t* environment);
Simon Camphausen9928f892021-11-24 17:40:19 +010019// A function to create the bytecode or C module.
Ben Vanik9aa83ed2022-08-06 12:55:34 -070020extern iree_status_t create_module(iree_vm_instance_t* instance,
21 iree_vm_module_t** out_module);
Simon Camphausen9928f892021-11-24 17:40:19 +010022
23extern void print_success();
Kojo Acquah31357022021-07-16 15:55:31 -070024
25// A function to create the HAL device from the different backend targets.
26// The HAL device is returned based on the implementation, and it must be
27// released by the caller.
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080028iree_status_t create_device_with_static_loader(iree_allocator_t host_allocator,
29 iree_hal_device_t** out_device) {
Marius Brehler1b728942023-02-21 18:09:57 +010030 // Set parameters for the device created in the next step.
Marius Brehler0f338bf2021-11-08 23:55:09 +010031 iree_hal_sync_device_params_t params;
32 iree_hal_sync_device_params_initialize(&params);
Kojo Acquah31357022021-07-16 15:55:31 -070033
Ben Vanik6e015be2022-02-28 22:01:53 -080034 // Register the statically linked executable library.
35 const iree_hal_executable_library_query_fn_t libraries[] = {
36 simple_mul_dispatch_0_library_query,
37 };
Kojo Acquah31357022021-07-16 15:55:31 -070038 iree_hal_executable_loader_t* library_loader = NULL;
Ben Vanik6e015be2022-02-28 22:01:53 -080039 iree_status_t status = iree_hal_static_library_loader_create(
40 IREE_ARRAYSIZE(libraries), libraries,
41 iree_hal_executable_import_provider_null(), host_allocator,
42 &library_loader);
Kojo Acquah31357022021-07-16 15:55:31 -070043
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080044 // Use the default host allocator for buffer allocations.
Ben Vanike9006922024-07-16 11:00:47 -070045 iree_string_view_t identifier = iree_make_cstring_view("local-sync");
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080046 iree_hal_allocator_t* device_allocator = NULL;
47 if (iree_status_is_ok(status)) {
48 status = iree_hal_allocator_create_heap(identifier, host_allocator,
Ben Vanik315a0042021-11-30 13:11:09 -080049 host_allocator, &device_allocator);
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080050 }
51
Kojo Acquah31357022021-07-16 15:55:31 -070052 // Create the device and release the executor and loader afterwards.
53 if (iree_status_is_ok(status)) {
Marius Brehler0f338bf2021-11-08 23:55:09 +010054 status = iree_hal_sync_device_create(
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080055 identifier, &params, /*loader_count=*/1, &library_loader,
56 device_allocator, host_allocator, out_device);
Kojo Acquah31357022021-07-16 15:55:31 -070057 }
Kojo Acquah31357022021-07-16 15:55:31 -070058
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080059 iree_hal_allocator_release(device_allocator);
60 iree_hal_executable_loader_release(library_loader);
Kojo Acquah31357022021-07-16 15:55:31 -070061 return status;
62}
63
64iree_status_t Run() {
65 iree_status_t status = iree_ok_status();
66
67 // Instance configuration (this should be shared across sessions).
68 iree_runtime_instance_options_t instance_options;
Ben Vanikdecb7652022-10-28 16:01:14 +000069 iree_runtime_instance_options_initialize(&instance_options);
Kojo Acquah31357022021-07-16 15:55:31 -070070 iree_runtime_instance_options_use_all_available_drivers(&instance_options);
71 iree_runtime_instance_t* instance = NULL;
72
73 if (iree_status_is_ok(status)) {
74 status = iree_runtime_instance_create(&instance_options,
75 iree_allocator_system(), &instance);
76 }
77
Scott Todd55bec0d2022-07-28 11:45:18 -070078 // Create local device with static loader.
Kojo Acquah31357022021-07-16 15:55:31 -070079 iree_hal_device_t* device = NULL;
80 if (iree_status_is_ok(status)) {
Ben Vanik0dd0cfc2021-11-29 16:32:50 -080081 status = create_device_with_static_loader(iree_allocator_system(), &device);
Kojo Acquah31357022021-07-16 15:55:31 -070082 }
Kojo Acquah31357022021-07-16 15:55:31 -070083
84 // Session configuration (one per loaded module to hold module state).
85 iree_runtime_session_options_t session_options;
86 iree_runtime_session_options_initialize(&session_options);
87 iree_runtime_session_t* session = NULL;
88 if (iree_status_is_ok(status)) {
89 status = iree_runtime_session_create_with_device(
90 instance, &session_options, device,
91 iree_runtime_instance_host_allocator(instance), &session);
92 }
93
94 // Load bytecode module from the embedded data. Append to the session.
Simon Camphausen9928f892021-11-24 17:40:19 +010095 iree_vm_module_t* module = NULL;
96
Kojo Acquah31357022021-07-16 15:55:31 -070097 if (iree_status_is_ok(status)) {
Ben Vanik9aa83ed2022-08-06 12:55:34 -070098 status =
99 create_module(iree_runtime_instance_vm_instance(instance), &module);
Kojo Acquah31357022021-07-16 15:55:31 -0700100 }
Simon Camphausen9928f892021-11-24 17:40:19 +0100101
Kojo Acquah31357022021-07-16 15:55:31 -0700102 if (iree_status_is_ok(status)) {
Simon Camphausen9928f892021-11-24 17:40:19 +0100103 status = iree_runtime_session_append_module(session, module);
Kojo Acquah31357022021-07-16 15:55:31 -0700104 }
105
106 // Lookup the entry point function call.
107 const char kMainFunctionName[] = "module.simple_mul";
108 iree_runtime_call_t call;
109 memset(&call, 0, sizeof(call));
110 if (iree_status_is_ok(status)) {
111 status = iree_runtime_call_initialize_by_name(
112 session, iree_make_cstring_view(kMainFunctionName), &call);
113 }
114
115 // Populate initial values for 4 * 2 = 8.
116 const int kElementCount = 4;
117 iree_hal_dim_t shape[1] = {kElementCount};
118 iree_hal_buffer_view_t* arg0_buffer_view = NULL;
119 iree_hal_buffer_view_t* arg1_buffer_view = NULL;
120 float kFloat4[] = {4.0f, 4.0f, 4.0f, 4.0f};
121 float kFloat2[] = {2.0f, 2.0f, 2.0f, 2.0f};
122
Kojo Acquah31357022021-07-16 15:55:31 -0700123 if (iree_status_is_ok(status)) {
Ben Vanik42b983c2023-08-15 21:31:09 -0700124 status = iree_hal_buffer_view_allocate_buffer_copy(
125 device, iree_hal_device_allocator(device), IREE_ARRAYSIZE(shape), shape,
Ben Vanike67c6602021-08-13 12:47:13 -0700126 IREE_HAL_ELEMENT_TYPE_FLOAT_32, IREE_HAL_ENCODING_TYPE_DENSE_ROW_MAJOR,
Scott Toddb4616002022-02-24 09:46:44 -0800127 (iree_hal_buffer_params_t){
Ben Vanik0339fa02022-04-05 10:44:33 -0700128 .type = IREE_HAL_MEMORY_TYPE_DEVICE_LOCAL,
Ben Vanik5844fd62022-06-13 08:45:41 -0700129 .usage = IREE_HAL_BUFFER_USAGE_DEFAULT,
Scott Toddb4616002022-02-24 09:46:44 -0800130 },
Kojo Acquah31357022021-07-16 15:55:31 -0700131 iree_make_const_byte_span((void*)kFloat4,
132 sizeof(float) * kElementCount),
133 &arg0_buffer_view);
134 }
135 if (iree_status_is_ok(status)) {
Ben Vanik42b983c2023-08-15 21:31:09 -0700136 status = iree_hal_buffer_view_allocate_buffer_copy(
137 device, iree_hal_device_allocator(device), IREE_ARRAYSIZE(shape), shape,
Ben Vanike67c6602021-08-13 12:47:13 -0700138 IREE_HAL_ELEMENT_TYPE_FLOAT_32, IREE_HAL_ENCODING_TYPE_DENSE_ROW_MAJOR,
Scott Toddb4616002022-02-24 09:46:44 -0800139 (iree_hal_buffer_params_t){
Ben Vanik0339fa02022-04-05 10:44:33 -0700140 .type = IREE_HAL_MEMORY_TYPE_DEVICE_LOCAL,
Ben Vanik5844fd62022-06-13 08:45:41 -0700141 .usage = IREE_HAL_BUFFER_USAGE_DEFAULT,
Scott Toddb4616002022-02-24 09:46:44 -0800142 },
Kojo Acquah31357022021-07-16 15:55:31 -0700143 iree_make_const_byte_span((void*)kFloat2,
144 sizeof(float) * kElementCount),
145 &arg1_buffer_view);
146 }
147
148 // Queue buffer views for input.
149 if (iree_status_is_ok(status)) {
150 status =
151 iree_runtime_call_inputs_push_back_buffer_view(&call, arg0_buffer_view);
152 }
153 iree_hal_buffer_view_release(arg0_buffer_view);
154
155 if (iree_status_is_ok(status)) {
156 status =
157 iree_runtime_call_inputs_push_back_buffer_view(&call, arg1_buffer_view);
158 }
159 iree_hal_buffer_view_release(arg1_buffer_view);
160
161 // Invoke call.
162 if (iree_status_is_ok(status)) {
163 status = iree_runtime_call_invoke(&call, /*flags=*/0);
164 }
165
Marius Brehler1b728942023-02-21 18:09:57 +0100166 // Retrieve output buffer view with results from the invocation.
Kojo Acquah31357022021-07-16 15:55:31 -0700167 iree_hal_buffer_view_t* ret_buffer_view = NULL;
168 if (iree_status_is_ok(status)) {
169 status = iree_runtime_call_outputs_pop_front_buffer_view(&call,
170 &ret_buffer_view);
171 }
172
173 // Read back the results and ensure we got the right values.
Ben Vanikfb9fb322021-12-15 18:35:12 -0800174 float results[] = {0.0f, 0.0f, 0.0f, 0.0f};
Kojo Acquah31357022021-07-16 15:55:31 -0700175 if (iree_status_is_ok(status)) {
Ben Vanik7536cb62022-03-15 15:52:07 -0700176 status = iree_hal_device_transfer_d2h(
177 device, iree_hal_buffer_view_buffer(ret_buffer_view), 0, results,
178 sizeof(results), IREE_HAL_TRANSFER_BUFFER_FLAG_DEFAULT,
179 iree_infinite_timeout());
Kojo Acquah31357022021-07-16 15:55:31 -0700180 }
181 if (iree_status_is_ok(status)) {
Ben Vanikfb9fb322021-12-15 18:35:12 -0800182 for (iree_host_size_t i = 0; i < IREE_ARRAYSIZE(results); ++i) {
183 if (results[i] != 8.0f) {
Kojo Acquah31357022021-07-16 15:55:31 -0700184 status = iree_make_status(IREE_STATUS_UNKNOWN, "result mismatches");
Ben Vanikfb9fb322021-12-15 18:35:12 -0800185 break;
Kojo Acquah31357022021-07-16 15:55:31 -0700186 }
187 }
188 }
189
190 // Cleanup call and buffers.
Kojo Acquah31357022021-07-16 15:55:31 -0700191 iree_hal_buffer_view_release(ret_buffer_view);
192 iree_runtime_call_deinitialize(&call);
193
194 // Cleanup session and instance.
195 iree_hal_device_release(device);
196 iree_runtime_session_release(session);
197 iree_runtime_instance_release(instance);
Simon Camphausen9928f892021-11-24 17:40:19 +0100198 iree_vm_module_release(module);
Kojo Acquah31357022021-07-16 15:55:31 -0700199
200 return status;
201}
202
203int main() {
204 const iree_status_t result = Run();
205 if (!iree_status_is_ok(result)) {
206 iree_status_fprint(stderr, result);
207 iree_status_free(result);
208 return -1;
209 }
Simon Camphausen9928f892021-11-24 17:40:19 +0100210 print_success();
Kojo Acquah31357022021-07-16 15:55:31 -0700211 return 0;
212}