Geoffrey Martin-Noble | 552d3f8 | 2021-05-25 17:56:09 -0700 | [diff] [blame] | 1 | // Copyright 2019 The IREE Authors |
powderluv | 2e2fc9c | 2019-10-23 10:09:44 -0700 | [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 |
powderluv | 2e2fc9c | 2019-10-23 10:09:44 -0700 | [diff] [blame] | 6 | |
Stella Laurenzo | 3b44a0a | 2022-04-18 19:57:57 -0700 | [diff] [blame] | 7 | #include "./vm.h" |
powderluv | 2e2fc9c | 2019-10-23 10:09:44 -0700 | [diff] [blame] | 8 | |
Stella Laurenzo | 3b44a0a | 2022-04-18 19:57:57 -0700 | [diff] [blame] | 9 | #include "./status_utils.h" |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 10 | #include "iree/base/api.h" |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 11 | // TODO: We shouldn't need the HAL API but it is used for direct printing |
| 12 | // summaries of HAL objects in lists. We should have a better way of doing this |
| 13 | // dynamically vs hard depending on a type switch here. |
Ben Vanik | 6ada293 | 2021-06-21 09:09:32 -0700 | [diff] [blame] | 14 | #include "iree/modules/hal/module.h" |
Eugene Zhulenev | 6f81ceb | 2023-05-16 19:23:26 -0700 | [diff] [blame] | 15 | #include "iree/tooling/modules/resolver.h" |
Ben Vanik | c3a13e6 | 2020-11-16 01:54:22 -0800 | [diff] [blame] | 16 | #include "iree/vm/api.h" |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 17 | #include "pybind11/numpy.h" |
powderluv | 2e2fc9c | 2019-10-23 10:09:44 -0700 | [diff] [blame] | 18 | |
| 19 | namespace iree { |
| 20 | namespace python { |
| 21 | |
Stella Laurenzo | edc8a98 | 2019-12-20 09:22:37 -0800 | [diff] [blame] | 22 | namespace { |
| 23 | |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 24 | // RAII wrapper for a Py_buffer which calls PyBuffer_Release when it goes |
| 25 | // out of scope. |
| 26 | class PyBufferReleaser { |
| 27 | public: |
| 28 | PyBufferReleaser(Py_buffer& b) : b_(b) {} |
| 29 | ~PyBufferReleaser() { PyBuffer_Release(&b_); } |
| 30 | |
| 31 | private: |
| 32 | Py_buffer& b_; |
| 33 | }; |
| 34 | |
| 35 | py::dict GetFunctionReflectionDict(iree_vm_function_t& f) { |
| 36 | py::dict attrs; |
Ben Vanik | 1d60c18 | 2022-06-28 12:37:40 -0700 | [diff] [blame] | 37 | for (iree_host_size_t i = 0;; ++i) { |
| 38 | iree_string_pair_t attr; |
| 39 | auto status = iree_vm_function_get_attr(f, i, &attr); |
| 40 | if (iree_status_is_out_of_range(status)) { |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 41 | iree_status_ignore(status); |
| 42 | break; |
| 43 | } |
| 44 | CheckApiStatus(status, "Error getting reflection attr"); |
Ben Vanik | 1d60c18 | 2022-06-28 12:37:40 -0700 | [diff] [blame] | 45 | py::str key_str(attr.key.data, attr.key.size); |
| 46 | py::str value_str(attr.value.data, attr.value.size); |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 47 | attrs[std::move(key_str)] = std::move(value_str); |
| 48 | } |
| 49 | return attrs; |
| 50 | } |
| 51 | |
Stella Laurenzo | edc8a98 | 2019-12-20 09:22:37 -0800 | [diff] [blame] | 52 | } // namespace |
| 53 | |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 54 | //------------------------------------------------------------------------------ |
| 55 | // VmInstance |
| 56 | //------------------------------------------------------------------------------ |
| 57 | |
| 58 | VmInstance VmInstance::Create() { |
Ben Vanik | cc43680 | 2023-06-10 08:53:52 -0700 | [diff] [blame] | 59 | IREE_TRACE_SCOPE_NAMED("VmInstance::Create"); |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 60 | |
| 61 | iree_vm_instance_t* instance = NULL; |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 62 | auto status = iree_vm_instance_create(IREE_VM_TYPE_CAPACITY_DEFAULT, |
| 63 | iree_allocator_system(), &instance); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 64 | CheckApiStatus(status, "Error creating instance"); |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 65 | |
| 66 | // The python bindings assume the HAL is always available for use. |
| 67 | // We register the types here so modules can be loaded using the HAL types |
| 68 | // in any order. |
| 69 | CheckApiStatus(iree_hal_module_register_all_types(instance), |
| 70 | "registering HAL types"); |
| 71 | |
Stella Laurenzo | 65690a1 | 2022-01-31 12:43:00 -0800 | [diff] [blame] | 72 | return VmInstance::StealFromRawPtr(instance); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | //------------------------------------------------------------------------------ |
| 76 | // VmContext |
| 77 | //------------------------------------------------------------------------------ |
| 78 | |
| 79 | VmContext VmContext::Create(VmInstance* instance, |
Ben Vanik | df89eb0 | 2021-06-20 18:01:16 -0700 | [diff] [blame] | 80 | std::optional<std::vector<VmModule*>> modules) { |
Ben Vanik | cc43680 | 2023-06-10 08:53:52 -0700 | [diff] [blame] | 81 | IREE_TRACE_SCOPE_NAMED("VmContext::Create"); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 82 | iree_vm_context_t* context; |
| 83 | if (!modules) { |
| 84 | // Simple create with open allowed modules. |
Ben Vanik | 89e9530 | 2021-10-05 17:05:39 -0700 | [diff] [blame] | 85 | auto status = |
| 86 | iree_vm_context_create(instance->raw_ptr(), IREE_VM_CONTEXT_FLAG_NONE, |
| 87 | iree_allocator_system(), &context); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 88 | CheckApiStatus(status, "Error creating vm context"); |
| 89 | } else { |
| 90 | // Closed set of modules. |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 91 | std::vector<iree_vm_module_t*> module_handles; |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 92 | module_handles.resize(modules->size()); |
| 93 | for (size_t i = 0, e = module_handles.size(); i < e; ++i) { |
| 94 | module_handles[i] = (*modules)[i]->raw_ptr(); |
| 95 | } |
| 96 | auto status = iree_vm_context_create_with_modules( |
Ben Vanik | 70c2bb0 | 2022-06-09 12:42:54 -0700 | [diff] [blame] | 97 | instance->raw_ptr(), IREE_VM_CONTEXT_FLAG_NONE, module_handles.size(), |
| 98 | module_handles.data(), iree_allocator_system(), &context); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 99 | CheckApiStatus(status, "Error creating vm context with modules"); |
| 100 | } |
| 101 | |
Ben Vanik | 91c75fb | 2022-06-23 19:08:12 -0700 | [diff] [blame] | 102 | IREE_ASSERT(context); |
Stella Laurenzo | 65690a1 | 2022-01-31 12:43:00 -0800 | [diff] [blame] | 103 | return VmContext::StealFromRawPtr(context); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | void VmContext::RegisterModules(std::vector<VmModule*> modules) { |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 107 | std::vector<iree_vm_module_t*> module_handles; |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 108 | module_handles.resize(modules.size()); |
| 109 | for (size_t i = 0, e = module_handles.size(); i < e; ++i) { |
| 110 | module_handles[i] = modules[i]->raw_ptr(); |
| 111 | } |
Ben Vanik | 70c2bb0 | 2022-06-09 12:42:54 -0700 | [diff] [blame] | 112 | auto status = iree_vm_context_register_modules( |
| 113 | raw_ptr(), module_handles.size(), &module_handles[0]); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 114 | CheckApiStatus(status, "Error registering modules"); |
| 115 | } |
| 116 | |
Stella Laurenzo | d5efc48 | 2019-12-21 04:59:36 -0800 | [diff] [blame] | 117 | void VmContext::Invoke(iree_vm_function_t f, VmVariantList& inputs, |
| 118 | VmVariantList& outputs) { |
Stella Laurenzo | d2009dc | 2022-03-08 17:59:40 -0800 | [diff] [blame] | 119 | iree_status_t status; |
| 120 | { |
| 121 | py::gil_scoped_release release; |
| 122 | status = iree_vm_invoke(raw_ptr(), f, IREE_VM_INVOCATION_FLAG_NONE, nullptr, |
| 123 | inputs.raw_ptr(), outputs.raw_ptr(), |
| 124 | iree_allocator_system()); |
| 125 | } |
| 126 | CheckApiStatus(status, "Error invoking function"); |
Stella Laurenzo | d5efc48 | 2019-12-21 04:59:36 -0800 | [diff] [blame] | 127 | } |
| 128 | |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 129 | //------------------------------------------------------------------------------ |
| 130 | // VmModule |
| 131 | //------------------------------------------------------------------------------ |
| 132 | |
Eugene Zhulenev | 6f81ceb | 2023-05-16 19:23:26 -0700 | [diff] [blame] | 133 | VmModule VmModule::ResolveModuleDependency(VmInstance* instance, |
| 134 | const std::string& name, |
| 135 | uint32_t minimum_version) { |
Ben Vanik | cc43680 | 2023-06-10 08:53:52 -0700 | [diff] [blame] | 136 | IREE_TRACE_SCOPE_NAMED("VmModule::ResolveModuleDependency"); |
Eugene Zhulenev | 6f81ceb | 2023-05-16 19:23:26 -0700 | [diff] [blame] | 137 | iree_vm_module_t* module = nullptr; |
| 138 | |
| 139 | iree_vm_module_dependency_t dependency = { |
| 140 | iree_make_cstring_view(name.c_str()), minimum_version, |
| 141 | IREE_VM_MODULE_DEPENDENCY_FLAG_REQUIRED}; |
| 142 | |
| 143 | auto status = iree_tooling_resolve_module_dependency( |
| 144 | instance->raw_ptr(), &dependency, iree_allocator_system(), &module); |
| 145 | |
| 146 | assert(module != nullptr); |
| 147 | |
| 148 | CheckApiStatus(status, "Error resolving module dependency"); |
| 149 | auto py_module = VmModule::StealFromRawPtr(module); |
| 150 | return py_module; |
| 151 | } |
| 152 | |
Stella Laurenzo | 3345b76 | 2023-06-15 00:22:24 -0700 | [diff] [blame] | 153 | VmModule VmModule::MMap(VmInstance* instance, std::string filepath) { |
| 154 | IREE_TRACE_SCOPE_NAMED("VmModule::MMap"); |
| 155 | auto mmap_module = py::module::import("mmap"); |
| 156 | auto open_func = py::module::import("io").attr("open"); |
| 157 | auto file_obj = open_func(filepath, "r+b"); |
| 158 | auto flags = py::cast<int64_t>(mmap_module.attr("MAP_SHARED")); |
| 159 | // MAP_POPULATE isn't available on all versions/platforms. |
| 160 | if (py::hasattr(mmap_module, "MAP_POPULATE")) { |
| 161 | flags |= py::cast<int64_t>(mmap_module.attr("MAP_POPULATE")); |
| 162 | } |
| 163 | auto prot = py::cast<int64_t>(mmap_module.attr("PROT_READ")); |
| 164 | auto mapped_file = |
| 165 | mmap_module.attr("mmap")(file_obj.attr("fileno")(), 0, flags, prot); |
| 166 | mapped_file.attr("madvise")(mmap_module.attr("MADV_RANDOM")); |
| 167 | return FromFlatbufferBlob(instance, mapped_file); |
| 168 | } |
| 169 | |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 170 | VmModule VmModule::FromFlatbufferBlob(VmInstance* instance, |
| 171 | py::object flatbuffer_blob_object) { |
Ben Vanik | cc43680 | 2023-06-10 08:53:52 -0700 | [diff] [blame] | 172 | IREE_TRACE_SCOPE_NAMED("VmModule::FromFlatbufferBlob"); |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 173 | auto flatbuffer_blob = py::cast<py::buffer>(flatbuffer_blob_object); |
Stella Laurenzo | e2b0d7f | 2020-01-06 13:14:40 -0800 | [diff] [blame] | 174 | auto buffer_info = flatbuffer_blob.request(); |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 175 | iree_vm_module_t* module = nullptr; |
Stella Laurenzo | e2b0d7f | 2020-01-06 13:14:40 -0800 | [diff] [blame] | 176 | |
| 177 | // Bridge to the C-based deallocator API. |
Kojo Acquah | c1d499e | 2023-05-25 07:01:25 -0700 | [diff] [blame] | 178 | PyObject* pyobject_ptr = flatbuffer_blob_object.ptr(); |
Ben Vanik | 5ca3e18 | 2021-07-12 07:46:23 -0700 | [diff] [blame] | 179 | auto ctl_fn = +([](void* self, iree_allocator_command_t command, |
| 180 | const void* params, void** inout_ptr) { |
| 181 | assert(command == IREE_ALLOCATOR_COMMAND_FREE); |
Kojo Acquah | c1d499e | 2023-05-25 07:01:25 -0700 | [diff] [blame] | 182 | PyObject* pyobject_ptr = static_cast<PyObject*>(self); |
| 183 | Py_XDECREF(pyobject_ptr); |
Ben Vanik | 5ca3e18 | 2021-07-12 07:46:23 -0700 | [diff] [blame] | 184 | return iree_ok_status(); |
Stella Laurenzo | e2b0d7f | 2020-01-06 13:14:40 -0800 | [diff] [blame] | 185 | }); |
Kojo Acquah | c1d499e | 2023-05-25 07:01:25 -0700 | [diff] [blame] | 186 | Py_XINCREF(pyobject_ptr); |
| 187 | iree_allocator_t deallocator{/*self=*/pyobject_ptr, /*ctl=*/ctl_fn}; |
Stella Laurenzo | e2b0d7f | 2020-01-06 13:14:40 -0800 | [diff] [blame] | 188 | |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 189 | auto status = iree_vm_bytecode_module_create( |
Ben Vanik | 9aa83ed | 2022-08-06 12:55:34 -0700 | [diff] [blame] | 190 | instance->raw_ptr(), |
Stella Laurenzo | e2b0d7f | 2020-01-06 13:14:40 -0800 | [diff] [blame] | 191 | {static_cast<const uint8_t*>(buffer_info.ptr), |
| 192 | static_cast<iree_host_size_t>(buffer_info.size)}, |
Ben Vanik | f5bd6fd | 2020-08-05 21:14:57 -0700 | [diff] [blame] | 193 | deallocator, iree_allocator_system(), &module); |
Ben Vanik | af5401f | 2020-08-06 21:31:15 -0700 | [diff] [blame] | 194 | if (!iree_status_is_ok(status)) { |
Kojo Acquah | c1d499e | 2023-05-25 07:01:25 -0700 | [diff] [blame] | 195 | Py_XDECREF(pyobject_ptr); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 196 | } |
| 197 | |
Ben Vanik | 9a50ab1 | 2022-05-26 14:20:59 -0700 | [diff] [blame] | 198 | CheckApiStatus(status, "Error creating vm module from FlatBuffer"); |
Stella Laurenzo | 65690a1 | 2022-01-31 12:43:00 -0800 | [diff] [blame] | 199 | auto py_module = VmModule::StealFromRawPtr(module); |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 200 | py_module.stashed_flatbuffer_blob = flatbuffer_blob_object; |
| 201 | return py_module; |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 202 | } |
| 203 | |
Ben Vanik | df89eb0 | 2021-06-20 18:01:16 -0700 | [diff] [blame] | 204 | std::optional<iree_vm_function_t> VmModule::LookupFunction( |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 205 | const std::string& name, iree_vm_function_linkage_t linkage) { |
| 206 | iree_vm_function_t f; |
Ben Vanik | fcd368b | 2019-12-20 10:55:37 -0800 | [diff] [blame] | 207 | auto status = iree_vm_module_lookup_function_by_name( |
Scott Todd | 60b0764 | 2023-06-15 09:41:01 -0700 | [diff] [blame^] | 208 | raw_ptr(), linkage, |
| 209 | {name.data(), static_cast<iree_host_size_t>(name.size())}, &f); |
Ben Vanik | af5401f | 2020-08-06 21:31:15 -0700 | [diff] [blame] | 210 | if (iree_status_is_not_found(status)) { |
| 211 | iree_status_ignore(status); |
Ben Vanik | df89eb0 | 2021-06-20 18:01:16 -0700 | [diff] [blame] | 212 | return std::nullopt; |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 213 | } |
| 214 | CheckApiStatus(status, "Error looking up function"); |
| 215 | return f; |
| 216 | } |
| 217 | |
Stella Laurenzo | 480e6ef | 2019-12-23 10:07:52 -0800 | [diff] [blame] | 218 | //------------------------------------------------------------------------------ |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 219 | // VmRef |
| 220 | //------------------------------------------------------------------------------ |
| 221 | |
| 222 | const char* const VmRef::kRefAttr = "__iree_vm_ref__"; |
| 223 | const char* const VmRef::kCastAttr = "__iree_vm_cast__"; |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 224 | const char* const VmRef::kTypeAttr = "__iree_vm_type__"; |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 225 | |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 226 | py::object VmRef::Deref(py::object ref_object_class, bool optional) { |
| 227 | py::object casted = ref_object_class.attr(kCastAttr)(*this); |
| 228 | if (!optional && casted.is_none()) { |
| 229 | throw py::type_error("Cannot dereference to specific type"); |
| 230 | } |
| 231 | return casted; |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | bool VmRef::IsInstance(py::object ref_object_class) { |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 235 | auto type = py::cast<iree_vm_ref_type_t>(ref_object_class.attr(kTypeAttr)()); |
| 236 | return type == ref_.type; |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 237 | } |
| 238 | |
| 239 | std::string VmRef::ToString() { |
| 240 | if (!ref_.ptr) { |
| 241 | return "<VmRef NULL>"; |
| 242 | } |
| 243 | iree_string_view_t type_name = iree_vm_ref_type_name(ref_.type); |
| 244 | std::stringstream ss; |
| 245 | ss << "<VmRef "; |
| 246 | ss.write(type_name.data, type_name.size); |
| 247 | ss << " at " << std::hex << "0x" << reinterpret_cast<uintptr_t>(ref_.ptr) |
| 248 | << ">"; |
| 249 | return ss.str(); |
| 250 | } |
| 251 | |
| 252 | //------------------------------------------------------------------------------ |
Stella Laurenzo | 480e6ef | 2019-12-23 10:07:52 -0800 | [diff] [blame] | 253 | // VmVariantList |
| 254 | //------------------------------------------------------------------------------ |
| 255 | |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 256 | void VmVariantList::PushFloat(double fvalue) { |
| 257 | // Note that Python floats are f64. |
| 258 | iree_vm_value_t value = iree_vm_value_make_f64(fvalue); |
| 259 | CheckApiStatus(iree_vm_list_push_value(raw_ptr(), &value), |
| 260 | "Could not push float"); |
| 261 | } |
| 262 | |
| 263 | void VmVariantList::PushInt(int64_t ivalue) { |
| 264 | // Note that Python ints are unbounded, so just use the largest type we |
| 265 | // have. |
| 266 | iree_vm_value_t value = iree_vm_value_make_i64(ivalue); |
| 267 | CheckApiStatus(iree_vm_list_push_value(raw_ptr(), &value), |
| 268 | "Could not push int"); |
| 269 | } |
| 270 | |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 271 | void VmVariantList::PushList(VmVariantList& other) { |
| 272 | iree_vm_ref_t retained = iree_vm_list_retain_ref(other.raw_ptr()); |
| 273 | iree_vm_list_push_ref_move(raw_ptr(), &retained); |
| 274 | } |
| 275 | |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 276 | void VmVariantList::PushRef(py::handle ref_or_object) { |
| 277 | py::object py_ref = ref_or_object.attr(VmRef::kRefAttr); |
| 278 | VmRef& ref = py::cast<VmRef&>(py_ref); |
| 279 | CheckApiStatus(iree_vm_list_push_ref_retain(raw_ptr(), &ref.ref()), |
| 280 | "Failed to push ref"); |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 281 | } |
| 282 | |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 283 | py::object VmVariantList::GetAsList(int index) { |
Stella Laurenzo | 5ba8a7a | 2021-05-11 21:29:23 -0700 | [diff] [blame] | 284 | iree_vm_ref_t ref = {0}; |
| 285 | CheckApiStatus(iree_vm_list_get_ref_assign(raw_ptr(), index, &ref), |
| 286 | "Could not access list element"); |
| 287 | iree_vm_list_t* sub_list = NULL; |
| 288 | CheckApiStatus(iree_vm_list_check_deref(ref, &sub_list), |
| 289 | "Could not deref list (wrong type?)"); |
| 290 | iree_vm_list_retain(sub_list); |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 291 | return py::cast(VmVariantList::StealFromRawPtr(sub_list)); |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 292 | } |
| 293 | |
| 294 | py::object VmVariantList::GetVariant(int index) { |
| 295 | iree_vm_variant_t v = iree_vm_variant_empty(); |
Ben Vanik | 78fc0e3 | 2023-03-06 16:20:08 -0800 | [diff] [blame] | 296 | CheckApiStatus(iree_vm_list_get_variant_assign(raw_ptr(), index, &v), |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 297 | "Could not access list element"); |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 298 | if (iree_vm_variant_is_empty(v)) { |
| 299 | return py::none(); |
| 300 | } else if (iree_vm_variant_is_value(v)) { |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 301 | // Convert a value type. |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 302 | switch (iree_vm_type_def_as_value(v.type)) { |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 303 | case IREE_VM_VALUE_TYPE_I8: |
| 304 | return py::cast(v.i8); |
| 305 | case IREE_VM_VALUE_TYPE_I16: |
| 306 | return py::cast(v.i16); |
| 307 | case IREE_VM_VALUE_TYPE_I32: |
| 308 | return py::cast(v.i32); |
| 309 | case IREE_VM_VALUE_TYPE_I64: |
| 310 | return py::cast(v.i64); |
| 311 | case IREE_VM_VALUE_TYPE_F32: |
| 312 | return py::cast(v.f32); |
| 313 | case IREE_VM_VALUE_TYPE_F64: |
| 314 | return py::cast(v.f64); |
| 315 | default: |
| 316 | throw RaiseValueError("Unsupported VM value type conversion"); |
| 317 | } |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 318 | } else if (iree_vm_variant_is_ref(v)) { |
| 319 | VmRef ref; |
| 320 | iree_vm_ref_retain(&v.ref, &ref.ref()); |
| 321 | return py::cast(ref, py::return_value_policy::move); |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | throw RaiseValueError("Unsupported VM to Python Type Conversion"); |
Stella Laurenzo | 5ba8a7a | 2021-05-11 21:29:23 -0700 | [diff] [blame] | 325 | } |
| 326 | |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 327 | py::object VmVariantList::GetAsSerializedTraceValue(int index) { |
| 328 | iree_vm_variant_t v = iree_vm_variant_empty(); |
Ben Vanik | 78fc0e3 | 2023-03-06 16:20:08 -0800 | [diff] [blame] | 329 | CheckApiStatus(iree_vm_list_get_variant_assign(raw_ptr(), index, &v), |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 330 | "Could not access list element"); |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 331 | if (iree_vm_variant_is_empty(v)) { |
| 332 | py::dict record; |
| 333 | record["type"] = "null"; |
| 334 | return std::move(record); |
| 335 | } else if (iree_vm_variant_is_value(v)) { |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 336 | // Convert a value type. |
| 337 | py::dict record; |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 338 | switch (iree_vm_type_def_as_value(v.type)) { |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 339 | case IREE_VM_VALUE_TYPE_I8: |
| 340 | record["i8"] = py::cast(v.i8); |
| 341 | break; |
| 342 | case IREE_VM_VALUE_TYPE_I16: |
| 343 | record["i16"] = py::cast(v.i16); |
| 344 | break; |
| 345 | case IREE_VM_VALUE_TYPE_I32: |
| 346 | record["i32"] = py::cast(v.i32); |
| 347 | break; |
| 348 | case IREE_VM_VALUE_TYPE_I64: |
| 349 | record["i64"] = py::cast(v.i64); |
| 350 | break; |
| 351 | case IREE_VM_VALUE_TYPE_F32: |
| 352 | record["f32"] = py::cast(v.f32); |
| 353 | break; |
| 354 | case IREE_VM_VALUE_TYPE_F64: |
| 355 | record["f64"] = py::cast(v.f64); |
| 356 | break; |
| 357 | default: |
| 358 | throw RaiseValueError("Unsupported VM value type conversion"); |
| 359 | } |
| 360 | record["type"] = py::cast("value"); |
| 361 | return std::move(record); |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 362 | } else if (iree_vm_variant_is_ref(v)) { |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 363 | // Convert reference type. |
| 364 | if (iree_vm_list_isa(v.ref)) { |
| 365 | py::dict record; |
Ben Vanik | abe6c76 | 2021-06-27 21:57:07 -0700 | [diff] [blame] | 366 | record["type"] = "vm.list"; |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 367 | py::list items; |
| 368 | iree_vm_list_t* sub_list = NULL; |
| 369 | CheckApiStatus(iree_vm_list_check_deref(v.ref, &sub_list), |
| 370 | "Could not deref list (wrong type?)"); |
| 371 | iree_vm_list_retain(sub_list); |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 372 | VmVariantList sub_list_object = VmVariantList::StealFromRawPtr(sub_list); |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 373 | for (int i = 0, e = sub_list_object.size(); i < e; ++i) { |
| 374 | items.append(sub_list_object.GetAsSerializedTraceValue(i)); |
| 375 | } |
| 376 | record["items"] = std::move(items); |
| 377 | return std::move(record); |
| 378 | } else if (iree_hal_buffer_view_isa(v.ref)) { |
| 379 | py::dict record; |
Ben Vanik | abe6c76 | 2021-06-27 21:57:07 -0700 | [diff] [blame] | 380 | record["type"] = "hal.buffer_view"; |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 381 | iree_hal_buffer_view_t* buffer_view = iree_hal_buffer_view_deref(v.ref); |
| 382 | if (!buffer_view) { |
| 383 | throw RaiseValueError( |
| 384 | "Could not deref result buffer view (wrong type?)"); |
| 385 | } |
| 386 | iree_hal_buffer_t* raw_buffer = iree_hal_buffer_view_buffer(buffer_view); |
| 387 | if (!raw_buffer) { |
| 388 | throw RaiseValueError("Could not deref result buffer (wrong type?)"); |
| 389 | } |
| 390 | |
| 391 | // Extract dims from the buffer view. |
Scott Todd | 60b0764 | 2023-06-15 09:41:01 -0700 | [diff] [blame^] | 392 | iree_host_size_t rank = 0; |
Ben Vanik | 49fee30 | 2022-05-16 21:18:59 -0700 | [diff] [blame] | 393 | std::vector<iree_hal_dim_t> dims(6); |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 394 | iree_status_t status = iree_hal_buffer_view_shape( |
| 395 | buffer_view, dims.capacity(), dims.data(), &rank); |
| 396 | if (iree_status_is_out_of_range(status)) { |
| 397 | dims.resize(rank); |
| 398 | status = iree_hal_buffer_view_shape(buffer_view, dims.capacity(), |
| 399 | dims.data(), &rank); |
| 400 | } |
| 401 | CheckApiStatus(status, "Error extracting shape"); |
| 402 | dims.resize(rank); |
| 403 | record["shape"] = py::cast(std::move(dims)); |
| 404 | |
| 405 | // Element type. |
| 406 | iree_hal_element_type_t element_type = |
| 407 | iree_hal_buffer_view_element_type(buffer_view); |
Ben Vanik | 40876b9 | 2023-03-06 11:26:53 -0800 | [diff] [blame] | 408 | char element_type_str[64] = {0}; |
| 409 | iree_host_size_t element_type_length = 0; |
| 410 | CheckApiStatus( |
| 411 | iree_hal_format_element_type(element_type, sizeof(element_type_str), |
| 412 | element_type_str, &element_type_length), |
| 413 | "Formatting element type"); |
| 414 | record["element_type"] = |
| 415 | std::string(element_type_str, element_type_length); |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 416 | |
| 417 | // Map memory. |
| 418 | iree_device_size_t byte_length = iree_hal_buffer_byte_length(raw_buffer); |
Ben Vanik | eff1bb5 | 2021-12-16 11:04:21 -0800 | [diff] [blame] | 419 | iree_hal_buffer_mapping_t mapped_memory = {{0}}; |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 420 | CheckApiStatus(iree_hal_buffer_map_range( |
Ben Vanik | b036c63 | 2021-12-14 14:21:16 -0800 | [diff] [blame] | 421 | raw_buffer, IREE_HAL_MAPPING_MODE_SCOPED, |
| 422 | IREE_HAL_MEMORY_ACCESS_READ, 0 /* element_offset */, |
| 423 | byte_length, &mapped_memory), |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 424 | "Could not map memory"); |
| 425 | record["contents"] = |
| 426 | py::bytes(reinterpret_cast<const char*>(mapped_memory.contents.data), |
| 427 | mapped_memory.contents.data_length); |
| 428 | iree_hal_buffer_unmap_range(&mapped_memory); |
| 429 | |
| 430 | return std::move(record); |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | throw RaiseValueError("Unsupported VM to Python Type Conversion"); |
| 435 | } |
| 436 | |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 437 | py::object VmVariantList::GetAsRef(int index) { |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 438 | iree_vm_variant_t v = iree_vm_variant_empty(); |
Ben Vanik | 78fc0e3 | 2023-03-06 16:20:08 -0800 | [diff] [blame] | 439 | CheckApiStatus(iree_vm_list_get_variant_assign(raw_ptr(), index, &v), |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 440 | "Could not access list element"); |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 441 | if (!iree_vm_variant_is_ref(v)) { |
| 442 | throw std::invalid_argument("list element is not a ref"); |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 443 | } |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 444 | VmRef ref; |
| 445 | iree_vm_ref_retain(&v.ref, &ref.ref()); |
| 446 | return py::cast(ref, py::return_value_policy::move); |
| 447 | } |
| 448 | |
| 449 | py::object VmVariantList::GetAsObject(int index, py::object clazz) { |
| 450 | return clazz.attr(VmRef::kCastAttr)(GetAsRef(index)); |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 451 | } |
| 452 | |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 453 | namespace { |
| 454 | |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 455 | static std::string ToHexString(const uint8_t* data, size_t length) { |
| 456 | static constexpr char kHexChars[] = {'0', '1', '2', '3', '4', '5', '6', '7', |
| 457 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; |
| 458 | std::string s(length * 2, ' '); |
| 459 | for (size_t i = 0; i < length; ++i) { |
| 460 | s[2 * i + 0] = kHexChars[(data[i] & 0xF0) >> 4]; |
| 461 | s[2 * i + 1] = kHexChars[(data[i] & 0x0F) >> 0]; |
| 462 | } |
| 463 | return s; |
| 464 | } |
| 465 | static std::string ToHexString(uint32_t value) { |
| 466 | return ToHexString((const uint8_t*)&value, sizeof(value)); |
| 467 | } |
| 468 | |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 469 | void AppendListContents(std::string& out, iree_vm_list_t* list, |
| 470 | std::unordered_set<iree_vm_list_t*>& visited) { |
| 471 | for (iree_host_size_t i = 0, e = iree_vm_list_size(list); i < e; ++i) { |
| 472 | iree_vm_variant_t variant = iree_vm_variant_empty(); |
Ben Vanik | 78fc0e3 | 2023-03-06 16:20:08 -0800 | [diff] [blame] | 473 | iree_status_t status = iree_vm_list_get_variant_assign(list, i, &variant); |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 474 | if (!iree_status_is_ok(status)) { |
| 475 | iree_status_ignore(status); |
| 476 | out.append("Error"); |
| 477 | continue; |
| 478 | } |
| 479 | if (i > 0) out.append(", "); |
| 480 | |
| 481 | if (iree_vm_variant_is_value(variant)) { |
Sean Silva | bef60b4 | 2021-09-09 20:51:05 -0700 | [diff] [blame] | 482 | // Convert a value type to a string. |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 483 | switch (iree_vm_type_def_as_value(variant.type)) { |
Sean Silva | bef60b4 | 2021-09-09 20:51:05 -0700 | [diff] [blame] | 484 | case IREE_VM_VALUE_TYPE_I8: { |
| 485 | out += std::to_string(variant.i8); |
| 486 | break; |
| 487 | } |
| 488 | case IREE_VM_VALUE_TYPE_I16: { |
| 489 | out += std::to_string(variant.i16); |
| 490 | break; |
| 491 | } |
| 492 | case IREE_VM_VALUE_TYPE_I32: { |
| 493 | out += std::to_string(variant.i32); |
| 494 | break; |
| 495 | } |
| 496 | case IREE_VM_VALUE_TYPE_I64: { |
| 497 | out += std::to_string(variant.i64); |
| 498 | break; |
| 499 | } |
| 500 | case IREE_VM_VALUE_TYPE_F32: { |
| 501 | out += std::to_string(variant.f32); |
| 502 | break; |
| 503 | } |
| 504 | case IREE_VM_VALUE_TYPE_F64: { |
| 505 | out += std::to_string(variant.f64); |
| 506 | break; |
| 507 | } |
| 508 | default: |
| 509 | throw RaiseValueError("Unsupported VM value type to string"); |
| 510 | } |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 511 | } else if (iree_vm_variant_is_ref(variant)) { |
| 512 | // Pretty print a subset of ABI impacting known types. |
| 513 | if (iree_hal_buffer_isa(variant.ref)) { |
| 514 | auto* hal_buffer = iree_hal_buffer_deref(variant.ref); |
| 515 | assert(hal_buffer); |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 516 | out += std::string("HalBuffer(") + |
| 517 | std::to_string(iree_hal_buffer_byte_length(hal_buffer)) + ")"; |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 518 | } else if (iree_hal_buffer_view_isa(variant.ref)) { |
| 519 | auto hal_bv = iree_hal_buffer_view_deref(variant.ref); |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 520 | out += "HalBufferView("; |
Ben Vanik | 49fee30 | 2022-05-16 21:18:59 -0700 | [diff] [blame] | 521 | std::vector<iree_hal_dim_t> shape( |
| 522 | iree_hal_buffer_view_shape_rank(hal_bv)); |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 523 | iree_hal_buffer_view_shape(hal_bv, shape.size(), shape.data(), nullptr); |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 524 | for (size_t i = 0; i < shape.size(); ++i) { |
| 525 | if (i > 0) out += 'x'; |
| 526 | out += std::to_string(shape[i]); |
| 527 | } |
| 528 | out += ":0x" + |
| 529 | ToHexString(static_cast<uint32_t>( |
| 530 | iree_hal_buffer_view_element_type(hal_bv))) + |
| 531 | ")"; |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 532 | } else if (iree_vm_list_isa(variant.ref)) { |
| 533 | out.append("List["); |
| 534 | iree_vm_list_t* sub_list = iree_vm_list_deref(variant.ref); |
| 535 | if (visited.insert(sub_list).second) { |
| 536 | AppendListContents(out, sub_list, visited); |
| 537 | } else { |
| 538 | out.append("...circular..."); |
| 539 | } |
| 540 | out.append("]"); |
| 541 | } else { |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 542 | out += "Unknown(" + |
| 543 | std::to_string(iree_vm_type_def_as_ref(variant.type)) + ")"; |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 544 | } |
| 545 | } else { |
| 546 | out.append("None"); |
| 547 | } |
| 548 | } |
| 549 | } |
| 550 | |
| 551 | } // namespace |
| 552 | |
Stella Laurenzo | 480e6ef | 2019-12-23 10:07:52 -0800 | [diff] [blame] | 553 | std::string VmVariantList::DebugString() const { |
| 554 | // The variant list API requires mutability, so we const cast to it internally |
| 555 | // so we can maintain a const DebugString() for callers. |
| 556 | auto mutable_this = const_cast<VmVariantList*>(this); |
Ben Vanik | b9b794b | 2021-06-19 20:11:08 -0700 | [diff] [blame] | 557 | std::string s = |
| 558 | std::string("<VmVariantList(") + std::to_string(size()) + "): ["; |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 559 | iree_vm_list_t* list = mutable_this->raw_ptr(); |
| 560 | std::unordered_set<iree_vm_list_t*> visited; |
| 561 | visited.insert(list); |
| 562 | AppendListContents(s, list, visited); |
| 563 | s.append("]>"); |
Stella Laurenzo | 480e6ef | 2019-12-23 10:07:52 -0800 | [diff] [blame] | 564 | return s; |
| 565 | } |
| 566 | |
powderluv | 2e2fc9c | 2019-10-23 10:09:44 -0700 | [diff] [blame] | 567 | void SetupVmBindings(pybind11::module m) { |
Ben Vanik | 4c0a53e | 2020-06-16 10:33:19 -0700 | [diff] [blame] | 568 | py::enum_<enum iree_vm_function_linkage_e>(m, "Linkage") |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 569 | .value("INTERNAL", IREE_VM_FUNCTION_LINKAGE_INTERNAL) |
| 570 | .value("IMPORT", IREE_VM_FUNCTION_LINKAGE_IMPORT) |
Ben Vanik | 79495f4 | 2022-04-18 10:49:21 -0700 | [diff] [blame] | 571 | .value("IMPORT_OPTIONAL", IREE_VM_FUNCTION_LINKAGE_IMPORT_OPTIONAL) |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 572 | .value("EXPORT", IREE_VM_FUNCTION_LINKAGE_EXPORT) |
| 573 | .export_values(); |
| 574 | |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 575 | auto vm_buffer = py::class_<VmBuffer>(m, "VmBuffer", py::buffer_protocol()); |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 576 | VmRef::BindRefProtocol(vm_buffer, iree_vm_buffer_type, |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 577 | iree_vm_buffer_retain_ref, iree_vm_buffer_deref, |
| 578 | iree_vm_buffer_isa); |
| 579 | vm_buffer |
Ben Vanik | 3e6130e | 2023-03-04 12:41:21 -0800 | [diff] [blame] | 580 | .def(py::init([](iree_host_size_t length, iree_host_size_t alignment, |
| 581 | bool is_mutable) { |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 582 | iree_vm_buffer_access_t access = 0; |
| 583 | if (is_mutable) { |
| 584 | access |= IREE_VM_BUFFER_ACCESS_MUTABLE; |
| 585 | } |
| 586 | iree_vm_buffer_t* raw_buffer; |
| 587 | CheckApiStatus( |
Ben Vanik | 3e6130e | 2023-03-04 12:41:21 -0800 | [diff] [blame] | 588 | iree_vm_buffer_create(access, length, alignment, |
| 589 | iree_allocator_system(), &raw_buffer), |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 590 | "Error creating buffer"); |
| 591 | return VmBuffer::StealFromRawPtr(raw_buffer); |
| 592 | }), |
Ben Vanik | 3e6130e | 2023-03-04 12:41:21 -0800 | [diff] [blame] | 593 | py::arg("length"), py::arg("alignment") = 0, |
| 594 | py::arg("mutable") = true) |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 595 | .def_buffer([](VmBuffer& self) -> py::buffer_info { |
| 596 | return py::buffer_info( |
| 597 | /*ptr=*/self.raw_ptr()->data.data, |
| 598 | /*itemsize=*/sizeof(uint8_t), |
| 599 | /*format=*/py::format_descriptor<uint8_t>::format(), |
| 600 | /*ndim=*/1, |
| 601 | /*shape=*/{self.raw_ptr()->data.data_length}, |
| 602 | /*strides=*/{1}, |
| 603 | /*readonly=*/ |
| 604 | !(self.raw_ptr()->access & IREE_VM_BUFFER_ACCESS_MUTABLE)); |
| 605 | }) |
| 606 | .def("__repr__", [](VmBuffer& self) { |
| 607 | std::stringstream ss; |
| 608 | ss << "<VmBuffer size " << self.raw_ptr()->data.data_length << " at 0x" |
| 609 | << std::hex << reinterpret_cast<uintptr_t>(self.raw_ptr()->data.data) |
| 610 | << ">"; |
| 611 | return ss.str(); |
| 612 | }); |
| 613 | |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 614 | // Mutation and inspection of the variant list is mostly opaque to python. |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 615 | auto vm_list = py::class_<VmVariantList>(m, "VmVariantList"); |
Ben Vanik | 09630d6 | 2023-04-13 14:21:40 -0700 | [diff] [blame] | 616 | VmRef::BindRefProtocol(vm_list, iree_vm_list_type, iree_vm_list_retain_ref, |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 617 | iree_vm_list_deref, iree_vm_list_isa); |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 618 | vm_list |
| 619 | // User Methods. |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 620 | .def(py::init(&VmVariantList::Create)) |
Stella Laurenzo | 480e6ef | 2019-12-23 10:07:52 -0800 | [diff] [blame] | 621 | .def_property_readonly("size", &VmVariantList::size) |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 622 | .def("__len__", &VmVariantList::size) |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 623 | .def("get_as_ref", &VmVariantList::GetAsRef) |
| 624 | .def("get_as_object", &VmVariantList::GetAsObject) |
Stella Laurenzo | 5ba8a7a | 2021-05-11 21:29:23 -0700 | [diff] [blame] | 625 | .def("get_as_list", &VmVariantList::GetAsList) |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 626 | .def("get_variant", &VmVariantList::GetVariant) |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 627 | .def("get_serialized_trace_value", |
| 628 | &VmVariantList::GetAsSerializedTraceValue) |
Stella Laurenzo | 9995604 | 2021-05-14 10:32:38 -0700 | [diff] [blame] | 629 | .def("push_float", &VmVariantList::PushFloat) |
| 630 | .def("push_int", &VmVariantList::PushInt) |
Stella Laurenzo | 397c4fc | 2021-05-08 00:19:22 -0700 | [diff] [blame] | 631 | .def("push_list", &VmVariantList::PushList) |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 632 | .def("push_ref", &VmVariantList::PushRef) |
Stella Laurenzo | 480e6ef | 2019-12-23 10:07:52 -0800 | [diff] [blame] | 633 | .def("__repr__", &VmVariantList::DebugString); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 634 | |
| 635 | py::class_<iree_vm_function_t>(m, "VmFunction") |
Stella Laurenzo | d5efc48 | 2019-12-21 04:59:36 -0800 | [diff] [blame] | 636 | .def_readonly("linkage", &iree_vm_function_t::linkage) |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 637 | .def_readonly("ordinal", &iree_vm_function_t::ordinal) |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 638 | .def_property_readonly("name", |
| 639 | [](iree_vm_function_t& self) { |
| 640 | iree_string_view_t name = |
| 641 | iree_vm_function_name(&self); |
| 642 | return py::str(name.data, name.size); |
| 643 | }) |
| 644 | .def_property_readonly("module_name", |
| 645 | [](iree_vm_function_t& self) { |
| 646 | iree_string_view_t name = |
| 647 | iree_vm_module_name(self.module); |
| 648 | return py::str(name.data, name.size); |
| 649 | }) |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 650 | .def_property_readonly("reflection", |
| 651 | [](iree_vm_function_t& self) { |
| 652 | return GetFunctionReflectionDict(self); |
| 653 | }) |
| 654 | .def("__repr__", [](iree_vm_function_t& self) { |
| 655 | iree_string_view_t name = iree_vm_function_name(&self); |
| 656 | std::string repr("<VmFunction "); |
| 657 | repr.append(name.data, name.size); |
| 658 | |
| 659 | iree_vm_function_signature_t sig = iree_vm_function_signature(&self); |
| 660 | repr.append("("); |
| 661 | repr.append(sig.calling_convention.data, sig.calling_convention.size); |
| 662 | repr.append("), reflection = "); |
| 663 | py::dict reflection = GetFunctionReflectionDict(self); |
| 664 | repr.append(py::cast<std::string>(py::repr(reflection))); |
| 665 | repr.append(">"); |
| 666 | return repr; |
| 667 | }); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 668 | |
| 669 | py::class_<VmInstance>(m, "VmInstance").def(py::init(&VmInstance::Create)); |
| 670 | |
| 671 | py::class_<VmContext>(m, "VmContext") |
| 672 | .def(py::init(&VmContext::Create), py::arg("instance"), |
Ben Vanik | df89eb0 | 2021-06-20 18:01:16 -0700 | [diff] [blame] | 673 | py::arg("modules") = std::optional<std::vector<VmModule*>>()) |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 674 | .def("register_modules", &VmContext::RegisterModules) |
Stella Laurenzo | d5efc48 | 2019-12-21 04:59:36 -0800 | [diff] [blame] | 675 | .def_property_readonly("context_id", &VmContext::context_id) |
Stella Laurenzo | d5efc48 | 2019-12-21 04:59:36 -0800 | [diff] [blame] | 676 | .def("invoke", &VmContext::Invoke); |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 677 | |
| 678 | py::class_<VmModule>(m, "VmModule") |
Eugene Zhulenev | 6f81ceb | 2023-05-16 19:23:26 -0700 | [diff] [blame] | 679 | .def_static("resolve_module_dependency", |
| 680 | &VmModule::ResolveModuleDependency) |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 681 | .def_static("from_flatbuffer", &VmModule::FromFlatbufferBlob) |
Stella Laurenzo | 3345b76 | 2023-06-15 00:22:24 -0700 | [diff] [blame] | 682 | .def_static("mmap", &VmModule::MMap) |
Stella Laurenzo | 449e7e5 | 2019-12-23 14:24:38 -0800 | [diff] [blame] | 683 | .def_property_readonly("name", &VmModule::name) |
Ben Vanik | 6b8387c | 2022-08-08 12:26:17 -0700 | [diff] [blame] | 684 | .def_property_readonly("version", |
| 685 | [](VmModule& self) { |
| 686 | iree_vm_module_signature_t sig = |
| 687 | iree_vm_module_signature(self.raw_ptr()); |
| 688 | return sig.version; |
| 689 | }) |
Stella Laurenzo | dc513de | 2019-12-19 10:19:57 -0800 | [diff] [blame] | 690 | .def("lookup_function", &VmModule::LookupFunction, py::arg("name"), |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 691 | py::arg("linkage") = IREE_VM_FUNCTION_LINKAGE_EXPORT) |
Stella Laurenzo | 7304521 | 2021-06-25 16:18:57 -0700 | [diff] [blame] | 692 | .def_property_readonly( |
| 693 | "stashed_flatbuffer_blob", |
| 694 | [](VmModule& self) { return self.get_stashed_flatbuffer_blob(); }) |
Stella Laurenzo | c459808 | 2021-10-05 12:46:52 -0700 | [diff] [blame] | 695 | .def_property_readonly( |
| 696 | "function_names", |
| 697 | [](VmModule& self) { |
| 698 | py::list names; |
| 699 | iree_vm_module_signature_t sig = |
| 700 | iree_vm_module_signature(self.raw_ptr()); |
| 701 | for (size_t ordinal = 0; ordinal < sig.export_function_count; |
| 702 | ++ordinal) { |
| 703 | iree_vm_function_t f; |
Stella Laurenzo | c459808 | 2021-10-05 12:46:52 -0700 | [diff] [blame] | 704 | auto status = iree_vm_module_lookup_function_by_ordinal( |
Ben Vanik | 71904de | 2021-10-05 15:57:07 -0700 | [diff] [blame] | 705 | self.raw_ptr(), IREE_VM_FUNCTION_LINKAGE_EXPORT, ordinal, &f); |
Stella Laurenzo | c459808 | 2021-10-05 12:46:52 -0700 | [diff] [blame] | 706 | if (iree_status_is_not_found(status)) { |
| 707 | iree_status_ignore(status); |
| 708 | break; |
| 709 | } |
| 710 | CheckApiStatus(status, "Error enumerating module"); |
| 711 | iree_string_view_t fname = iree_vm_function_name(&f); |
| 712 | py::str name(fname.data, fname.size); |
| 713 | names.append(name); |
| 714 | } |
| 715 | return names; |
| 716 | }) |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 717 | .def("__repr__", [](VmModule& self) { |
| 718 | std::string repr("<VmModule "); |
| 719 | iree_string_view_t name = iree_vm_module_name(self.raw_ptr()); |
| 720 | repr.append(name.data, name.size); |
| 721 | |
| 722 | iree_vm_module_signature_t sig = |
| 723 | iree_vm_module_signature(self.raw_ptr()); |
| 724 | repr.append(" : ["); |
| 725 | for (size_t ordinal = 0; ordinal < sig.export_function_count; |
| 726 | ++ordinal) { |
| 727 | iree_vm_function_t f; |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 728 | auto status = iree_vm_module_lookup_function_by_ordinal( |
Ben Vanik | 6c4dd5b | 2021-10-05 15:29:23 -0700 | [diff] [blame] | 729 | self.raw_ptr(), IREE_VM_FUNCTION_LINKAGE_EXPORT, ordinal, &f); |
Stella Laurenzo | aeaaad6 | 2021-05-03 13:44:52 -0700 | [diff] [blame] | 730 | if (iree_status_is_not_found(status)) { |
| 731 | iree_status_ignore(status); |
| 732 | break; |
| 733 | } |
| 734 | CheckApiStatus(status, "Error enumerating module"); |
| 735 | iree_string_view_t fname = iree_vm_function_name(&f); |
| 736 | if (ordinal > 0) { |
| 737 | repr.append(", "); |
| 738 | } |
| 739 | repr.append(fname.data, fname.size); |
| 740 | } |
| 741 | repr.append("]"); |
| 742 | repr.append(">"); |
| 743 | return repr; |
| 744 | }); |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 745 | |
| 746 | py::class_<VmRef>(m, "VmRef") |
| 747 | .def("isinstance", &VmRef::IsInstance) |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 748 | .def("deref", &VmRef::Deref, py::arg("value"), |
| 749 | py::arg("optional") = false) |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 750 | .def("__repr__", &VmRef::ToString) |
Stella Laurenzo | 7b06657 | 2022-07-31 18:38:15 -0700 | [diff] [blame] | 751 | .def_property_readonly(VmRef::kRefAttr, |
| 752 | [](py::object self) { return self; }) |
Stella Laurenzo | 95dff50 | 2022-07-31 14:16:12 -0700 | [diff] [blame] | 753 | .def("__eq__", |
| 754 | [](VmRef& self, VmRef& other) { |
| 755 | return self.ref().ptr == other.ref().ptr; |
| 756 | }) |
| 757 | .def("__eq__", [](VmRef& self, py::object& other) { return false; }); |
powderluv | 2e2fc9c | 2019-10-23 10:09:44 -0700 | [diff] [blame] | 758 | } |
| 759 | |
| 760 | } // namespace python |
| 761 | } // namespace iree |