diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 5a906578..1a6970a2 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -58,6 +58,25 @@ Tensor::Tensor(std::shared_ptr physicalDevice, this->rebuild(data, elementTotalCount, elementMemorySize); } +Tensor::Tensor(std::shared_ptr physicalDevice, + std::shared_ptr device, + uint32_t elementTotalCount, + uint32_t elementMemorySize, + const TensorDataTypes& dataType, + 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->reserve(elementTotalCount, elementMemorySize); +} + Tensor::~Tensor() { KP_LOG_DEBUG("Kompute Tensor destructor started. Type: {}", @@ -70,6 +89,23 @@ Tensor::~Tensor() KP_LOG_DEBUG("Kompute Tensor destructor success"); } +void +Tensor::reserve(uint32_t elementTotalCount, uint32_t elementMemorySize) +{ + KP_LOG_DEBUG("Reserving {} bytes for memory", elementTotalCount); + + this->mSize = elementTotalCount; + this->mDataTypeMemorySize = elementMemorySize; + + if (this->mPrimaryBuffer || this->mPrimaryMemory) { + KP_LOG_DEBUG( + "Kompute Tensor destroying existing resources before rebuild"); + this->destroy(); + } + + this->allocateMemoryCreateGPUResources(); +} + void Tensor::rebuild(void* data, uint32_t elementTotalCount, diff --git a/src/include/kompute/Manager.hpp b/src/include/kompute/Manager.hpp index 52f9ada7..5458dda7 100644 --- a/src/include/kompute/Manager.hpp +++ b/src/include/kompute/Manager.hpp @@ -124,6 +124,26 @@ class Manager return tensor; } + std::shared_ptr tensor( + uint32_t elementTotalCount, + uint32_t elementMemorySize, + const Tensor::TensorDataTypes& dataType, + Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice) + { + std::shared_ptr tensor{ new kp::Tensor(this->mPhysicalDevice, + this->mDevice, + elementTotalCount, + elementMemorySize, + dataType, + tensorType) }; + + if (this->mManageResources) { + this->mManagedTensors.push_back(tensor); + } + + return tensor; + } + /** * Default non-template function that can be used to create algorithm * objects which provides default types to the push and spec constants as diff --git a/src/include/kompute/Tensor.hpp b/src/include/kompute/Tensor.hpp index e39cc64c..3fd00244 100644 --- a/src/include/kompute/Tensor.hpp +++ b/src/include/kompute/Tensor.hpp @@ -62,6 +62,23 @@ class Tensor const TensorDataTypes& dataType, const TensorTypes& tensorType = TensorTypes::eDevice); + /** + * Constructor with size provided which would be used to create the + * respective vulkan buffer and memory. Data is not copied. + * + * @param physicalDevice The physical device to use to fetch properties + * @param device The device to use to create the buffer and memory from + * @param elmentTotalCount the number of elements of the array + * @param elementMemorySize the size of the element + * @param tensorTypes Type for the tensor which is of type TensorTypes + */ + Tensor(std::shared_ptr physicalDevice, + std::shared_ptr device, + uint32_t elementTotalCount, + uint32_t elementMemorySize, + const TensorDataTypes& dataType, + const TensorTypes& tensorType = TensorTypes::eDevice); + /** * Destructor which is in charge of freeing vulkan resources unless they * have been provided externally. @@ -79,6 +96,15 @@ class Tensor uint32_t elementTotalCount, uint32_t elementMemorySize); + /** + * Function to reserve memory on the tensor. This does not copy any data, it + * just reserves memory, similarly to std::vector reserve() method. + * + * @param elementTotalCount Total number of elements for new size + * @param elementMemorySize Memory size of element + */ + void reserve(uint32_t elementTotalCount, uint32_t elementMemorySize); + /** * Destroys and frees the GPU resources which include the buffer and memory. */ @@ -301,6 +327,20 @@ class TensorT : public Tensor { public: + TensorT(std::shared_ptr physicalDevice, + std::shared_ptr device, + const size_t size, + const TensorTypes& tensorType = TensorTypes::eDevice) + : Tensor(physicalDevice, + device, + size, + sizeof(T), + this->dataType(), + tensorType) + { + KP_LOG_DEBUG("Kompute TensorT constructor with data size {}", size); + } + TensorT(std::shared_ptr physicalDevice, std::shared_ptr device, const std::vector& data, @@ -313,7 +353,7 @@ class TensorT : public Tensor this->dataType(), tensorType) { - KP_LOG_DEBUG("Kompute TensorT constructor with data size {}", + KP_LOG_DEBUG("Kompute TensorT filling constructor with data size {}", data.size()); } diff --git a/test/TestTensor.cpp b/test/TestTensor.cpp index 7eeff4af..0aaeb995 100644 --- a/test/TestTensor.cpp +++ b/test/TestTensor.cpp @@ -15,6 +15,14 @@ TEST(TestTensor, ConstructorData) EXPECT_EQ(tensor->vector(), vec); } +TEST(TestTensor, ReserveData) +{ + kp::Manager mgr; + std::shared_ptr> tensor = mgr.tensor(3, sizeof(uint32_t), Tensor::TensorDataType::eUnsignedInt); + EXPECT_EQ(tensor->size(), 0); + EXPECT_EQ(tensor->dataTypeMemorySize(), sizeof(uint32_t)); +} + TEST(TestTensor, DataTypes) { kp::Manager mgr;