Kompute
Tensor.hpp
1 // SPDX-License-Identifier: Apache-2.0
2 #pragma once
3 
4 #include "kompute/Core.hpp"
5 #include "logger/Logger.hpp"
6 #include <memory>
7 #include <string>
8 
9 namespace kp {
10 
19 class Tensor
20 {
21  public:
28  enum class TensorTypes
29  {
30  eDevice = 0,
31  eHost = 1,
32  eStorage = 2,
33  };
34  enum class TensorDataTypes
35  {
36  eBool = 0,
37  eInt = 1,
38  eUnsignedInt = 2,
39  eFloat = 3,
40  eDouble = 4,
41  };
42 
43  static std::string toString(TensorDataTypes dt);
44  static std::string toString(TensorTypes dt);
45 
56  Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
57  std::shared_ptr<vk::Device> device,
58  void* data,
59  uint32_t elementTotalCount,
60  uint32_t elementMemorySize,
61  const TensorDataTypes& dataType,
63 
68  virtual ~Tensor();
69 
77  void rebuild(void* data,
78  uint32_t elementTotalCount,
79  uint32_t elementMemorySize);
80 
84  void destroy();
85 
91  bool isInit();
92 
99 
108  void recordCopyFrom(const vk::CommandBuffer& commandBuffer,
109  std::shared_ptr<Tensor> copyFromTensor);
110 
118  void recordCopyFromStagingToDevice(const vk::CommandBuffer& commandBuffer);
119 
127  void recordCopyFromDeviceToStaging(const vk::CommandBuffer& commandBuffer);
128 
141  const vk::CommandBuffer& commandBuffer,
142  vk::AccessFlagBits srcAccessMask,
143  vk::AccessFlagBits dstAccessMask,
144  vk::PipelineStageFlagBits srcStageMask,
145  vk::PipelineStageFlagBits dstStageMask);
158  const vk::CommandBuffer& commandBuffer,
159  vk::AccessFlagBits srcAccessMask,
160  vk::AccessFlagBits dstAccessMask,
161  vk::PipelineStageFlagBits srcStageMask,
162  vk::PipelineStageFlagBits dstStageMask);
163 
171  vk::DescriptorBufferInfo constructDescriptorBufferInfo();
172 
179  uint32_t size();
180 
188  uint32_t dataTypeMemorySize();
189 
197  uint32_t memorySize();
198 
204  TensorDataTypes dataType();
205 
213  void* rawData();
214 
219  void setRawData(const void* data);
220 
228  template<typename T>
229  T* data()
230  {
231  return (T*)this->mRawData;
232  }
233 
241  template<typename T>
242  std::vector<T> vector()
243  {
244  return { (T*)this->mRawData, ((T*)this->mRawData) + this->size() };
245  }
246 
247  protected:
248  // -------------- ALWAYS OWNED RESOURCES
249  TensorTypes mTensorType;
250  TensorDataTypes mDataType;
251  uint32_t mSize;
252  uint32_t mDataTypeMemorySize;
253  void* mRawData;
254 
255  private:
256  // -------------- NEVER OWNED RESOURCES
257  std::shared_ptr<vk::PhysicalDevice> mPhysicalDevice;
258  std::shared_ptr<vk::Device> mDevice;
259 
260  // -------------- OPTIONALLY OWNED RESOURCES
261  std::shared_ptr<vk::Buffer> mPrimaryBuffer;
262  bool mFreePrimaryBuffer = false;
263  std::shared_ptr<vk::Buffer> mStagingBuffer;
264  bool mFreeStagingBuffer = false;
265  std::shared_ptr<vk::DeviceMemory> mPrimaryMemory;
266  bool mFreePrimaryMemory = false;
267  std::shared_ptr<vk::DeviceMemory> mStagingMemory;
268  bool mFreeStagingMemory = false;
269 
270  void allocateMemoryCreateGPUResources(); // Creates the vulkan buffer
271  void createBuffer(std::shared_ptr<vk::Buffer> buffer,
272  vk::BufferUsageFlags bufferUsageFlags);
273  void allocateBindMemory(std::shared_ptr<vk::Buffer> buffer,
274  std::shared_ptr<vk::DeviceMemory> memory,
275  vk::MemoryPropertyFlags memoryPropertyFlags);
276  void recordCopyBuffer(const vk::CommandBuffer& commandBuffer,
277  std::shared_ptr<vk::Buffer> bufferFrom,
278  std::shared_ptr<vk::Buffer> bufferTo,
279  vk::DeviceSize bufferSize,
280  vk::BufferCopy copyRegion);
281  void recordBufferMemoryBarrier(const vk::CommandBuffer& commandBuffer,
282  const vk::Buffer& buffer,
283  vk::AccessFlagBits srcAccessMask,
284  vk::AccessFlagBits dstAccessMask,
285  vk::PipelineStageFlagBits srcStageMask,
286  vk::PipelineStageFlagBits dstStageMask);
287 
288  // Private util functions
289  vk::BufferUsageFlags getPrimaryBufferUsageFlags();
290  vk::MemoryPropertyFlags getPrimaryMemoryPropertyFlags();
291  vk::BufferUsageFlags getStagingBufferUsageFlags();
292  vk::MemoryPropertyFlags getStagingMemoryPropertyFlags();
293 
294  void mapRawData();
295  void unmapRawData();
296 };
297 
298 template<typename T>
299 class TensorT : public Tensor
300 {
301 
302  public:
303  TensorT(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
304  std::shared_ptr<vk::Device> device,
305  const std::vector<T>& data,
307  : Tensor(physicalDevice,
308  device,
309  (void*)data.data(),
310  data.size(),
311  sizeof(T),
312  this->dataType(),
313  tensorType)
314  {
315  KP_LOG_DEBUG("Kompute TensorT constructor with data size {}",
316  data.size());
317  }
318 
319  ~TensorT() { KP_LOG_DEBUG("Kompute TensorT destructor"); }
320 
321  T* data() { return (T*)this->mRawData; }
322 
323  std::vector<T> vector()
324  {
325  return { (T*)this->mRawData, ((T*)this->mRawData) + this->size() };
326  }
327 
328  T& operator[](int index) { return *(((T*)this->mRawData) + index); }
329 
330  void setData(const std::vector<T>& data)
331  {
332 
333  KP_LOG_DEBUG("Kompute TensorT setting data with data size {}",
334  data.size());
335 
336  if (data.size() != this->mSize) {
337  throw std::runtime_error(
338  "Kompute TensorT Cannot set data of different sizes");
339  }
340 
341  Tensor::setRawData(data.data());
342  }
343 
344  TensorDataTypes dataType();
345 };
346 
347 } // End namespace kp
Definition: Tensor.hpp:300
Definition: Tensor.hpp:20
std::vector< T > vector()
Definition: Tensor.hpp:242
TensorTypes
Definition: Tensor.hpp:29
@ eDevice
Type is device memory, source and destination.
@ eHost
Type is host memory, source and destination.
@ eStorage
Type is Device memory (only)
void recordPrimaryBufferMemoryBarrier(const vk::CommandBuffer &commandBuffer, vk::AccessFlagBits srcAccessMask, vk::AccessFlagBits dstAccessMask, vk::PipelineStageFlagBits srcStageMask, vk::PipelineStageFlagBits dstStageMask)
uint32_t size()
void * rawData()
uint32_t dataTypeMemorySize()
TensorDataTypes dataType()
uint32_t memorySize()
TensorTypes tensorType()
void destroy()
void setRawData(const void *data)
vk::DescriptorBufferInfo constructDescriptorBufferInfo()
void recordCopyFromDeviceToStaging(const vk::CommandBuffer &commandBuffer)
virtual ~Tensor()
void recordCopyFromStagingToDevice(const vk::CommandBuffer &commandBuffer)
Tensor(std::shared_ptr< vk::PhysicalDevice > physicalDevice, std::shared_ptr< vk::Device > device, void *data, uint32_t elementTotalCount, uint32_t elementMemorySize, const TensorDataTypes &dataType, const TensorTypes &tensorType=TensorTypes::eDevice)
void recordStagingBufferMemoryBarrier(const vk::CommandBuffer &commandBuffer, vk::AccessFlagBits srcAccessMask, vk::AccessFlagBits dstAccessMask, vk::PipelineStageFlagBits srcStageMask, vk::PipelineStageFlagBits dstStageMask)
void rebuild(void *data, uint32_t elementTotalCount, uint32_t elementMemorySize)
bool isInit()
T * data()
Definition: Tensor.hpp:229
void recordCopyFrom(const vk::CommandBuffer &commandBuffer, std::shared_ptr< Tensor > copyFromTensor)