Added logic to clean memory on operations
This commit is contained in:
parent
fbe5947a19
commit
4e2ef636c9
8 changed files with 94 additions and 35 deletions
12
README.md
12
README.md
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue