Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenCV
opencv
提交
17d99e62
O
opencv
项目概览
OpenCV
/
opencv
上一次同步 8 个月
通知
979
Star
71099
Fork
55580
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
17d99e62
编写于
11月 29, 2021
作者:
A
Alexander Alekhin
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #21142 from alalek:dnn_two_inputs_ocl_fp16_3.4
上级
ea7d4be3
58b06222
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
121 addition
and
103 deletion
+121
-103
modules/dnn/src/dnn.cpp
modules/dnn/src/dnn.cpp
+61
-52
modules/dnn/test/test_layers.cpp
modules/dnn/test/test_layers.cpp
+0
-51
modules/dnn/test/test_misc.cpp
modules/dnn/test/test_misc.cpp
+60
-0
未找到文件。
modules/dnn/src/dnn.cpp
浏览文件 @
17d99e62
...
...
@@ -597,29 +597,26 @@ struct DataLayer : public Layer
CV_TRACE_FUNCTION
();
CV_TRACE_ARG_VALUE
(
name
,
"name"
,
name
.
c_str
());
// FIXIT: add wrapper without exception suppression
CV_OCL_RUN
(
IS_DNN_OPENCL_TARGET
(
preferableTarget
),
forward_ocl
(
inputs_arr
,
outputs_arr
,
internals_arr
))
if
(
outputs_arr
.
depth
()
==
CV_16S
)
{
forward_fallback
(
inputs_arr
,
outputs_arr
,
internals_arr
);
return
;
}
bool
isFP16
=
outputs_arr
.
depth
()
==
CV_16S
;
std
::
vector
<
Mat
>
outputs
,
internals
;
outputs_arr
.
getMatVector
(
outputs
);
internals_arr
.
getMatVector
(
internals
);
// Supported modes:
// | Input type | Output type |
// | fp32 | fp32 |
// | uint8 | fp32 |
for
(
int
i
=
0
;
i
<
inputsData
.
size
();
++
i
)
{
double
scale
=
scaleFactors
[
i
];
Scalar
&
mean
=
means
[
i
];
CV_Assert
(
mean
==
Scalar
()
||
inputsData
[
i
].
size
[
1
]
<=
4
);
CV_CheckTypeEQ
(
outputs
[
i
].
type
(),
CV_32FC1
,
""
);
if
(
isFP16
)
CV_CheckTypeEQ
(
outputs
[
i
].
type
(),
CV_16SC1
,
""
);
else
CV_CheckTypeEQ
(
outputs
[
i
].
type
(),
CV_32FC1
,
""
);
bool
singleMean
=
true
;
for
(
int
j
=
1
;
j
<
std
::
min
(
4
,
inputsData
[
i
].
size
[
1
])
&&
singleMean
;
++
j
)
...
...
@@ -629,34 +626,49 @@ struct DataLayer : public Layer
if
(
singleMean
)
{
inputsData
[
i
].
convertTo
(
outputs
[
i
],
CV_32F
,
scale
,
-
mean
[
0
]
*
scale
);
if
(
isFP16
)
{
Mat
input_f32
;
inputsData
[
i
].
convertTo
(
input_f32
,
CV_32F
,
scale
,
-
mean
[
0
]
*
scale
);
convertFp16
(
input_f32
,
outputs
[
i
]);
}
else
{
inputsData
[
i
].
convertTo
(
outputs
[
i
],
CV_32F
,
scale
,
-
mean
[
0
]
*
scale
);
}
}
else
{
for
(
int
n
=
0
;
n
<
inputsData
[
i
].
size
[
0
];
++
n
)
{
for
(
int
c
=
0
;
c
<
inputsData
[
i
].
size
[
1
];
++
c
)
{
Mat
inp
=
getPlane
(
inputsData
[
i
],
n
,
c
);
Mat
out
=
getPlane
(
outputs
[
i
],
n
,
c
);
inp
.
convertTo
(
out
,
CV_32F
,
scale
,
-
mean
[
c
]
*
scale
);
if
(
isFP16
)
{
Mat
input_f32
;
inp
.
convertTo
(
input_f32
,
CV_32F
,
scale
,
-
mean
[
c
]
*
scale
);
convertFp16
(
input_f32
,
out
);
}
else
{
inp
.
convertTo
(
out
,
CV_32F
,
scale
,
-
mean
[
c
]
*
scale
);
}
}
}
}
}
}
#ifdef HAVE_OPENCL
std
::
vector
<
Mat
>
tmp_expressions
;
bool
forward_ocl
(
InputArrayOfArrays
,
OutputArrayOfArrays
outputs_
,
OutputArrayOfArrays
internals_
)
{
// Supported modes:
// | Input type | Output type |
// | fp32 | fp32 |
// | fp32 | fp16 |
// | uint8 | fp32 |
bool
isFP16
=
outputs_
.
depth
()
==
CV_16S
;
std
::
vector
<
UMat
>
outputs
;
outputs_
.
getUMatVector
(
outputs
);
tmp_expressions
.
clear
();
for
(
int
i
=
0
;
i
<
inputsData
.
size
();
++
i
)
{
Mat
inputData
=
inputsData
[
i
];
...
...
@@ -664,58 +676,55 @@ struct DataLayer : public Layer
double
scale
=
scaleFactors
[
i
];
Scalar
&
mean
=
means
[
i
];
CV_Assert
(
mean
==
Scalar
()
||
inputsData
[
i
].
size
[
1
]
<=
4
);
CV_Assert
(
mean
==
Scalar
()
||
inputData
.
size
[
1
]
<=
4
);
if
(
isFP16
)
CV_CheckTypeEQ
(
outputs
[
i
].
type
(),
CV_16SC1
,
""
);
else
CV_CheckTypeEQ
(
outputs
[
i
].
type
(),
CV_32FC1
,
""
);
bool
singleMean
=
true
;
for
(
int
j
=
1
;
j
<
std
::
min
(
4
,
input
sData
[
i
]
.
size
[
1
])
&&
singleMean
;
++
j
)
for
(
int
j
=
1
;
j
<
std
::
min
(
4
,
input
Data
.
size
[
1
])
&&
singleMean
;
++
j
)
{
singleMean
=
mean
[
j
]
==
mean
[
j
-
1
];
}
if
(
outputs_
.
depth
()
==
CV_16S
)
if
(
singleMean
)
{
if
(
singleMean
)
if
(
isFP16
)
{
tmp_expressions
.
push_back
(
Mat
(
scale
*
(
inputsData
[
i
]
-
mean
[
0
])));
convertFp16
(
tmp_expressions
.
back
(),
outputs
[
i
]);
UMat
input_i
;
inputData
.
convertTo
(
input_i
,
CV_32F
,
scale
,
-
mean
[
0
]
*
scale
);
convertFp16
(
input_i
,
outputs
[
i
]);
}
else
{
for
(
int
n
=
0
;
n
<
inputsData
[
i
].
size
[
0
];
++
n
)
for
(
int
c
=
0
;
c
<
inputsData
[
i
].
size
[
1
];
++
c
)
{
Mat
inp
=
getPlane
(
inputsData
[
i
],
n
,
c
);
std
::
vector
<
cv
::
Range
>
plane
(
4
,
Range
::
all
());
plane
[
0
]
=
Range
(
n
,
n
+
1
);
plane
[
1
]
=
Range
(
c
,
c
+
1
);
UMat
out
=
outputs
[
i
](
plane
).
reshape
(
1
,
inp
.
dims
,
inp
.
size
);
tmp_expressions
.
push_back
(
scale
*
(
inp
-
mean
[
c
]));
convertFp16
(
tmp_expressions
.
back
(),
out
);
}
inputData
.
convertTo
(
outputs
[
i
],
CV_32F
,
scale
,
-
mean
[
0
]
*
scale
);
}
}
else
{
CV_Assert
(
outputs_
.
depth
()
==
CV_32F
);
if
(
singleMean
)
{
inputsData
[
i
].
convertTo
(
outputs
[
i
],
CV_32F
,
scale
,
-
mean
[
0
]
*
scale
);
}
else
for
(
int
n
=
0
;
n
<
inputData
.
size
[
0
];
++
n
)
{
for
(
int
n
=
0
;
n
<
inputsData
[
i
].
size
[
0
];
++
n
)
for
(
int
c
=
0
;
c
<
inputsData
[
i
].
size
[
1
];
++
c
)
{
Mat
inp
=
getPlane
(
inputsData
[
i
],
n
,
c
);
for
(
int
c
=
0
;
c
<
inputData
.
size
[
1
];
++
c
)
{
Mat
inp
=
getPlane
(
inputData
,
n
,
c
);
std
::
vector
<
cv
::
Range
>
plane
(
4
,
Range
::
all
());
plane
[
0
]
=
Range
(
n
,
n
+
1
);
plane
[
1
]
=
Range
(
c
,
c
+
1
);
UMat
out
=
outputs
[
i
](
plane
).
reshape
(
1
,
inp
.
dims
,
inp
.
size
);
std
::
vector
<
cv
::
Range
>
plane
(
4
,
Range
::
all
());
plane
[
0
]
=
Range
(
n
,
n
+
1
);
plane
[
1
]
=
Range
(
c
,
c
+
1
);
UMat
out
=
outputs
[
i
](
plane
).
reshape
(
1
,
inp
.
dims
,
inp
.
size
);
if
(
isFP16
)
{
UMat
input_i
;
inp
.
convertTo
(
input_i
,
CV_32F
,
scale
,
-
mean
[
c
]
*
scale
);
convertFp16
(
input_i
,
out
);
}
else
{
inp
.
convertTo
(
out
,
CV_32F
,
scale
,
-
mean
[
c
]
*
scale
);
}
}
}
}
}
...
...
modules/dnn/test/test_layers.cpp
浏览文件 @
17d99e62
...
...
@@ -1380,57 +1380,6 @@ INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_DLDT_two_inputs_3dim, Combine(
testing
::
ValuesIn
(
list_sizes
)
));
typedef
testing
::
TestWithParam
<
tuple
<
int
,
int
,
tuple
<
Backend
,
Target
>
>
>
Test_DLDT_two_inputs
;
TEST_P
(
Test_DLDT_two_inputs
,
as_backend
)
{
static
const
float
kScale
=
0.5
f
;
static
const
float
kScaleInv
=
1.0
f
/
kScale
;
Backend
backendId
=
get
<
0
>
(
get
<
2
>
(
GetParam
()));
Target
targetId
=
get
<
1
>
(
get
<
2
>
(
GetParam
()));
Net
net
;
LayerParams
lp
;
lp
.
type
=
"Eltwise"
;
lp
.
name
=
"testLayer"
;
lp
.
set
(
"operation"
,
"sum"
);
int
eltwiseId
=
net
.
addLayerToPrev
(
lp
.
name
,
lp
.
type
,
lp
);
// connect to a first input
net
.
connect
(
0
,
1
,
eltwiseId
,
1
);
// connect to a second input
int
inpSize
[]
=
{
1
,
2
,
3
,
4
};
Mat
firstInp
(
4
,
&
inpSize
[
0
],
get
<
0
>
(
GetParam
()));
Mat
secondInp
(
4
,
&
inpSize
[
0
],
get
<
1
>
(
GetParam
()));
randu
(
firstInp
,
0
,
255
);
randu
(
secondInp
,
0
,
255
);
net
.
setInputsNames
({
"data"
,
"second_input"
});
net
.
setInput
(
firstInp
,
"data"
,
kScale
);
net
.
setInput
(
secondInp
,
"second_input"
,
kScaleInv
);
net
.
setPreferableBackend
(
backendId
);
net
.
setPreferableTarget
(
targetId
);
Mat
out
=
net
.
forward
();
Mat
ref
;
addWeighted
(
firstInp
,
kScale
,
secondInp
,
kScaleInv
,
0
,
ref
,
CV_32F
);
// Output values are in range [0, 637.5].
double
l1
=
(
targetId
==
DNN_TARGET_OPENCL_FP16
||
targetId
==
DNN_TARGET_MYRIAD
)
?
0.06
:
1e-6
;
double
lInf
=
(
targetId
==
DNN_TARGET_OPENCL_FP16
||
targetId
==
DNN_TARGET_MYRIAD
)
?
0.3
:
1e-5
;
normAssert
(
out
,
ref
,
""
,
l1
,
lInf
);
if
(
cvtest
::
debugLevel
>
0
||
HasFailure
())
{
std
::
cout
<<
"input1 scale="
<<
kScale
<<
" input2 scale="
<<
kScaleInv
<<
std
::
endl
;
std
::
cout
<<
"input1: "
<<
firstInp
.
size
<<
" "
<<
firstInp
.
reshape
(
1
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"input2: "
<<
secondInp
.
size
<<
" "
<<
secondInp
.
reshape
(
1
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"ref: "
<<
ref
.
reshape
(
1
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"out: "
<<
out
.
reshape
(
1
,
1
)
<<
std
::
endl
;
}
}
INSTANTIATE_TEST_CASE_P
(
/*nothing*/
,
Test_DLDT_two_inputs
,
Combine
(
Values
(
CV_8U
,
CV_32F
),
Values
(
CV_8U
,
CV_32F
),
dnnBackendsAndTargets
()
));
class
UnsupportedLayer
:
public
Layer
{
public:
...
...
modules/dnn/test/test_misc.cpp
浏览文件 @
17d99e62
...
...
@@ -828,4 +828,64 @@ INSTANTIATE_TEST_CASE_P(/**/, Test_Model_Optimizer,
#endif // HAVE_INF_ENGINE
typedef
testing
::
TestWithParam
<
tuple
<
MatDepth
,
MatDepth
,
tuple
<
Backend
,
Target
>
>
>
Test_two_inputs
;
TEST_P
(
Test_two_inputs
,
basic
)
{
static
const
float
kScale
=
0.5
f
;
static
const
float
kScaleInv
=
1.0
f
/
kScale
;
Backend
backendId
=
get
<
0
>
(
get
<
2
>
(
GetParam
()));
Target
targetId
=
get
<
1
>
(
get
<
2
>
(
GetParam
()));
Net
net
;
LayerParams
lp
;
lp
.
type
=
"Eltwise"
;
lp
.
name
=
"testLayer"
;
lp
.
set
(
"operation"
,
"sum"
);
int
eltwiseId
=
net
.
addLayerToPrev
(
lp
.
name
,
lp
.
type
,
lp
);
// connect to a first input
net
.
connect
(
0
,
1
,
eltwiseId
,
1
);
// connect to a second input
int
inpSize
[]
=
{
1
,
2
,
3
,
4
};
Mat
firstInp
(
4
,
&
inpSize
[
0
],
get
<
0
>
(
GetParam
()));
Mat
secondInp
(
4
,
&
inpSize
[
0
],
get
<
1
>
(
GetParam
()));
randu
(
firstInp
,
0
,
100
);
randu
(
secondInp
,
0
,
100
);
#ifndef CV_CXX11
std
::
vector
<
String
>
input_names
;
input_names
.
push_back
(
"data"
);
input_names
.
push_back
(
"second_input"
);
net
.
setInputsNames
(
input_names
);
#else
net
.
setInputsNames
({
"data"
,
"second_input"
});
#endif
net
.
setInput
(
firstInp
,
"data"
,
kScale
);
net
.
setInput
(
secondInp
,
"second_input"
,
kScaleInv
);
net
.
setPreferableBackend
(
backendId
);
net
.
setPreferableTarget
(
targetId
);
Mat
out
=
net
.
forward
();
Mat
ref
;
addWeighted
(
firstInp
,
kScale
,
secondInp
,
kScaleInv
,
0
,
ref
,
CV_32F
);
double
l1
=
(
targetId
==
DNN_TARGET_OPENCL_FP16
||
targetId
==
DNN_TARGET_MYRIAD
)
?
0.06
:
1e-6
;
double
lInf
=
(
targetId
==
DNN_TARGET_OPENCL_FP16
||
targetId
==
DNN_TARGET_MYRIAD
)
?
0.3
:
1e-5
;
normAssert
(
out
,
ref
,
""
,
l1
,
lInf
);
if
(
cvtest
::
debugLevel
>
0
||
HasFailure
())
{
std
::
cout
<<
"input1 scale="
<<
kScale
<<
" input2 scale="
<<
kScaleInv
<<
std
::
endl
;
std
::
cout
<<
"input1: "
<<
firstInp
.
size
<<
" "
<<
firstInp
.
reshape
(
1
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"input2: "
<<
secondInp
.
size
<<
" "
<<
secondInp
.
reshape
(
1
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"ref: "
<<
ref
.
reshape
(
1
,
1
)
<<
std
::
endl
;
std
::
cout
<<
"out: "
<<
out
.
reshape
(
1
,
1
)
<<
std
::
endl
;
}
}
INSTANTIATE_TEST_CASE_P
(
/*nothing*/
,
Test_two_inputs
,
Combine
(
Values
(
CV_32F
,
CV_8U
),
Values
(
CV_32F
,
CV_8U
),
dnnBackendsAndTargets
()
));
}}
// namespace
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录