| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| /*! |
| * \file vulkan_module.cc |
| * \brief Plugin-only Vulkan runtime module. Built only when USE_VULKAN=ON. |
| * No exported header — codegen-side construction goes through |
| * src/backend/vulkan/codegen/vulkan_fallback_module.h:VulkanModuleCreateWithFallback, |
| * which dispatches to "ffi.Module.create.vulkan" registered below |
| * when this file is linked into the build. |
| */ |
| #include <tvm/ffi/function.h> |
| #include <tvm/ffi/reflection/registry.h> |
| #include <tvm/support/io.h> |
| |
| #include <string> |
| #include <utility> |
| |
| #include "../../../support/bytes_io.h" |
| #include "spirv_shader.h" |
| #include "vulkan_wrapped_func.h" |
| |
| namespace tvm { |
| namespace runtime { |
| namespace vulkan { |
| |
| /*! |
| * \brief Deserialize a SPIRVShader from ffi::Bytes. |
| * Format: flag (uint32_t) followed by data (vector<uint32_t>) — matches |
| * the SPIRVShader::Save format in src/backend/vulkan/runtime/spirv_shader.h. |
| */ |
| static SPIRVShader DeserializeSPIRVShader(const ffi::Bytes& bytes) { |
| support::BytesInStream stream(bytes); |
| SPIRVShader shader; |
| TVM_FFI_ICHECK(stream.Read(&shader)); |
| return shader; |
| } |
| |
| static ffi::Module VulkanModuleCreateImpl(ffi::Map<ffi::String, ffi::Bytes> smap, ffi::String fmt, |
| ffi::Map<ffi::String, FunctionInfo> fmap, |
| ffi::Map<ffi::String, ffi::String> source) { |
| // Convert Map<String, Bytes> smap → unordered_map<string, SPIRVShader> |
| // for the in-memory module. SaveToBytes will re-emit Map<String, Bytes> |
| // form so the bytes shape stays uniform across backends. |
| std::unordered_map<std::string, SPIRVShader> internal_smap; |
| for (const auto& kv : smap) { |
| internal_smap[std::string(kv.first)] = DeserializeSPIRVShader(kv.second); |
| } |
| auto n = ffi::make_object<VulkanModuleNode>(std::move(internal_smap), std::move(smap), |
| std::move(fmt), std::move(fmap), std::move(source)); |
| return ffi::Module(n); |
| } |
| |
| static ffi::Module VulkanModuleLoadFromBytes(const ffi::Bytes& bytes) { |
| support::BytesInStream stream(bytes); |
| ffi::String fmt; |
| ffi::Map<ffi::String, FunctionInfo> fmap; |
| ffi::Map<ffi::String, ffi::Bytes> smap; |
| stream.Read(&fmt); |
| TVM_FFI_ICHECK(stream.Read(&fmap)); |
| stream.Read(&smap); |
| // Source map is not serialized — reconstructed empty on load. |
| return VulkanModuleCreateImpl(std::move(smap), std::move(fmt), std::move(fmap), |
| ffi::Map<ffi::String, ffi::String>()); |
| } |
| |
| TVM_FFI_STATIC_INIT_BLOCK() { |
| namespace refl = tvm::ffi::reflection; |
| // Registry: "ffi.Module.create.vulkan" — codegen-time Vulkan module factory. |
| // Used by src/backend/vulkan/codegen/vulkan_fallback_module.h:VulkanModuleCreateWithFallback. |
| // Registry: "ffi.Module.load_from_bytes.vulkan" — disk loader. Only this |
| // (real) module registers a loader; the fallback is codegen-only. |
| refl::GlobalDef() |
| .def("ffi.Module.load_from_bytes.vulkan", VulkanModuleLoadFromBytes) |
| .def("ffi.Module.create.vulkan", |
| [](ffi::Map<ffi::String, ffi::Bytes> smap, ffi::String fmt, |
| ffi::Map<ffi::String, FunctionInfo> fmap, ffi::Map<ffi::String, ffi::String> source) { |
| return VulkanModuleCreateImpl(std::move(smap), std::move(fmt), std::move(fmap), |
| std::move(source)); |
| }); |
| } |
| |
| } // namespace vulkan |
| } // namespace runtime |
| } // namespace tvm |