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