Skip to content

Commit c802826

Browse files
committed
Solving precision problems in mul and div with scale
Ascend NPU will cause precision loss due to type conversion when calculating multiplication and division for integers. Cast to float and round result to avoid precision loss. Removed duplicate code.
1 parent 8896676 commit c802826

File tree

10 files changed

+289
-413
lines changed

10 files changed

+289
-413
lines changed

modules/cannops/include/opencv2/cann.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,17 @@ class CV_EXPORTS_W AscendMat
6767

6868
//! constructs AscendMat of the specified size and type
6969
CV_WRAP AscendMat(int rows, int cols, int type,
70-
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
70+
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
7171
//! constructs AscendMat of the specified size and type
72-
CV_WRAP AscendMat(Size size, int type, AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
72+
CV_WRAP AscendMat(Size size, int type,
73+
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
7374

7475
//! constructs AscendMat and fills it with the specified value s
7576
CV_WRAP AscendMat(int rows, int cols, int type, Scalar& s,
76-
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
77+
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
7778
//! constructs AscendMat and fills it with the specified value s
7879
CV_WRAP AscendMat(Size size, int type, Scalar& s,
79-
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
80+
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
8081

8182
//! copy constructor
8283
CV_WRAP AscendMat(const AscendMat& m);
@@ -87,7 +88,7 @@ class CV_EXPORTS_W AscendMat
8788

8889
//! builds AscendMat from host memory (Blocking call)
8990
CV_WRAP explicit AscendMat(InputArray arr, AscendStream& stream,
90-
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
91+
AscendMat::Allocator* allocator = AscendMat::defaultAllocator());
9192

9293
//! assignment operators
9394
AscendMat& operator=(const AscendMat& m);
@@ -125,6 +126,9 @@ class CV_EXPORTS_W AscendMat
125126
//! converts AscendMat to another datatype (Non-Blocking call)
126127
CV_WRAP void convertTo(CV_OUT AscendMat& dst, int rtype, AscendStream& stream) const;
127128

129+
//! converts AscendMat to another datatype, dst mat is allocated. (Non-Blocking call)
130+
CV_WRAP void convertTo(CV_OUT AscendMat& dst, AscendStream& stream) const;
131+
128132
//! returns true iff the AscendMat data is continuous
129133
//! (i.e. when there are no gaps between successive rows)
130134
CV_WRAP bool isContinuous() const;

modules/cannops/include/opencv2/cann_call.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ void aclrtMemcpy2dWarpper(void* dst, size_t dpitch, const std::shared_ptr<uchar>
3434
AscendStream& stream);
3535
void aclrtMemsetWarpper(std::shared_ptr<uchar>& ptr, int32_t value, size_t count,
3636
AscendStream& stream);
37+
aclDataType getACLType(int opencvdepth);
3738
std::shared_ptr<uchar> mallocAndUpload(const void* data, size_t size, AscendStream& stream,
3839
AscendMat::Allocator* allocator);
3940

@@ -107,16 +108,20 @@ class OperatorRunner
107108
OperatorRunner& addAttr(const int64_t* value, int size, const char* name);
108109
OperatorRunner& addInput(const AscendMat& mat, const char* name);
109110
OperatorRunner& addInput(const Scalar& sc, int type, const char* name);
111+
110112
template <typename T>
111-
OperatorRunner& addInput(const T* value, size_t size, aclDataType type, AscendStream& stream,
113+
OperatorRunner& addInput(const T* value, int64_t* dims, size_t dimSize, aclDataType type,
112114
const char* name)
113115
{
116+
int64_t size = dims[0];
117+
for (size_t i = 1; i < dimSize; i++)
118+
size *= dims[i];
119+
114120
size_t dataSize = size * sizeof(T);
115-
std::shared_ptr<uchar> axisPtr =
116-
mallocAndUpload(value, dataSize, stream, AscendMat::defaultAllocator());
121+
std::shared_ptr<uchar> ptr =
122+
mallocAndUpload(value, dataSize, AscendStream::Null(), AscendMat::defaultAllocator());
117123

118-
int64_t dims[] = {(int64_t)size};
119-
AscendTensor tensor(axisPtr, dataSize, dims, 1, type, name);
124+
AscendTensor tensor(ptr, dataSize, dims, dimSize, type, name);
120125
return addInput(tensor);
121126
}
122127
OperatorRunner& addOutput(AscendMat& mat, const char* name);

modules/cannops/include/opencv2/cann_private.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ namespace cv
1010
{
1111
namespace cann
1212
{
13+
void arithm_op(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const char* op,
14+
AscendStream& stream);
15+
void arithm_op(const AscendMat& src, const Scalar& sc, AscendMat& dst, const char* op,
16+
AscendStream& stream);
17+
void arithm_op(const Scalar& sc, const AscendMat& src, AscendMat& dst, const char* op,
18+
AscendStream& stream);
19+
void arithm_op(const AscendMat& src, AscendMat& dst, const char* op, AscendStream& stream);
20+
void arithm_op(const AscendMat& src, float scalar, AscendMat& dst, const char* op,
21+
AscendStream& stream);
1322
void transData(const AscendMat& src, AscendMat& dst, const char* from, const char* to,
1423
AscendStream& stream);
1524
void transpose(const AscendMat& src, int64_t* perm, AscendMat& dst, AscendStream& stream);

modules/cannops/src/ascend_mat.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,8 @@ AscendMat& AscendMat::setTo(const Scalar& sc, AscendStream& stream)
182182
return *this;
183183

184184
aclrtMemsetWarpper(data, 0, totalBytes, stream);
185-
186185
AscendMat dst(rows, cols, type());
187-
// TODO use AssignAdd to avoid memcpy, or use broadcase.
188-
OperatorRunner runner;
189-
runner.setOp("Add")
190-
.addInput(*this, "")
191-
.addInput(sc, this->flags, "")
192-
.addOutput(dst, "")
193-
.run(stream);
186+
arithm_op(*this, sc, dst, "Add", stream);
194187
swap(dst);
195188

196189
return *this;
@@ -207,8 +200,7 @@ AscendMat& AscendMat::setTo(float sc, AscendStream& stream)
207200
aclrtMemsetWarpper(data, 0, totalBytes, stream);
208201

209202
AscendMat dst(rows, cols, type());
210-
OperatorRunner runner;
211-
runner.setOp("Adds").addInput(*this, "").addOutput(dst, "").addAttr(sc, "value").run(stream);
203+
arithm_op(*this, sc, dst, "Adds", stream);
212204
swap(dst);
213205

214206
return *this;
@@ -223,8 +215,17 @@ void AscendMat::convertTo(AscendMat& dst, int _rtype, AscendStream& stream) cons
223215
{
224216
int cn = channels();
225217
dst.create(rows, cols, CV_MAKE_TYPE(_rtype, cn));
218+
convertTo(dst, stream);
219+
}
220+
221+
void AscendMat::convertTo(AscendMat& dst, AscendStream& stream) const
222+
{
226223
OperatorRunner runner;
227-
runner.setOp("Cast").addInput(*this, "").addOutput(dst, "").run(stream);
224+
runner.setOp("Cast")
225+
.addInput(*this, "x")
226+
.addOutput(dst, "y")
227+
.addAttr((int32_t)(getACLType(dst.depth())), "dst_type")
228+
.run(stream);
228229
}
229230

230231
static AscendMat getAscendMat(InputArray arr)

modules/cannops/src/cann_call.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void aclrtMemsetWarpper(std::shared_ptr<uchar>& ptr, int32_t value, size_t count
141141
}
142142
}
143143

144-
static inline aclDataType getACLType(int opencvdepth)
144+
aclDataType getACLType(int opencvdepth)
145145
{
146146
switch (opencvdepth)
147147
{
@@ -167,7 +167,7 @@ static inline aclDataType getACLType(int opencvdepth)
167167
}
168168

169169
std::shared_ptr<uchar> mallocAndUpload(const void* data, size_t size, AscendStream& stream,
170-
AscendMat::Allocator* allocator)
170+
AscendMat::Allocator* allocator)
171171
{
172172
std::shared_ptr<uchar> ptr = allocator->allocate(size);
173173
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
@@ -202,7 +202,7 @@ OperatorRunner& OperatorRunner::reset()
202202
{
203203
CV_ACL_SAFE_CALL(aclDestroyDataBuffer(buf));
204204
}
205-
if(opAttrInit)
205+
if (opAttrInit)
206206
aclopDestroyAttr(opAttr_);
207207
inputDesc_.clear();
208208
outputDesc_.clear();
@@ -301,12 +301,12 @@ OperatorRunner& OperatorRunner::addInput(const Scalar& sc, int type, const char*
301301
{
302302
uchar rawData[32];
303303
cv::scalarToRawData(sc, rawData, type, 0);
304-
std::shared_ptr<uchar> scPtr =
305-
mallocAndUpload(rawData, (CV_ELEM_SIZE(type)), AscendStream::Null(), AscendMat::defaultAllocator());
304+
std::shared_ptr<uchar> scPtr = mallocAndUpload(
305+
rawData, (CV_ELEM_SIZE(type)), AscendStream::Null(), AscendMat::defaultAllocator());
306306

307307
int64_t dims[] = {1, 1, 1, (CV_MAT_CN(type))};
308308
AscendTensor tensor(scPtr, (CV_ELEM_SIZE(type)), dims, sizeof(dims) / sizeof(dims[0]),
309-
getACLType(CV_MAT_DEPTH(type)), name);
309+
getACLType(CV_MAT_DEPTH(type)), name);
310310
return addInput(tensor);
311311
}
312312

0 commit comments

Comments
 (0)