Spaces:
Runtime error
Runtime error
// SPDX-License-Identifier: Apache-2.0 | |
namespace kp { | |
std::string | |
Tensor::toString(Tensor::TensorDataTypes dt) | |
{ | |
switch (dt) { | |
case TensorDataTypes::eBool: | |
return "eBool"; | |
case TensorDataTypes::eInt: | |
return "eInt"; | |
case TensorDataTypes::eUnsignedInt: | |
return "eUnsignedInt"; | |
case TensorDataTypes::eFloat: | |
return "eFloat"; | |
case TensorDataTypes::eDouble: | |
return "eDouble"; | |
default: | |
return "unknown"; | |
} | |
} | |
std::string | |
Tensor::toString(Tensor::TensorTypes dt) | |
{ | |
switch (dt) { | |
case TensorTypes::eDevice: | |
return "eDevice"; | |
case TensorTypes::eHost: | |
return "eHost"; | |
case TensorTypes::eStorage: | |
return "eStorage"; | |
default: | |
return "unknown"; | |
} | |
} | |
Tensor::Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice, | |
std::shared_ptr<vk::Device> device, | |
void* data, | |
uint32_t elementTotalCount, | |
uint32_t elementMemorySize, | |
const TensorDataTypes& dataType, | |
vk::DeviceMemory *primaryMemory, | |
vk::Buffer *primaryBuffer, | |
vk::DeviceMemory *stagingMemory, | |
vk::Buffer *stagingBuffer, | |
vk::DeviceSize offset, | |
const TensorTypes& tensorType) | |
{ | |
KP_LOG_DEBUG("Kompute Tensor constructor data length: {}, and type: {}", | |
elementTotalCount, | |
Tensor::toString(tensorType)); | |
this->mPhysicalDevice = physicalDevice; | |
this->mDevice = device; | |
this->mDataType = dataType; | |
this->mTensorType = tensorType; | |
this->rebuild(data, elementTotalCount, elementMemorySize, primaryMemory, primaryBuffer, stagingMemory, stagingBuffer, offset); | |
} | |
Tensor::~Tensor() | |
{ | |
KP_LOG_DEBUG("Kompute Tensor destructor started. Type: {}", | |
Tensor::toString(this->tensorType())); | |
if (this->mDevice) { | |
this->destroy(); | |
} | |
KP_LOG_DEBUG("Kompute Tensor destructor success"); | |
} | |
void | |
Tensor::rebuild(void* /*data*/, | |
uint32_t elementTotalCount, | |
uint64_t memorySize, | |
vk::DeviceMemory *primaryMemory, | |
vk::Buffer *primaryBuffer, | |
vk::DeviceMemory *stagingMemory, | |
vk::Buffer *stagingBuffer, | |
vk::DeviceSize offset) | |
{ | |
KP_LOG_DEBUG("Kompute Tensor rebuilding with size {}", elementTotalCount); | |
this->mSize = elementTotalCount; | |
this->mMemorySize = memorySize; | |
this->mOffset = offset; | |
if (this->mPrimaryBuffer || this->mPrimaryMemory) { | |
KP_LOG_DEBUG( | |
"Kompute Tensor destroying existing resources before rebuild"); | |
this->destroy(); | |
} | |
this->setGPUResources(primaryMemory, primaryBuffer, stagingMemory, stagingBuffer, offset); | |
} | |
Tensor::TensorTypes | |
Tensor::tensorType() | |
{ | |
return this->mTensorType; | |
} | |
bool | |
Tensor::isInit() | |
{ | |
return this->mDevice && this->mPrimaryBuffer && this->mPrimaryMemory && | |
this->mRawData; | |
} | |
uint32_t | |
Tensor::size() | |
{ | |
return this->mSize; | |
} | |
uint64_t | |
Tensor::memorySize() | |
{ | |
return this->mMemorySize; | |
} | |
kp::Tensor::TensorDataTypes | |
Tensor::dataType() | |
{ | |
return this->mDataType; | |
} | |
void* | |
Tensor::rawData() | |
{ | |
return this->mRawData; | |
} | |
void | |
Tensor::setRawData(const void* data) | |
{ | |
memcpy(this->mRawData, data, this->memorySize()); | |
} | |
void | |
Tensor::recordCopyFrom(const vk::CommandBuffer& commandBuffer, | |
std::shared_ptr<Tensor> copyFromTensor) | |
{ | |
vk::DeviceSize bufferSize(this->memorySize()); | |
vk::BufferCopy copyRegion(mOffset, mOffset, bufferSize); | |
KP_LOG_DEBUG("Kompute Tensor recordCopyFrom data size {}.", bufferSize); | |
this->recordCopyBuffer(commandBuffer, | |
copyFromTensor->mPrimaryBuffer, | |
this->mPrimaryBuffer, | |
bufferSize, | |
copyRegion); | |
} | |
void | |
Tensor::recordCopyFromStagingToDevice(const vk::CommandBuffer& commandBuffer) | |
{ | |
if (!this->mStagingBuffer) | |
return; | |
vk::DeviceSize bufferSize(this->memorySize()); | |
vk::BufferCopy copyRegion(mOffset, mOffset, bufferSize); | |
KP_LOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize); | |
this->recordCopyBuffer(commandBuffer, | |
this->mStagingBuffer, | |
this->mPrimaryBuffer, | |
bufferSize, | |
copyRegion); | |
} | |
void | |
Tensor::recordCopyFromDeviceToStaging(const vk::CommandBuffer& commandBuffer) | |
{ | |
if (!this->mStagingBuffer) | |
return; | |
vk::DeviceSize bufferSize(this->memorySize()); | |
vk::BufferCopy copyRegion(mOffset, mOffset, bufferSize); | |
KP_LOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize); | |
this->recordCopyBuffer(commandBuffer, | |
this->mPrimaryBuffer, | |
this->mStagingBuffer, | |
bufferSize, | |
copyRegion); | |
} | |
void | |
Tensor::recordCopyBuffer(const vk::CommandBuffer& commandBuffer, | |
vk::Buffer *bufferFrom, | |
vk::Buffer *bufferTo, | |
vk::DeviceSize /*bufferSize*/, | |
vk::BufferCopy copyRegion) | |
{ | |
commandBuffer.copyBuffer(*bufferFrom, *bufferTo, copyRegion); | |
} | |
void | |
Tensor::recordFill(const vk::CommandBuffer &commandBuffer, | |
uint32_t fill) | |
{ | |
commandBuffer.fillBuffer(*this->mPrimaryBuffer, mOffset, this->memorySize(), fill); | |
} | |
void | |
Tensor::recordPrimaryBufferMemoryBarrier(const vk::CommandBuffer& commandBuffer, | |
vk::AccessFlagBits srcAccessMask, | |
vk::AccessFlagBits dstAccessMask, | |
vk::PipelineStageFlagBits srcStageMask, | |
vk::PipelineStageFlagBits dstStageMask) | |
{ | |
KP_LOG_DEBUG("Kompute Tensor recording PRIMARY buffer memory barrier"); | |
this->recordBufferMemoryBarrier(commandBuffer, | |
*this->mPrimaryBuffer, | |
srcAccessMask, | |
dstAccessMask, | |
srcStageMask, | |
dstStageMask); | |
} | |
void | |
Tensor::recordStagingBufferMemoryBarrier(const vk::CommandBuffer& commandBuffer, | |
vk::AccessFlagBits srcAccessMask, | |
vk::AccessFlagBits dstAccessMask, | |
vk::PipelineStageFlagBits srcStageMask, | |
vk::PipelineStageFlagBits dstStageMask) | |
{ | |
if (!this->mStagingBuffer) | |
return; | |
KP_LOG_DEBUG("Kompute Tensor recording STAGING buffer memory barrier"); | |
this->recordBufferMemoryBarrier(commandBuffer, | |
*this->mStagingBuffer, | |
srcAccessMask, | |
dstAccessMask, | |
srcStageMask, | |
dstStageMask); | |
} | |
void | |
Tensor::recordBufferMemoryBarrier(const vk::CommandBuffer& commandBuffer, | |
const vk::Buffer& buffer, | |
vk::AccessFlagBits srcAccessMask, | |
vk::AccessFlagBits dstAccessMask, | |
vk::PipelineStageFlagBits srcStageMask, | |
vk::PipelineStageFlagBits dstStageMask) | |
{ | |
KP_LOG_DEBUG("Kompute Tensor recording buffer memory barrier"); | |
vk::DeviceSize bufferSize = this->memorySize(); | |
vk::BufferMemoryBarrier bufferMemoryBarrier; | |
bufferMemoryBarrier.buffer = buffer; | |
bufferMemoryBarrier.size = bufferSize; | |
bufferMemoryBarrier.srcAccessMask = srcAccessMask; | |
bufferMemoryBarrier.dstAccessMask = dstAccessMask; | |
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | |
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | |
commandBuffer.pipelineBarrier(srcStageMask, | |
dstStageMask, | |
vk::DependencyFlags(), | |
nullptr, | |
bufferMemoryBarrier, | |
nullptr); | |
} | |
vk::DescriptorBufferInfo | |
Tensor::constructDescriptorBufferInfo() | |
{ | |
KP_LOG_DEBUG("Kompute Tensor construct descriptor buffer info size {}", | |
this->memorySize()); | |
vk::DeviceSize bufferSize = this->memorySize(); | |
return vk::DescriptorBufferInfo(*this->mPrimaryBuffer, | |
mOffset, // offset | |
bufferSize); | |
} | |
vk::BufferUsageFlags | |
Tensor::getPrimaryBufferUsageFlags() | |
{ | |
switch (this->mTensorType) { | |
case TensorTypes::eDevice: | |
return vk::BufferUsageFlagBits::eStorageBuffer | | |
vk::BufferUsageFlagBits::eTransferSrc | | |
vk::BufferUsageFlagBits::eTransferDst; | |
break; | |
case TensorTypes::eHost: | |
return vk::BufferUsageFlagBits::eStorageBuffer | | |
vk::BufferUsageFlagBits::eTransferSrc | | |
vk::BufferUsageFlagBits::eTransferDst; | |
break; | |
case TensorTypes::eStorage: | |
return vk::BufferUsageFlagBits::eStorageBuffer; | |
break; | |
default: | |
throw std::runtime_error("Kompute Tensor invalid tensor type"); | |
} | |
} | |
vk::MemoryPropertyFlags | |
Tensor::getPrimaryMemoryPropertyFlags() | |
{ | |
switch (this->mTensorType) { | |
case TensorTypes::eDevice: | |
return vk::MemoryPropertyFlagBits::eDeviceLocal; | |
break; | |
case TensorTypes::eHost: | |
return vk::MemoryPropertyFlagBits::eHostVisible | | |
vk::MemoryPropertyFlagBits::eHostCoherent; | |
break; | |
case TensorTypes::eStorage: | |
return vk::MemoryPropertyFlagBits::eDeviceLocal; | |
break; | |
default: | |
throw std::runtime_error("Kompute Tensor invalid tensor type"); | |
} | |
} | |
vk::BufferUsageFlags | |
Tensor::getStagingBufferUsageFlags() | |
{ | |
switch (this->mTensorType) { | |
case TensorTypes::eDevice: | |
return vk::BufferUsageFlagBits::eTransferSrc | | |
vk::BufferUsageFlagBits::eTransferDst; | |
break; | |
default: | |
throw std::runtime_error("Kompute Tensor invalid tensor type"); | |
} | |
} | |
vk::MemoryPropertyFlags | |
Tensor::getStagingMemoryPropertyFlags() | |
{ | |
switch (this->mTensorType) { | |
case TensorTypes::eDevice: | |
return vk::MemoryPropertyFlagBits::eHostVisible | | |
vk::MemoryPropertyFlagBits::eHostCoherent; | |
break; | |
default: | |
throw std::runtime_error("Kompute Tensor invalid tensor type"); | |
} | |
} | |
void | |
Tensor::setGPUResources(vk::DeviceMemory *primaryMemory, | |
vk::Buffer *primaryBuffer, | |
vk::DeviceMemory *stagingMemory, | |
vk::Buffer *stagingBuffer, | |
vk::DeviceSize /*offset*/) | |
{ | |
KP_LOG_DEBUG("Kompute Tensor creating buffer"); | |
if (!this->mPhysicalDevice) { | |
throw std::runtime_error("Kompute Tensor phyisical device is null"); | |
} | |
if (!this->mDevice) { | |
throw std::runtime_error("Kompute Tensor device is null"); | |
} | |
KP_LOG_DEBUG("Kompute Tensor creating primary buffer and memory"); | |
this->mPrimaryBuffer = primaryBuffer; | |
this->mPrimaryMemory = primaryMemory; | |
if (this->mTensorType == TensorTypes::eDevice) { | |
KP_LOG_DEBUG("Kompute Tensor creating staging buffer and memory"); | |
this->mStagingBuffer = stagingBuffer; | |
this->mStagingMemory = stagingMemory; | |
} | |
KP_LOG_DEBUG("Kompute Tensor buffer & memory creation successful"); | |
} | |
void | |
Tensor::destroy() | |
{ | |
KP_LOG_DEBUG("Kompute Tensor started destroy()"); | |
// Setting raw data to null regardless whether device is available to | |
// invalidate Tensor | |
this->mRawData = nullptr; | |
this->mSize = 0; | |
this->mMemorySize = 0; | |
if (!this->mDevice) { | |
KP_LOG_WARN( | |
"Kompute Tensor destructor reached with null Device pointer"); | |
return; | |
} | |
if (this->mDevice) { | |
this->mDevice = nullptr; | |
} | |
KP_LOG_DEBUG("Kompute Tensor successful destroy()"); | |
} | |
template<> | |
Tensor::TensorDataTypes | |
TensorT<bool>::dataType() | |
{ | |
return Tensor::TensorDataTypes::eBool; | |
} | |
template<> | |
Tensor::TensorDataTypes | |
TensorT<int32_t>::dataType() | |
{ | |
return Tensor::TensorDataTypes::eInt; | |
} | |
template<> | |
Tensor::TensorDataTypes | |
TensorT<uint32_t>::dataType() | |
{ | |
return Tensor::TensorDataTypes::eUnsignedInt; | |
} | |
template<> | |
Tensor::TensorDataTypes | |
TensorT<float>::dataType() | |
{ | |
return Tensor::TensorDataTypes::eFloat; | |
} | |
template<> | |
Tensor::TensorDataTypes | |
TensorT<double>::dataType() | |
{ | |
return Tensor::TensorDataTypes::eDouble; | |
} | |
} | |