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.
```c++
class CustomOp : kp::OpBase {
class OpCustom : kp::OpBase {
// ...
void init(std::shared_ptr<Tensor> tensors) {
// ... extra steps to initialise tensors
@ -102,14 +102,12 @@ class CustomOp : kp::OpBase {
}
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});
kp::Tensor output( {0, 0, 0, 0} );
kManager.eval<kp::CustomOp>({ inputOne, inputTwo, output });
mgr.evalOp<kp::OpCustom>({ tensorLHS, tensorRHS, tensorOutput });
std::cout << fmt::format("Output: {}", tensorOutput.data()) << std::endl;
}

View file

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

View file

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

View file

@ -22,6 +22,29 @@ OpCreateTensor::OpCreateTensor(
OpCreateTensor::~OpCreateTensor()
{
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
@ -36,6 +59,9 @@ OpCreateTensor::init(std::vector<std::shared_ptr<Tensor>> tensors)
spdlog::warn("Kompute OpCreateTensor called with more than 1 tensor");
}
this->mFreePrimaryTensorResources = true;
this->mFreeStagingTensorResources = true;
this->mPrimaryTensor = tensors[0];
if (this->mPrimaryTensor->tensorType() == Tensor::TensorTypes::eDevice) {

View file

@ -27,30 +27,8 @@ Tensor::~Tensor()
{
SPDLOG_DEBUG("Kompute Tensor destructor started");
if (!this->mDevice) {
spdlog::error(
"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);
}
if (this->isInit()) {
this->freeMemoryDestroyGPUResources();
}
SPDLOG_DEBUG("Kompute Tensor destructor success");
@ -345,4 +323,39 @@ Tensor::createBuffer()
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();
Sequence constructSequence();
std::weak_ptr<Sequence> managedSequence();
template<typename T, typename... TArgs>
void evalOp(std::vector<std::shared_ptr<Tensor>> tensors)
@ -49,6 +49,9 @@ class Manager
uint32_t mComputeQueueFamilyIndex = -1;
std::shared_ptr<vk::Queue> mComputeQueue = nullptr;
// Always owned resources
std::vector<std::shared_ptr<Sequence>> mManagedSequences;
#if DEBUG
vk::DebugReportCallbackEXT mDebugReportCallback;
vk::DispatchLoaderDynamic mDebugDispatcher;

View file

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

View file

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