diff --git a/backends/vulkan/runtime/VulkanBackend.cpp b/backends/vulkan/runtime/VulkanBackend.cpp index 14cc7df02a1..5093d61d2f7 100644 --- a/backends/vulkan/runtime/VulkanBackend.cpp +++ b/backends/vulkan/runtime/VulkanBackend.cpp @@ -621,6 +621,10 @@ class VulkanBackend final : public ::executorch::runtime::BackendInterface { void destroy(DelegateHandle* handle) const override { if (handle != nullptr) { ComputeGraph* compute_graph = static_cast(handle); + compute_graph->context() + ->adapter_ptr() + ->compute_pipeline_cache() + .save_cache(); // ComputeGraph is not trivially destructible. Since // this was constructed manually in init(), we must destroy it manually // here. diff --git a/backends/vulkan/runtime/vk_api/Pipeline.cpp b/backends/vulkan/runtime/vk_api/Pipeline.cpp index 5cc5a76c358..49bbf083359 100644 --- a/backends/vulkan/runtime/vk_api/Pipeline.cpp +++ b/backends/vulkan/runtime/vk_api/Pipeline.cpp @@ -406,8 +406,6 @@ ComputePipelineCache::~ComputePipelineCache() { return; } - save_cache(); - vkDestroyPipelineCache(device_, pipeline_cache_, nullptr); pipeline_cache_ = VK_NULL_HANDLE; } @@ -433,12 +431,12 @@ void ComputePipelineCache::purge() { } std::vector ComputePipelineCache::load_cache() { - // Return if path is not specified; this means the optimization is disabled + // No optimization if path is unspecified if (cache_data_path_.empty()) { return {}; } - // Return if file doesn't exist; this is expected on the first model-load + // Return if file doesn't exist; this is expected on first model-load std::ifstream file(cache_data_path_, std::ios::binary | std::ios::ate); if (file.fail()) { return {}; @@ -454,6 +452,17 @@ std::vector ComputePipelineCache::load_cache() { } void ComputePipelineCache::save_cache() { + // No optimization if path is unspecified + if (cache_data_path_.empty()) { + return; + } + + // Return if file exists; the cache is already saved + std::ifstream ifile(cache_data_path_); + if (ifile.good()) { + return; + } + size_t size{}; vkGetPipelineCacheData(device_, pipeline_cache_, &size, nullptr); diff --git a/backends/vulkan/runtime/vk_api/Pipeline.h b/backends/vulkan/runtime/vk_api/Pipeline.h index 8765156deb2..4f42a9bf6bb 100644 --- a/backends/vulkan/runtime/vk_api/Pipeline.h +++ b/backends/vulkan/runtime/vk_api/Pipeline.h @@ -269,9 +269,10 @@ class ComputePipelineCache final { } }; + void save_cache(); + private: std::vector load_cache(); - void save_cache(); // Multiple threads could potentially be adding entries into the cache, so use // a mutex to manage access diff --git a/backends/vulkan/runtime/vk_api/Runtime.cpp b/backends/vulkan/runtime/vk_api/Runtime.cpp index e82f631ddb4..da03c4e86d7 100644 --- a/backends/vulkan/runtime/vk_api/Runtime.cpp +++ b/backends/vulkan/runtime/vk_api/Runtime.cpp @@ -265,7 +265,7 @@ std::unique_ptr init_global_vulkan_runtime() { }; try { - return std::make_unique(Runtime(default_config)); + return std::make_unique(default_config); } catch (...) { } @@ -323,16 +323,6 @@ Runtime::~Runtime() { instance_ = VK_NULL_HANDLE; } -Runtime::Runtime(Runtime&& other) noexcept - : config_(other.config_), - instance_(other.instance_), - adapters_(std::move(other.adapters_)), - default_adapter_i_(other.default_adapter_i_), - debug_report_callback_(other.debug_report_callback_) { - other.instance_ = VK_NULL_HANDLE; - other.debug_report_callback_ = {}; -} - uint32_t Runtime::create_adapter(const Selector& selector) { VK_CHECK_COND( !device_mappings_.empty(), diff --git a/backends/vulkan/runtime/vk_api/Runtime.h b/backends/vulkan/runtime/vk_api/Runtime.h index 14e6bd57dcb..16f1400021c 100644 --- a/backends/vulkan/runtime/vk_api/Runtime.h +++ b/backends/vulkan/runtime/vk_api/Runtime.h @@ -51,7 +51,7 @@ class Runtime final { Runtime(const Runtime&) = delete; Runtime& operator=(const Runtime&) = delete; - Runtime(Runtime&&) noexcept; + Runtime(Runtime&&) = delete; Runtime& operator=(Runtime&&) = delete; ~Runtime();