Added logic to clean memory on operations

This commit is contained in:
Alejandro Saucedo 2020-08-27 06:27:24 +01:00
parent fbe5947a19
commit 4e2ef636c9
8 changed files with 94 additions and 35 deletions

View file

@ -93,7 +93,7 @@ int main() {
Create your own custom operations to leverage Vulkan Compute for your specialised use-cases. Create your own custom operations to leverage Vulkan Compute for your specialised use-cases.
```c++ ```c++
class CustomOp : kp::OpBase { class OpCustom : kp::OpBase {
// ... // ...
void init(std::shared_ptr<Tensor> tensors) { void init(std::shared_ptr<Tensor> tensors) {
// ... extra steps to initialise tensors // ... extra steps to initialise tensors
@ -102,14 +102,12 @@ class CustomOp : kp::OpBase {
} }
int main() { int main() {
kp::Manager kManager(); // Chooses device 0 kp::Manager mgr; // Automatically selects Device 0
kp::Tensor inputOne({0, 1, 2, 3}); std::shared_ptr<kp::Tensor> tensor{ new kp::Tensor({ 0.0, 1.0, 2.0 }) };
mgr.evalOp<kp::OpCreateTensor>({ tensorLHS });
kp::Tensor inputTwo({0, 1, 2, 3}); mgr.evalOp<kp::OpCustom>({ tensorLHS, tensorRHS, tensorOutput });
kp::Tensor output( {0, 0, 0, 0} );
kManager.eval<kp::CustomOp>({ inputOne, inputTwo, output });
std::cout << fmt::format("Output: {}", tensorOutput.data()) << std::endl; std::cout << fmt::format("Output: {}", tensorOutput.data()) << std::endl;
} }

View file

@ -178,6 +178,9 @@ class Tensor
// Create functions // Create functions
void createBuffer(); void createBuffer();
// Destroy/Free functions
void freeMemoryDestroyGPUResources();
// Getter functions // Getter functions
std::vector<uint32_t> data(); std::vector<uint32_t> data();
uint32_t size(); uint32_t size();
@ -692,7 +695,9 @@ class OpCreateTensor : public OpBase
private: private:
std::shared_ptr<Tensor> mPrimaryTensor; std::shared_ptr<Tensor> mPrimaryTensor;
bool mFreePrimaryTensorResources = false;
std::shared_ptr<Tensor> mStagingTensor; std::shared_ptr<Tensor> mStagingTensor;
bool mFreeStagingTensorResources = false;
}; };
} // End namespace kp } // End namespace kp

View file

@ -39,6 +39,11 @@ Manager::~Manager()
return; return;
} }
if (this->mManagedSequences.size()) {
SPDLOG_DEBUG("Releasing managed sequence");
this->mManagedSequences.clear();
}
if (this->mFreeDevice) { if (this->mFreeDevice) {
spdlog::info("Destroying device"); spdlog::info("Destroying device");
this->mDevice->destroy(); this->mDevice->destroy();
@ -65,14 +70,17 @@ Manager::~Manager()
} }
} }
Sequence std::weak_ptr<Sequence>
Manager::constructSequence() Manager::managedSequence()
{ {
SPDLOG_DEBUG("Kompute Manager creating Sequence object"); SPDLOG_DEBUG("Kompute Manager creating Sequence object");
return Sequence(this->mPhysicalDevice, std::shared_ptr<Sequence> sq = std::make_shared<Sequence>(
this->mPhysicalDevice,
this->mDevice, this->mDevice,
this->mComputeQueue, this->mComputeQueue,
this->mComputeQueueFamilyIndex); this->mComputeQueueFamilyIndex);
this->mManagedSequences.push_back(sq);
return sq;
} }
void void

View file

