diff --git a/src/Algorithm.cpp b/src/Algorithm.cpp index af12e091..b8f7cbfa 100644 --- a/src/Algorithm.cpp +++ b/src/Algorithm.cpp @@ -18,7 +18,7 @@ Algorithm::isInit() { return this->mPipeline && this->mPipelineCache && this->mPipelineLayout && this->mDescriptorPool && this->mDescriptorSet && - this->mDescriptorSetLayout && this->mShaderModule; + this->mDescriptorSetLayout && this->mShader; } void @@ -73,18 +73,12 @@ Algorithm::destroy() (vk::Optional)nullptr); this->mPipelineLayout = nullptr; } - - if (this->mFreeShaderModule && this->mShaderModule) { - KP_LOG_DEBUG("Kompute Algorithm Destroying shader module"); - if (!this->mShaderModule) { - KP_LOG_WARN("Kompute Algorithm Error requested to destroy shader " - "module but it is null"); - } - this->mDevice->destroy( - *this->mShaderModule, - (vk::Optional)nullptr); - this->mShaderModule = nullptr; - } + + if (this->mShader) + { + this->mShader->destroy(); + this->mShader = nullptr; + } // We don't call freeDescriptorSet as the descriptor pool is not created // with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT more at @@ -219,24 +213,11 @@ Algorithm::createParameters() } void -Algorithm::createShaderModule() +Algorithm::createShaderModule(const std::vector& spirv) { - KP_LOG_DEBUG("Kompute Algorithm createShaderModule started"); - - vk::ShaderModuleCreateInfo shaderModuleInfo(vk::ShaderModuleCreateFlags(), - sizeof(uint32_t) * - this->mSpirv.size(), - this->mSpirv.data()); - - KP_LOG_DEBUG("Kompute Algorithm Creating shader module. ShaderFileSize: {}", - this->mSpirv.size()); - this->mFreeShaderModule = true; - this->mShaderModule = std::make_shared(); - this->mDevice->createShaderModule( - &shaderModuleInfo, nullptr, this->mShaderModule.get()); - this->mFreeShaderModule = true; - - KP_LOG_DEBUG("Kompute Algorithm create shader module success"); + KP_LOG_DEBUG("Kompute Algorithm createShaderModule started"); + this->mShader = std::make_shared(this->mDevice, spirv); + KP_LOG_DEBUG("Kompute Algorithm create shader module success"); } void @@ -289,7 +270,7 @@ Algorithm::createPipeline() vk::PipelineShaderStageCreateInfo shaderStage( vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eCompute, - *this->mShaderModule, + this->mShader->getShaderModule(), "main", &specializationInfo); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8805e842..04aa4e77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,8 @@ add_library(kompute Algorithm.cpp Tensor.cpp Core.cpp Image.cpp - Memory.cpp) + Memory.cpp + Shader.cpp) add_library(kompute::kompute ALIAS kompute) diff --git a/src/Manager.cpp b/src/Manager.cpp index b74dc59c..3b8f91a5 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -381,11 +381,11 @@ Manager::createDevice(const std::vector& familyQueueIndices, uint32_t computeQueueFamilyIndex = 0; bool computeQueueSupported = false; for (uint32_t i = 0; i < allQueueFamilyProperties.size(); i++) { - vk::QueueFamilyProperties queueFamilyProperties = + const vk::QueueFamilyProperties& queueFamilyProperties = allQueueFamilyProperties[i]; if (queueFamilyProperties.queueFlags & - vk::QueueFlagBits::eCompute) { + vk::QueueFlagBits::eCompute ) { computeQueueFamilyIndex = i; computeQueueSupported = true; break; diff --git a/src/Shader.cpp b/src/Shader.cpp new file mode 100644 index 00000000..bfe604b0 --- /dev/null +++ b/src/Shader.cpp @@ -0,0 +1,43 @@ +#include "kompute/Shader.hpp" + +namespace kp { + +Shader::Shader(const std::shared_ptr& device, + const std::vector& spv) : + mDevice(device) +{ + KP_LOG_DEBUG("Kompute Module constructor started"); + KP_LOG_DEBUG("Kompute Module Creating shader module. ShaderFileSize: {}", + spv.size()); + vk::ShaderModuleCreateInfo shaderModuleInfo(vk::ShaderModuleCreateFlags(), + sizeof(uint32_t) * spv.size(), spv.data()); + this->mDevice->createShaderModule( + &shaderModuleInfo, nullptr, &(this->mShaderModule) ); + KP_LOG_DEBUG("Kompute Module constructor success"); +} + +const vk::ShaderModule& Shader::getShaderModule() +{ + if (this->mDestroyed) + throw std::runtime_error("Attempting to get vk::ShaderModule from destroyed kp::Shader instance"); + return this->mShaderModule; +} + +void Shader::destroy() +{ + KP_LOG_DEBUG("Kompute Module destructor started"); + KP_LOG_DEBUG("Kompute Module Destroying shader module"); + if (!this->mDestroyed) + { + this->mDestroyed = true; + this->mDevice->destroyShaderModule(this->mShaderModule); + } + KP_LOG_DEBUG("Kompute Module destructor success"); +} + +Shader::~Shader() +{ + this->destroy(); +} + +} // end namespace kp diff --git a/src/include/kompute/Algorithm.hpp b/src/include/kompute/Algorithm.hpp index c459babf..6de6aa06 100644 --- a/src/include/kompute/Algorithm.hpp +++ b/src/include/kompute/Algorithm.hpp @@ -10,6 +10,7 @@ #endif #include "kompute/Tensor.hpp" +#include "kompute/Shader.hpp" #include "logger/Logger.hpp" namespace kp { @@ -95,7 +96,6 @@ class Algorithm KP_LOG_DEBUG("Kompute Algorithm rebuild started"); this->mMemObjects = memObjects; - this->mSpirv = spirv; if (specializationConstants.size()) { if (this->mSpecializationConstantsData) { @@ -137,7 +137,7 @@ class Algorithm } this->createParameters(); - this->createShaderModule(); + this->createShaderModule(spirv); this->createPipeline(); } @@ -303,8 +303,6 @@ class Algorithm bool mFreeDescriptorPool = false; std::shared_ptr mDescriptorSet; bool mFreeDescriptorSet = false; - std::shared_ptr mShaderModule; - bool mFreeShaderModule = false; std::shared_ptr mPipelineLayout; bool mFreePipelineLayout = false; std::shared_ptr mPipelineCache; @@ -313,7 +311,6 @@ class Algorithm bool mFreePipeline = false; // -------------- ALWAYS OWNED RESOURCES - std::vector mSpirv; void* mSpecializationConstantsData = nullptr; uint32_t mSpecializationConstantsDataTypeMemorySize = 0; uint32_t mSpecializationConstantsSize = 0; @@ -321,9 +318,10 @@ class Algorithm uint32_t mPushConstantsDataTypeMemorySize = 0; uint32_t mPushConstantsSize = 0; Workgroup mWorkgroup; + std::shared_ptr mShader = nullptr; // Create util functions - void createShaderModule(); + void createShaderModule(const std::vector& spirv); void createPipeline(); // Parameters diff --git a/src/include/kompute/Shader.hpp b/src/include/kompute/Shader.hpp new file mode 100644 index 00000000..2d430391 --- /dev/null +++ b/src/include/kompute/Shader.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "kompute/Core.hpp" +#include "logger/Logger.hpp" +#include + +namespace kp { + +// forward declarations for std::shared_from_this +class Shader; + +/* + * Wrapper for Vulkan's shader modules. + */ +class Shader +{ + // not-owned resources + std::shared_ptr mDevice; + + // owned resources + vk::ShaderModule mShaderModule; + bool mDestroyed = false; + +public: + + /** + * Constructor accepting a device and a SPIR-V binary + * @param device The vk::Device for the shader module to be compiled for + * @param spv The SPIR-V binary + **/ + Shader(const std::shared_ptr& device, + const std::vector& spv); + + /** + * getter for mShaderModule + **/ + const vk::ShaderModule& getShaderModule(); + + void destroy(); + + ~Shader(); +}; + +} // End namespace kp diff --git a/test/TestAsyncOperations.cpp b/test/TestAsyncOperations.cpp index 92ec664b..28d05256 100644 --- a/test/TestAsyncOperations.cpp +++ b/test/TestAsyncOperations.cpp @@ -86,8 +86,8 @@ TEST(TestAsyncOperations, TestManagerParallelExecution) std::vector> algosAsync; for (uint32_t i = 0; i < numParallel; i++) { - inputsAsyncB.push_back(mgr.tensor(data)); - algosAsync.push_back(mgr.algorithm({ inputsAsyncB[i] }, spirv)); + inputsAsyncB.push_back(mgrAsync.tensor(data)); + algosAsync.push_back(mgrAsync.algorithm({ inputsAsyncB[i] }, spirv)); } std::vector> sqs;