This commit is contained in:
Alejandro Saucedo 2021-02-08 07:18:32 +00:00
parent 815acfa1fe
commit d24dfb7590
4 changed files with 98 additions and 57 deletions

View file

@ -106,8 +106,8 @@ OpAlgoLhsRhsOut::record()
vk::PipelineStageFlagBits::eTransfer); vk::PipelineStageFlagBits::eTransfer);
if (this->mTensorOutput->tensorType() == Tensor::TensorTypes::eDevice) { if (this->mTensorOutput->tensorType() == Tensor::TensorTypes::eDevice) {
this->mTensorOutput->recordCopyFromDeviceToStaging( this->mTensorOutput->recordCopyFromDeviceToStaging(this->mCommandBuffer,
this->mCommandBuffer, true); true);
} }
} }

View file

@ -113,45 +113,65 @@ Tensor::recordCopyFrom(std::shared_ptr<vk::CommandBuffer> commandBuffer,
SPDLOG_DEBUG("Kompute Tensor recordCopyFrom data size {}.", bufferSize); SPDLOG_DEBUG("Kompute Tensor recordCopyFrom data size {}.", bufferSize);
this->copyBuffer(commandBuffer, copyFromTensor->mPrimaryBuffer, this->mPrimaryBuffer, bufferSize, copyRegion, createBarrier); this->copyBuffer(commandBuffer,
copyFromTensor->mPrimaryBuffer,
this->mPrimaryBuffer,
bufferSize,
copyRegion,
createBarrier);
} }
void void
Tensor::recordCopyFromStagingToDevice(std::shared_ptr<vk::CommandBuffer> commandBuffer, Tensor::recordCopyFromStagingToDevice(
bool createBarrier) std::shared_ptr<vk::CommandBuffer> commandBuffer,
bool createBarrier)
{ {
vk::DeviceSize bufferSize(this->memorySize()); vk::DeviceSize bufferSize(this->memorySize());
vk::BufferCopy copyRegion(0, 0, bufferSize); vk::BufferCopy copyRegion(0, 0, bufferSize);
SPDLOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize); SPDLOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize);
this->copyBuffer(commandBuffer, this->mStagingBuffer, this->mPrimaryBuffer, bufferSize, copyRegion, createBarrier); this->copyBuffer(commandBuffer,
this->mStagingBuffer,
this->mPrimaryBuffer,
bufferSize,
copyRegion,
createBarrier);
} }
void void
Tensor::recordCopyFromDeviceToStaging(std::shared_ptr<vk::CommandBuffer> commandBuffer, Tensor::recordCopyFromDeviceToStaging(
bool createBarrier) std::shared_ptr<vk::CommandBuffer> commandBuffer,
bool createBarrier)
{ {
vk::DeviceSize bufferSize(this->memorySize()); vk::DeviceSize bufferSize(this->memorySize());
vk::BufferCopy copyRegion(0, 0, bufferSize); vk::BufferCopy copyRegion(0, 0, bufferSize);
SPDLOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize); SPDLOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize);
this->copyBuffer(commandBuffer, this->mPrimaryBuffer, this->mStagingBuffer, bufferSize, copyRegion, createBarrier); this->copyBuffer(commandBuffer,
this->mPrimaryBuffer,
this->mStagingBuffer,
bufferSize,
copyRegion,
createBarrier);
} }
void void
Tensor::copyBuffer(std::shared_ptr<vk::CommandBuffer> commandBuffer, std::shared_ptr<vk::Buffer> bufferFrom, std::shared_ptr<vk::Buffer> bufferTo, vk::DeviceSize bufferSize, vk::BufferCopy copyRegion, bool createBarrier) { Tensor::copyBuffer(std::shared_ptr<vk::CommandBuffer> commandBuffer,
std::shared_ptr<vk::Buffer> bufferFrom,
std::shared_ptr<vk::Buffer> bufferTo,
vk::DeviceSize bufferSize,
vk::BufferCopy copyRegion,
bool createBarrier)
{
if (!this->mIsInit) { if (!this->mIsInit) {
throw std::runtime_error( throw std::runtime_error(
"Kompute Tensor attempted to run copyBuffer without init"); "Kompute Tensor attempted to run copyBuffer without init");
} }
commandBuffer->copyBuffer( commandBuffer->copyBuffer(*bufferFrom, *bufferTo, copyRegion);
*bufferFrom, *bufferTo, copyRegion);
if (createBarrier) { if (createBarrier) {
// Buffer to ensure wait until data is copied to staging buffer // Buffer to ensure wait until data is copied to staging buffer
@ -209,8 +229,7 @@ Tensor::mapDataFromHostMemory()
if (this->mTensorType == TensorTypes::eHost) { if (this->mTensorType == TensorTypes::eHost) {
hostVisibleMemory = this->mPrimaryMemory; hostVisibleMemory = this->mPrimaryMemory;
} } else {
else {
hostVisibleMemory = this->mStagingMemory; hostVisibleMemory = this->mStagingMemory;
} }
@ -233,8 +252,7 @@ Tensor::mapDataIntoHostMemory()
if (this->mTensorType == TensorTypes::eHost) { if (this->mTensorType == TensorTypes::eHost) {
hostVisibleMemory = this->mPrimaryMemory; hostVisibleMemory = this->mPrimaryMemory;
} } else {
else {
hostVisibleMemory = this->mStagingMemory; hostVisibleMemory = this->mStagingMemory;
} }
@ -333,20 +351,26 @@ Tensor::allocateMemoryCreateGPUResources()
SPDLOG_DEBUG("Kompute Tensor creating primary buffer and memory"); SPDLOG_DEBUG("Kompute Tensor creating primary buffer and memory");
this->mPrimaryBuffer = std::make_shared<vk::Buffer>(); this->mPrimaryBuffer = std::make_shared<vk::Buffer>();
this->createBuffer(this->mPrimaryBuffer, this->getPrimaryBufferUsageFlags()); this->createBuffer(this->mPrimaryBuffer,
this->getPrimaryBufferUsageFlags());
this->mFreePrimaryBuffer = true; this->mFreePrimaryBuffer = true;
this->mPrimaryMemory = std::make_shared<vk::DeviceMemory>(); this->mPrimaryMemory = std::make_shared<vk::DeviceMemory>();
this->allocateBindMemory(this->mPrimaryBuffer, this->mPrimaryMemory, this->getPrimaryMemoryPropertyFlags()); this->allocateBindMemory(this->mPrimaryBuffer,
this->mPrimaryMemory,
this->getPrimaryMemoryPropertyFlags());
this->mFreePrimaryMemory = true; this->mFreePrimaryMemory = true;
if (this->mTensorType == TensorTypes::eDevice) { if (this->mTensorType == TensorTypes::eDevice) {
SPDLOG_DEBUG("Kompute Tensor creating staging buffer and memory"); SPDLOG_DEBUG("Kompute Tensor creating staging buffer and memory");
this->mStagingBuffer = std::make_shared<vk::Buffer>(); this->mStagingBuffer = std::make_shared<vk::Buffer>();
this->createBuffer(this->mStagingBuffer, this->getStagingBufferUsageFlags()); this->createBuffer(this->mStagingBuffer,
this->getStagingBufferUsageFlags());
this->mFreeStagingBuffer = true; this->mFreeStagingBuffer = true;
this->mStagingMemory = std::make_shared<vk::DeviceMemory>(); this->mStagingMemory = std::make_shared<vk::DeviceMemory>();
this->allocateBindMemory(this->mStagingBuffer, this->mStagingMemory, this->getStagingMemoryPropertyFlags()); this->allocateBindMemory(this->mStagingBuffer,
this->mStagingMemory,
this->getStagingMemoryPropertyFlags());
this->mFreeStagingMemory = true; this->mFreeStagingMemory = true;
} }
@ -354,15 +378,16 @@ Tensor::allocateMemoryCreateGPUResources()
} }
void void
Tensor::createBuffer(std::shared_ptr<vk::Buffer> buffer, vk::BufferUsageFlags bufferUsageFlags) { Tensor::createBuffer(std::shared_ptr<vk::Buffer> buffer,
vk::BufferUsageFlags bufferUsageFlags)
{
vk::DeviceSize bufferSize = this->memorySize(); vk::DeviceSize bufferSize = this->memorySize();
if(bufferSize<1){ if (bufferSize < 1) {
throw std::runtime_error("Kompute Tensor attempted to create a zero-sized buffer"); throw std::runtime_error(
"Kompute Tensor attempted to create a zero-sized buffer");
} }
SPDLOG_DEBUG("Kompute Tensor creating buffer with memory size: {}, and " SPDLOG_DEBUG("Kompute Tensor creating buffer with memory size: {}, and "
"usage flags: {}", "usage flags: {}",
@ -376,11 +401,13 @@ Tensor::createBuffer(std::shared_ptr<vk::Buffer> buffer, vk::BufferUsageFlags bu
vk::SharingMode::eExclusive); vk::SharingMode::eExclusive);
this->mDevice->createBuffer(&bufferInfo, nullptr, buffer.get()); this->mDevice->createBuffer(&bufferInfo, nullptr, buffer.get());
} }
void void
Tensor::allocateBindMemory(std::shared_ptr<vk::Buffer> buffer, std::shared_ptr<vk::DeviceMemory> memory, vk::MemoryPropertyFlags memoryPropertyFlags) { Tensor::allocateBindMemory(std::shared_ptr<vk::Buffer> buffer,
std::shared_ptr<vk::DeviceMemory> memory,
vk::MemoryPropertyFlags memoryPropertyFlags)
{
SPDLOG_DEBUG("Kompute Tensor allocating and binding memory"); SPDLOG_DEBUG("Kompute Tensor allocating and binding memory");
@ -393,7 +420,8 @@ Tensor::allocateBindMemory(std::shared_ptr<vk::Buffer> buffer, std::shared_ptr<v
uint32_t memoryTypeIndex = -1; uint32_t memoryTypeIndex = -1;
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) { for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
if (memoryRequirements.memoryTypeBits & (1 << i)) { if (memoryRequirements.memoryTypeBits & (1 << i)) {
if (((memoryProperties.memoryTypes[i]).propertyFlags & memoryPropertyFlags) == memoryPropertyFlags) { if (((memoryProperties.memoryTypes[i]).propertyFlags &
memoryPropertyFlags) == memoryPropertyFlags) {
memoryTypeIndex = i; memoryTypeIndex = i;
break; break;
} }
@ -413,8 +441,7 @@ Tensor::allocateBindMemory(std::shared_ptr<vk::Buffer> buffer, std::shared_ptr<v
vk::MemoryAllocateInfo memoryAllocateInfo(memoryRequirements.size, vk::MemoryAllocateInfo memoryAllocateInfo(memoryRequirements.size,
memoryTypeIndex); memoryTypeIndex);
this->mDevice->allocateMemory( this->mDevice->allocateMemory(&memoryAllocateInfo, nullptr, memory.get());
&memoryAllocateInfo, nullptr, memory.get());
this->mDevice->bindBufferMemory(*buffer, *memory, 0); this->mDevice->bindBufferMemory(*buffer, *memory, 0);
} }
@ -434,8 +461,8 @@ Tensor::freeMemoryDestroyGPUResources()
if (this->mFreePrimaryBuffer) { if (this->mFreePrimaryBuffer) {
if (!this->mPrimaryBuffer) { if (!this->mPrimaryBuffer) {
SPDLOG_ERROR( SPDLOG_ERROR("Kompose Tensor expected to destroy primary buffer "
"Kompose Tensor expected to destroy primary buffer but got null buffer"); "but got null buffer");
} else { } else {
SPDLOG_DEBUG("Kompose Tensor destroying primary buffer"); SPDLOG_DEBUG("Kompose Tensor destroying primary buffer");
this->mDevice->destroy( this->mDevice->destroy(
@ -447,8 +474,8 @@ Tensor::freeMemoryDestroyGPUResources()
if (this->mFreeStagingBuffer) { if (this->mFreeStagingBuffer) {
if (!this->mStagingBuffer) { if (!this->mStagingBuffer) {
SPDLOG_ERROR( SPDLOG_ERROR("Kompose Tensor expected to destroy staging buffer "
"Kompose Tensor expected to destroy staging buffer but got null buffer"); "but got null buffer");
} else { } else {
SPDLOG_DEBUG("Kompose Tensor destroying staging buffer"); SPDLOG_DEBUG("Kompose Tensor destroying staging buffer");
this->mDevice->destroy( this->mDevice->destroy(
@ -460,8 +487,8 @@ Tensor::freeMemoryDestroyGPUResources()
if (this->mFreePrimaryMemory) { if (this->mFreePrimaryMemory) {
if (!this->mPrimaryMemory) { if (!this->mPrimaryMemory) {
SPDLOG_ERROR( SPDLOG_ERROR("Kompose Tensor expected to free primary memory but "
"Kompose Tensor expected to free primary memory but got null memory"); "got null memory");
} else { } else {
SPDLOG_DEBUG("Kompose Tensor freeing primary memory"); SPDLOG_DEBUG("Kompose Tensor freeing primary memory");
this->mDevice->freeMemory( this->mDevice->freeMemory(
@ -473,8 +500,8 @@ Tensor::freeMemoryDestroyGPUResources()
if (this->mFreeStagingMemory) { if (this->mFreeStagingMemory) {
if (!this->mStagingMemory) { if (!this->mStagingMemory) {
SPDLOG_ERROR( SPDLOG_ERROR("Kompose Tensor expected to free staging memory but "
"Kompose Tensor expected to free staging memory but got null memory"); "got null memory");
} else { } else {
SPDLOG_DEBUG("Kompose Tensor freeing staging memory"); SPDLOG_DEBUG("Kompose Tensor freeing staging memory");
this->mDevice->freeMemory( this->mDevice->freeMemory(

View file

@ -26,7 +26,7 @@ class Tensor
enum class TensorTypes enum class TensorTypes
{ {
eDevice = 0, ///< Type is device memory, source and destination eDevice = 0, ///< Type is device memory, source and destination
eHost = 1, ///< Type is host memory, source and destination eHost = 1, ///< Type is host memory, source and destination
eStorage = 2, ///< Type is Device memory (only) eStorage = 2, ///< Type is Device memory (only)
}; };
@ -39,7 +39,8 @@ class Tensor
* Default constructor with data provided which would be used to create the * Default constructor with data provided which would be used to create the
* respective vulkan buffer and memory. * respective vulkan buffer and memory.
* *
* @param data Non-zero-sized vector of data that will be used by the tensor * @param data Non-zero-sized vector of data that will be used by the
* tensor
* @param tensorType Type for the tensor which is of type TensorTypes * @param tensorType Type for the tensor which is of type TensorTypes
*/ */
Tensor(const std::vector<float>& data, Tensor(const std::vector<float>& data,
@ -132,24 +133,30 @@ class Tensor
bool createBarrier); bool createBarrier);
/** /**
* Records a copy from the internal staging memory to the device memory using an optional barrier to wait for the operation. This function would only be relevant for kp::Tensors of type eDevice. * Records a copy from the internal staging memory to the device memory
* using an optional barrier to wait for the operation. This function would
* only be relevant for kp::Tensors of type eDevice.
* *
* @param commandBuffer Vulkan Command Buffer to record the commands into * @param commandBuffer Vulkan Command Buffer to record the commands into
* @param createBarrier Whether to create a barrier that ensures the data is * @param createBarrier Whether to create a barrier that ensures the data is
* copied before further operations. Default is true. * copied before further operations. Default is true.
*/ */
void recordCopyFromStagingToDevice(std::shared_ptr<vk::CommandBuffer> commandBuffer, void recordCopyFromStagingToDevice(
bool createBarrier); std::shared_ptr<vk::CommandBuffer> commandBuffer,
bool createBarrier);
/** /**
* Records a copy from the internal device memory to the staging memory using an optional barrier to wait for the operation. This function would only be relevant for kp::Tensors of type eDevice. * Records a copy from the internal device memory to the staging memory
* using an optional barrier to wait for the operation. This function would
* only be relevant for kp::Tensors of type eDevice.
* *
* @param commandBuffer Vulkan Command Buffer to record the commands into * @param commandBuffer Vulkan Command Buffer to record the commands into
* @param createBarrier Whether to create a barrier that ensures the data is * @param createBarrier Whether to create a barrier that ensures the data is
* copied before further operations. Default is true. * copied before further operations. Default is true.
*/ */
void recordCopyFromDeviceToStaging(std::shared_ptr<vk::CommandBuffer> commandBuffer, void recordCopyFromDeviceToStaging(
bool createBarrier); std::shared_ptr<vk::CommandBuffer> commandBuffer,
bool createBarrier);
/** /**
* Records the buffer memory barrier into the command buffer which * Records the buffer memory barrier into the command buffer which
@ -211,9 +218,17 @@ class Tensor
bool mIsInit = false; bool mIsInit = false;
void allocateMemoryCreateGPUResources(); // Creates the vulkan buffer void allocateMemoryCreateGPUResources(); // Creates the vulkan buffer
void createBuffer(std::shared_ptr<vk::Buffer> buffer, vk::BufferUsageFlags bufferUsageFlags); void createBuffer(std::shared_ptr<vk::Buffer> buffer,
void allocateBindMemory(std::shared_ptr<vk::Buffer> buffer, std::shared_ptr<vk::DeviceMemory> memory, vk::MemoryPropertyFlags memoryPropertyFlags); vk::BufferUsageFlags bufferUsageFlags);
void copyBuffer(std::shared_ptr<vk::CommandBuffer> commandBuffer, std::shared_ptr<vk::Buffer> bufferFrom, std::shared_ptr<vk::Buffer> bufferTo, vk::DeviceSize bufferSize, vk::BufferCopy copyRegion, bool createBarrier); void allocateBindMemory(std::shared_ptr<vk::Buffer> buffer,
std::shared_ptr<vk::DeviceMemory> memory,
vk::MemoryPropertyFlags memoryPropertyFlags);
void copyBuffer(std::shared_ptr<vk::CommandBuffer> commandBuffer,
std::shared_ptr<vk::Buffer> bufferFrom,
std::shared_ptr<vk::Buffer> bufferTo,
vk::DeviceSize bufferSize,
vk::BufferCopy copyRegion,
bool createBarrier);
// Private util functions // Private util functions
vk::BufferUsageFlags getPrimaryBufferUsageFlags(); vk::BufferUsageFlags getPrimaryBufferUsageFlags();

View file

@ -114,7 +114,6 @@ TEST(TestOpTensorCreate, NoErrorIfTensorFreedBefore)
EXPECT_FALSE(tensorB->isInit()); EXPECT_FALSE(tensorB->isInit());
} }
TEST(TestOpTensorCreate, ExceptionOnZeroSizeTensor) TEST(TestOpTensorCreate, ExceptionOnZeroSizeTensor)
{ {
std::vector<float> testVecA; std::vector<float> testVecA;
@ -123,11 +122,11 @@ TEST(TestOpTensorCreate, ExceptionOnZeroSizeTensor)
kp::Manager mgr; kp::Manager mgr;
try{ try {
mgr.evalOpDefault<kp::OpTensorCreate>({ tensorA }); mgr.evalOpDefault<kp::OpTensorCreate>({ tensorA });
} catch( const std::runtime_error& err ) { } catch (const std::runtime_error& err) {
// check exception // check exception
ASSERT_TRUE( std::string(err.what()).find("zero-sized") != std::string::npos ); ASSERT_TRUE(std::string(err.what()).find("zero-sized") !=
std::string::npos);
} }
} }