@ -22,6 +22,29 @@ OpCreateTensor::OpCreateTensor(
OpCreateTensor::~OpCreateTensor() OpCreateTensor::~OpCreateTensor()
{ {
SPDLOG_DEBUG("Kompute OpCreateTensor destructor started"); SPDLOG_DEBUG("Kompute OpCreateTensor destructor started");
if(!this->mDevice) {
spdlog::warn("Kompute OpCreateTensor destructor called with empty device");
return;
}
if (!this->mFreePrimaryTensorResources) {
SPDLOG_DEBUG("Kompute OpCreateTensor removing primary tensor");
if (this->mPrimaryTensor && this->mPrimaryTensor->isInit()) {
this->mPrimaryTensor->freeMemoryDestroyGPUResources();
} else {
spdlog::error("Kompute OpCreateTensor expected to free primary tensor but has already been freed.");
}
}
if (!this->mFreeStagingTensorResources) {
SPDLOG_DEBUG("Kompute OpCreateTensor removing primary tensor");
if (this->mStagingTensor && this->mStagingTensor->isInit()) {
this->mStagingTensor->freeMemoryDestroyGPUResources();
} else {
spdlog::error("Kompute OpCreateTensor expected to free secondary tensor but has already been freed.");
}
}
} }
void void
@ -36,6 +59,9 @@ OpCreateTensor::init(std::vector<std::shared_ptr<Tensor>> tensors)
spdlog::warn("Kompute OpCreateTensor called with more than 1 tensor"); spdlog::warn("Kompute OpCreateTensor called with more than 1 tensor");
} }
this->mFreePrimaryTensorResources = true;
this->mFreeStagingTensorResources = true;
this->mPrimaryTensor = tensors[0]; this->mPrimaryTensor = tensors[0];
if (this->mPrimaryTensor->tensorType() == Tensor::TensorTypes::eDevice) { if (this->mPrimaryTensor->tensorType() == Tensor::TensorTypes::eDevice) {

View file

@ -27,30 +27,8 @@ Tensor::~Tensor()
{ {
SPDLOG_DEBUG("Kompute Tensor destructor started"); SPDLOG_DEBUG("Kompute Tensor destructor started");
if (!this->mDevice) { if (this->isInit()) {
spdlog::error( this->freeMemoryDestroyGPUResources();
"Kompute Sequence destructor reached with null Device pointer");
return;
}
if (this->mFreeBuffer) {
if (!this->mBuffer) {
spdlog::error(
"Kompose Tensor expected to free buffer but got null buffer");
} else {
SPDLOG_DEBUG("Kompose Tensor destroying buffer");
this->mDevice->destroy(*this->mBuffer);
}
}
if (this->mFreeMemory) {
if (!this->mMemory) {
spdlog::error(
"Kompose Tensor expected to free buffer but got null memory");
} else {
SPDLOG_DEBUG("Kompose Tensor freeing memory");
this->mDevice->freeMemory(*this->mMemory);
}
} }
SPDLOG_DEBUG("Kompute Tensor destructor success"); SPDLOG_DEBUG("Kompute Tensor destructor success");
@ -345,4 +323,39 @@ Tensor::createBuffer()
SPDLOG_DEBUG("Kompute Tensor buffer & memory creation successful"); SPDLOG_DEBUG("Kompute Tensor buffer & memory creation successful");
} }
void Tensor::freeMemoryDestroyGPUResources() {
SPDLOG_DEBUG("Kompute Tensor started freeMemoryDestroyGPUResources");
this->mIsInit = false;
if (!this->mDevice) {
spdlog::error(
"Kompute Tensor destructor reached with null Device pointer");
return;
}
if (this->mFreeBuffer) {
if (!this->mBuffer) {
spdlog::error(
"Kompose Tensor expected to free buffer but got null buffer");
} else {
SPDLOG_DEBUG("Kompose Tensor destroying buffer");
this->mDevice->destroy(*this->mBuffer);
}
}
if (this->mFreeMemory) {
if (!this->mMemory) {
spdlog::error(
"Kompose Tensor expected to free buffer but got null memory");
} else {
SPDLOG_DEBUG("Kompose Tensor freeing memory");
this->mDevice->freeMemory(*this->mMemory);
}
}
SPDLOG_DEBUG("Kompute Tensor successful freeMemoryDestroyGPUResources");
}
} }

View file

@ -18,7 +18,7 @@ class Manager
~Manager(); ~Manager();
Sequence constructSequence(); std::weak_ptr<Sequence> managedSequence();
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
void evalOp(std::vector<std::shared_ptr<Tensor>> tensors) void evalOp(std::vector<std::shared_ptr<Tensor>> tensors)
@ -49,6 +49,9 @@ class Manager
uint32_t mComputeQueueFamilyIndex = -1; uint32_t mComputeQueueFamilyIndex = -1;
std::shared_ptr<vk::Queue> mComputeQueue = nullptr; std::shared_ptr<vk::Queue> mComputeQueue = nullptr;
// Always owned resources
std::vector<std::shared_ptr<Sequence>> mManagedSequences;
#if DEBUG #if DEBUG
vk::DebugReportCallbackEXT mDebugReportCallback; vk::DebugReportCallbackEXT mDebugReportCallback;
vk::DispatchLoaderDynamic mDebugDispatcher; vk::DispatchLoaderDynamic mDebugDispatcher;

View file

@ -27,7 +27,9 @@ class OpCreateTensor : public OpBase
private: private:
std::shared_ptr<Tensor> mPrimaryTensor; std::shared_ptr<Tensor> mPrimaryTensor;
bool mFreePrimaryTensorResources = false;
std::shared_ptr<Tensor> mStagingTensor; std::shared_ptr<Tensor> mStagingTensor;
bool mFreeStagingTensorResources = false;
}; };
} // End namespace kp } // End namespace kp

View file

@ -30,6 +30,9 @@ class Tensor
// Create functions // Create functions
void createBuffer(); void createBuffer();
// Destroy/Free functions
void freeMemoryDestroyGPUResources();
// Getter functions // Getter functions
std::vector<uint32_t> data(); std::vector<uint32_t> data();
uint32_t size(); uint32_t size();
@ -54,6 +57,7 @@ class Tensor
void mapDataFromHostMemory(); void mapDataFromHostMemory();
void mapDataIntoHostMemory(); void mapDataIntoHostMemory();
private: private:
std::shared_ptr<vk::PhysicalDevice> mPhysicalDevice; std::shared_ptr<vk::PhysicalDevice> mPhysicalDevice;
std::shared_ptr<vk::Device> mDevice; std::shared_ptr<vk::Device> mDevice;