1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2018, Intel Corporation, all rights reserved.
6 // Third party copyrights are property of their respective owners.
7
8 #include "../../precomp.hpp"
9 #include "common.hpp"
10 #include "internal.hpp"
11
12 namespace cv { namespace dnn { namespace vkcom {
13
14 #ifdef HAVE_VULKAN
15
Tensor(Format fmt)16 Tensor::Tensor(Format fmt) : size_in_byte_(0), format_(fmt)
17 {
18 createContext();
19 device_ = kDevice;
20 }
21
Tensor(const char * data,std::vector<int> & shape,Format fmt)22 Tensor::Tensor(const char* data, std::vector<int>& shape, Format fmt)
23 : size_in_byte_(0), format_(fmt)
24 {
25 createContext();
26 device_ = kDevice;
27 reshape(data, shape);
28 }
29
map()30 void* Tensor::map()
31 {
32 void *p;
33
34 VK_CHECK_RESULT(vkMapMemory(device_, buffer_->getVkMemory(),
35 0, size_in_byte_, 0, (void **)&p));
36
37 return p;
38 }
39
unMap()40 void Tensor::unMap()
41 {
42 vkUnmapMemory(device_, buffer_->getVkMemory());
43 }
44
getShape() const45 Shape Tensor::getShape() const
46 {
47 return shape_;
48 }
49
count(const int start_axis,const int end_axis) const50 int Tensor::count(const int start_axis, const int end_axis) const
51 {
52 return shapeCount(shape_, start_axis, end_axis);
53 }
54
dimSize(const int axis) const55 int Tensor::dimSize(const int axis) const
56 {
57 CV_Assert(axis >= 0);
58 CV_Assert(axis < shape_.size());
59
60 return shape_[axis];
61 }
62
dimNum() const63 int Tensor::dimNum() const
64 {
65 return shape_.size();
66 }
67
reshape(const char * data,const std::vector<int> & shape,bool alloc,Format fmt)68 Tensor Tensor::reshape(const char* data, const std::vector<int>& shape, bool alloc, Format fmt)
69 {
70 if (device_ == VK_NULL_HANDLE)
71 {
72 CV_Error(Error::StsError, "device is NULL");
73 return *this;
74 }
75
76 CV_Assert(shape.size() > 0 && shape.size() <= 6);
77
78 if (shape_ != shape) shape_ = shape;
79 if (checkFormat(fmt) && fmt != format_) format_ = fmt;
80
81 size_t new_size = shapeCount(shape_) * elementSize(format_);
82 if (alloc || new_size > size_in_byte_)
83 alloc = true;
84 size_in_byte_ = new_size;
85
86 if (alloc)
87 {
88 buffer_.reset(new Buffer(device_, size_in_byte_, data));
89 }
90 else if (data)
91 {
92 void* p = map();
93 memcpy(p, data, size_in_byte_);
94 unMap();
95 }
96
97 return *this;
98 }
99
setTo(float val)100 void Tensor::setTo(float val)
101 {
102 if (device_ == VK_NULL_HANDLE)
103 {
104 CV_Error(Error::StsError, "device is NULL");
105 return;
106 }
107
108 CV_Assert(format_ == kFormatFp32);
109
110 float* p = (float *)map();
111 int cnt = count();
112 for (int i = 0; i < cnt; i++)
113 *p++ = val;
114 unMap();
115 }
116
getFormat() const117 int Tensor::getFormat() const
118 {
119 return format_;
120 }
121
copyTo(Tensor & dst)122 void Tensor::copyTo(Tensor& dst)
123 {
124 void* p = map();
125 dst.reshape((const char*)p, shape_, format_);
126 unMap();
127 }
128
129 #endif // HAVE_VULKAN
130
131 }}} // namespace cv::dnn::vkcom
132