diff --git a/README.md b/README.md index 9da291d03..c4c2104b4 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,9 @@ Use equations to group operations on memory and execution step int main() { kp::Manager kManager(); // Chooses device 0 - kp::Sequence sq = kManager().createSequence(); + kp::Sequence sq; + kManager.createSequence(&sq); + //kManager.createSequence(); kp::Tensor inputOne; sq.record(&inputOne, {0, 1, 2, 3}); // Mounts to device and binds to 0 diff --git a/src/BaseOperator.cpp b/src/BaseOperator.cpp new file mode 100644 index 000000000..ff4b94f4f --- /dev/null +++ b/src/BaseOperator.cpp @@ -0,0 +1,33 @@ + +#include + +#include "BaseOperator.hpp" + +namespace kp { + +BaseOperator::BaseOperator() { + +} + +BaseOperator::BaseOperator(vk::CommandBuffer* commandBuffer) { + SPDLOG_DEBUG("Compute BaseOperator constructor started"); + this->mCommandBuffer = commandBuffer; +} + +BaseOperator::~BaseOperator() { + SPDLOG_DEBUG("Compute BaseOperator destructor started"); + +} + +void BaseOperator::init(std::string one, std::string two) { + SPDLOG_DEBUG("Compute BaseOperator init started"); + +} + +void BaseOperator::record() { + SPDLOG_DEBUG("Compute BaseOperator record started"); + +} + +} + diff --git a/src/BaseOperator.hpp b/src/BaseOperator.hpp index 2a87c5519..a9335b506 100644 --- a/src/BaseOperator.hpp +++ b/src/BaseOperator.hpp @@ -1,15 +1,30 @@ #pragma once +#include + +#include +#include + + namespace kp { class BaseOperator { private: - + public: BaseOperator(); + BaseOperator(vk::CommandBuffer* commandBuffer); virtual ~BaseOperator(); + + void init(std::string one, std::string two); + void record(); + +private: + vk::Device* mDevice; + vk::CommandBuffer* mCommandBuffer; + }; } // End namespace kp diff --git a/src/Manager.cpp b/src/Manager.cpp index c799da3cd..b417f3749 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -34,13 +34,14 @@ debugMessageCallback(VkDebugReportFlagsEXT flags, Manager::Manager() { + this->mPhysicalDeviceIndex = 0; this->createInstance(); this->createDevice(); } Manager::~Manager() { - SPDLOG_DEBUG("Destroying Kompute Manager"); + SPDLOG_DEBUG("Kompute Manager Destructor started"); if (this->mDevice == nullptr) { spdlog::error("Kompute Manager destructor reached with null Device pointer"); @@ -48,7 +49,9 @@ Manager::~Manager() } if (this->mFreeDevice) { + spdlog::info("Destroying device"); this->mDevice->destroy(); + SPDLOG_DEBUG("Kompute Manager Destroyed Device"); } if (this->mInstance == nullptr) { @@ -56,13 +59,24 @@ Manager::~Manager() return; } +#if DEBUG + if (this->mDebugReportCallback) { + this->mInstance->destroyDebugReportCallbackEXT( + this->mDebugReportCallback, nullptr, this->mDebugDispatcher); + SPDLOG_DEBUG("Kompute Manager Destroyed Debug Report Callback"); + } +#endif + if (this->mFreeInstance) { this->mInstance->destroy(); + SPDLOG_DEBUG("Kompute Manager Destroyed Instance"); } } void Manager::createInstance() { + SPDLOG_DEBUG("Kompute Manager creating instance"); + this->mFreeInstance = true; vk::ApplicationInfo applicationInfo; @@ -83,6 +97,7 @@ void Manager::createInstance() { } #if DEBUG + SPDLOG_DEBUG("Kompute Manager adding debug validation layers"); // We'll identify the layers that are supported std::vector validLayerNames; std::vector desiredLayerNames = { @@ -114,9 +129,12 @@ void Manager::createInstance() { } #endif - vk::createInstance(&computeInstanceCreateInfo, nullptr, this->mInstance); + vk::Instance instance = vk::createInstance(computeInstanceCreateInfo); + this->mInstance = &instance; + SPDLOG_DEBUG("Kompute Manager Instance Created"); #if DEBUG + SPDLOG_DEBUG("Kompute Manager adding debug callbacks"); if (validLayerNames.size() > 0) { vk::DebugReportFlagsEXT debugFlags = vk::DebugReportFlagBitsEXT::eError | @@ -137,8 +155,13 @@ void Manager::createInstance() { void Manager::createDevice() { + SPDLOG_DEBUG("Kompute Manager creating Device"); + if (this->mInstance == nullptr) { - throw std::runtime_error("Manager instance is null"); + throw std::runtime_error("Kompute Manager instance is null"); + } + if (this->mPhysicalDeviceIndex < 0) { + throw std::runtime_error("Kompute Manager physical device index not provided"); } this->mFreeDevice = true; @@ -146,12 +169,12 @@ void Manager::createDevice() { std::vector physicalDevices = this->mInstance->enumeratePhysicalDevices(); - vk::PhysicalDevice physicalDevice = physicalDevices[0]; + vk::PhysicalDevice physicalDevice = physicalDevices[this->mPhysicalDeviceIndex]; vk::PhysicalDeviceProperties physicalDeviceProperties = physicalDevice.getProperties(); - spdlog::info("Using device {}", physicalDeviceProperties.deviceName); + spdlog::info("Using physical device index {} found {}", this->mPhysicalDeviceIndex, physicalDeviceProperties.deviceName); // Find compute queue std::vector allQueueFamilyProperties = @@ -186,9 +209,13 @@ void Manager::createDevice() { 1, // Number of deviceQueueCreateInfo &deviceQueueCreateInfo); - physicalDevice.createDevice(&deviceCreateInfo, nullptr, this->mDevice); + vk::Device device = physicalDevice.createDevice(deviceCreateInfo); + this->mDevice = &device; + SPDLOG_DEBUG("Kompute Manager device created"); - this->mDevice->getQueue(this->mComputeQueueFamilyIndex, 0, this->mComputeQueue); + vk::Queue computeQueue = this->mDevice->getQueue(this->mComputeQueueFamilyIndex, 0); + this->mComputeQueue = &computeQueue; + SPDLOG_DEBUG("Kompute Manager compute queue obtained"); } } diff --git a/src/Manager.hpp b/src/Manager.hpp index 83de2a857..0f573b78c 100644 --- a/src/Manager.hpp +++ b/src/Manager.hpp @@ -3,6 +3,10 @@ #include #include +#include + +#include "Sequence.hpp" + namespace kp { class Manager @@ -12,13 +16,24 @@ private: public: Manager(); - virtual ~Manager(); + ~Manager(); + + // Evaluate actions + template + void eval(TArgs&&... args) { + SPDLOG_DEBUG("Kompute Manager eval triggered"); + Sequence sq(this->mDevice, this->mComputeQueue, this->mComputeQueueFamilyIndex); + sq.begin(); + sq.record(std::forward(args)...); + sq.end(); + sq.eval(); + } - // Templated Commands private: vk::Instance* mInstance = nullptr; bool mFreeInstance = false; + uint32_t mPhysicalDeviceIndex = -1; vk::Device* mDevice = nullptr; bool mFreeDevice = false; uint32_t mComputeQueueFamilyIndex = -1; @@ -32,7 +47,6 @@ private: // Create functions void createInstance(); void createDevice(); - }; } // End namespace kp diff --git a/src/Sequence.cpp b/src/Sequence.cpp new file mode 100644 index 000000000..a2d6cdf54 --- /dev/null +++ b/src/Sequence.cpp @@ -0,0 +1,135 @@ + +#include + +#include "spdlog/spdlog.h" + +#include "Sequence.hpp" + +namespace kp { + +Sequence::Sequence() +{ + // TODO: Create device, queue, etc +} + +Sequence::Sequence(vk::Device* device, vk::Queue* computeQueue, uint32_t queueIndex) +{ + SPDLOG_DEBUG("Kompute Sequence Created with existing device & queue"); + this->mDevice = device; + this->mComputeQueue = computeQueue; + this->mQueueIndex = queueIndex; +} + +Sequence::~Sequence() { + SPDLOG_DEBUG("Kompute Sequence Destructor started"); + + if (this->mDevice == nullptr) { + spdlog::error("Kompute Sequence destructor reached with null Device pointer"); + return; + } + + if (this->mCommandBuffer == nullptr) { + spdlog::error("Kompute Sequence destructor reached with null CommandPool pointer"); + return; + } + + if (this->mFreeCommandBuffer) { + spdlog::info("Freeing CommandBuffer"); + this->mDevice->freeCommandBuffers(*this->mCommandPool, 1, this->mCommandBuffer); + SPDLOG_DEBUG("Kompute Manager Freed CommandBuffer"); + } + + if (this->mCommandPool == nullptr) { + spdlog::error("Kompute Sequence destructor reached with null CommandPool pointer"); + return; + } + + if (this->mFreeCommandPool) { + spdlog::info("Destroying CommandPool"); + this->mDevice->destroy(*this->mCommandPool); + SPDLOG_DEBUG("Kompute Manager Destroyed CommandPool"); + } + +} + +void Sequence::begin() { + if (this->mCommandPool == nullptr) { + throw std::runtime_error("Kompute Sequence command pool is null"); + } + + if (!this->mRecording) { + spdlog::info("Kompute Sequence starting command recording"); + this->mCommandBuffer->begin(vk::CommandBufferBeginInfo()); + this->mRecording = true; + } + else { + spdlog::warn("Kompute Sequence attempted to start command recording but recording already started"); + } +} + +void Sequence::end() { + if (this->mCommandPool == nullptr) { + throw std::runtime_error("Kompute Sequence command pool is null"); + } + + if (this->mRecording) { + spdlog::info("Kompute Sequence ending command recording"); + this->mCommandBuffer->end(); + this->mRecording = false; + } + else { + spdlog::warn("Kompute Sequence attempted to end command recording but recording not started"); + } +} + +void Sequence::eval() { + bool toggleSingleRecording = !this->mRecording; + if (toggleSingleRecording) { + this->begin(); + } + + const vk::PipelineStageFlags waitStageMask = vk::PipelineStageFlagBits::eTransfer; + vk::SubmitInfo submitInfo(0, nullptr, &waitStageMask, 1, this->mCommandBuffer); + + vk::Fence fence = this->mDevice->createFence(vk::FenceCreateInfo()); + this->mComputeQueue->submit(1, &submitInfo, fence); + this->mDevice->waitForFences(1, &fence, VK_TRUE, UINT64_MAX); + this->mDevice->destroy(fence); + + if (toggleSingleRecording) { + this->end(); + } +} + +void Sequence::createCommandPool() { + SPDLOG_DEBUG("Kompute Sequence creating command pool"); + if (this->mQueueIndex < 0) { + throw std::runtime_error("Kompute Sequence queue index not provided"); + } + + this->mFreeCommandPool = true; + + vk::CommandPoolCreateInfo commandPoolInfo(vk::CommandPoolCreateFlags(), this->mQueueIndex); + vk::CommandPool commandPool = this->mDevice->createCommandPool(commandPoolInfo); + this->mCommandPool = &commandPool; +} + +void Sequence::createCommandBuffer() { + SPDLOG_DEBUG("Kompute Sequence creating command buffer"); + if (this->mDevice == nullptr) { + throw std::runtime_error("Kompute Sequence device is null"); + } + if (this->mCommandPool == nullptr) { + throw std::runtime_error("Kompute Sequence command pool is null"); + } + + this->mFreeCommandBuffer = true; + + vk::CommandBufferAllocateInfo commandBufferAllocateInfo(*this->mCommandPool, vk::CommandBufferLevel::ePrimary, 1); + + vk::CommandBuffer commandBuffer; + this->mDevice->allocateCommandBuffers(&commandBufferAllocateInfo, &commandBuffer); + this->mCommandBuffer = &commandBuffer; +} + +} diff --git a/src/Sequence.hpp b/src/Sequence.hpp index 3586451e3..7bc861aff 100644 --- a/src/Sequence.hpp +++ b/src/Sequence.hpp @@ -1,15 +1,48 @@ #pragma once +#include +#include + namespace kp { class Sequence { private: - public: Sequence(); - virtual ~Sequence(); + Sequence(vk::Device* device, vk::Queue* computeQueue, uint32_t queueIndex); + ~Sequence(); + + // Record command functions + void begin(); + void end(); + void eval(); + + template + void record(TArgs&&... args) { + T op(this->mCommandBuffer); + op.init(std::forward(args)...); + op.record(); + } + + +private: + vk::Device* mDevice = nullptr; + vk::Queue* mComputeQueue = nullptr; + uint32_t mQueueIndex = -1; + vk::CommandPool* mCommandPool = nullptr; + bool mFreeCommandPool = false; + vk::CommandBuffer* mCommandBuffer = nullptr; + bool mFreeCommandBuffer = false; + + // Record state + bool mRecording = false; + + // Create functions + void createCommandPool(); + void createCommandBuffer(); + }; } // End namespace kp diff --git a/src/main.cpp b/src/main.cpp index 41281046a..8efc08b9f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,9 @@ #include #include +#include "Manager.hpp" +#include "BaseOperator.hpp" + #define BUFFER_ELEMENTS 32 #if DEBUG @@ -609,9 +612,16 @@ main() #endif try { - VulkanCompute* vulkanExample = new VulkanCompute(); - std::cout << "Finished."; - delete (vulkanExample); + //VulkanCompute* vulkanExample = new VulkanCompute(); + //spdlog::info("Finished."); + //delete (vulkanExample); + + // Run Kompute + spdlog::info("Creating manager"); + kp::Manager mgr; + spdlog::info("Calling manager eval"); + mgr.eval("one", "two"); + spdlog::info("Called manager eval success"); return 0; } catch (const std::exception& exc) { spdlog::error(exc.what()); diff --git a/test/ManagerTest.cpp b/test/ManagerTest.cpp new file mode 100644 index 000000000..b869aa043 --- /dev/null +++ b/test/ManagerTest.cpp @@ -0,0 +1,8 @@ +#include "gtest/gtest.h" + +#include "../src/Manager.hpp" + +TEST(ManagerTest, ManagerEmptyInitTest) { + kp::Manager mgr; + mgr.~Manager(); +}