Skip to content

Commit fe459c8

Browse files
mshabuninalalek
authored andcommitted
Merge pull request opencv#13332 from mshabunin:dnn-backends
DNN backends registry (opencv#13332) * Added dnn backends registry * dnn: process DLIE/FPGA target
1 parent cdf906b commit fe459c8

File tree

9 files changed

+138
-133
lines changed

9 files changed

+138
-133
lines changed

modules/dnn/include/opencv2/dnn/dnn.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
9393
DNN_TARGET_FPGA
9494
};
9595

96+
CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
97+
CV_EXPORTS std::vector<Target> getAvailableTargets(Backend be);
98+
9699
/** @brief This class provides all data needed to initialize layer.
97100
*
98101
* It includes dictionary with scalar params (which can be read by using Dict interface),

modules/dnn/perf/perf_net.cpp

-17
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,6 @@ class DNNTestNetwork : public ::perf::TestBaseWithParam< tuple<Backend, Target>
3131
void processNet(std::string weights, std::string proto, std::string halide_scheduler,
3232
const Mat& input, const std::string& outputLayer = "")
3333
{
34-
if (backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
35-
{
36-
#if defined(HAVE_OPENCL)
37-
if (!cv::ocl::useOpenCL())
38-
#endif
39-
{
40-
throw cvtest::SkipTestException("OpenCL is not available/disabled in OpenCV");
41-
}
42-
}
43-
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
44-
{
45-
if (!checkIETarget(DNN_TARGET_MYRIAD))
46-
{
47-
throw SkipTestException("Myriad is not available/disabled in OpenCV");
48-
}
49-
}
50-
5134
randu(input, 0.0f, 1.0f);
5235

5336
weights = findDataFile(weights, false);

modules/dnn/src/dnn.cpp

+98
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,104 @@ static int PARAM_DNN_BACKEND_DEFAULT = (int)utils::getConfigurationParameterSize
7474
#endif
7575
);
7676

77+
//==================================================================================================
78+
79+
class BackendRegistry
80+
{
81+
public:
82+
typedef std::vector< std::pair<Backend, Target> > BackendsList;
83+
const BackendsList & getBackends() const { return backends; }
84+
static BackendRegistry & getRegistry()
85+
{
86+
static BackendRegistry impl;
87+
return impl;
88+
}
89+
private:
90+
BackendRegistry()
91+
{
92+
#ifdef HAVE_HALIDE
93+
backends.push_back(std::make_pair(DNN_BACKEND_HALIDE, DNN_TARGET_CPU));
94+
# ifdef HAVE_OPENCL
95+
if (cv::ocl::useOpenCL())
96+
backends.push_back(std::make_pair(DNN_BACKEND_HALIDE, DNN_TARGET_OPENCL));
97+
# endif
98+
#endif // HAVE_HALIDE
99+
100+
#ifdef HAVE_INF_ENGINE
101+
if (checkIETarget(DNN_TARGET_CPU))
102+
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_CPU));
103+
if (checkIETarget(DNN_TARGET_MYRIAD))
104+
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_MYRIAD));
105+
if (checkIETarget(DNN_TARGET_FPGA))
106+
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_FPGA));
107+
# ifdef HAVE_OPENCL
108+
if (cv::ocl::useOpenCL() && ocl::Device::getDefault().isIntel())
109+
{
110+
if (checkIETarget(DNN_TARGET_OPENCL))
111+
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL));
112+
if (checkIETarget(DNN_TARGET_OPENCL_FP16))
113+
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL_FP16));
114+
}
115+
# endif
116+
#endif // HAVE_INF_ENGINE
117+
118+
#ifdef HAVE_OPENCL
119+
if (cv::ocl::useOpenCL())
120+
{
121+
backends.push_back(std::make_pair(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL));
122+
backends.push_back(std::make_pair(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL_FP16));
123+
}
124+
#endif
125+
126+
backends.push_back(std::make_pair(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
127+
}
128+
static inline bool checkIETarget(int target)
129+
{
130+
#ifndef HAVE_INF_ENGINE
131+
return false;
132+
#else
133+
cv::dnn::Net net;
134+
cv::dnn::LayerParams lp;
135+
net.addLayerToPrev("testLayer", "Identity", lp);
136+
net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
137+
net.setPreferableTarget(target);
138+
static int inpDims[] = {1, 2, 3, 4};
139+
net.setInput(cv::Mat(4, &inpDims[0], CV_32FC1, cv::Scalar(0)));
140+
try
141+
{
142+
net.forward();
143+
}
144+
catch(...)
145+
{
146+
return false;
147+
}
148+
return true;
149+
#endif
150+
}
151+
152+
BackendsList backends;
153+
};
154+
155+
156+
std::vector< std::pair<Backend, Target> > getAvailableBackends()
157+
{
158+
return BackendRegistry::getRegistry().getBackends();
159+
}
160+
161+
std::vector<Target> getAvailableTargets(Backend be)
162+
{
163+
std::vector<Target> result;
164+
const BackendRegistry::BackendsList all_backends = getAvailableBackends();
165+
for(BackendRegistry::BackendsList::const_iterator i = all_backends.begin(); i != all_backends.end(); ++i )
166+
{
167+
if (i->first == be)
168+
result.push_back(i->second);
169+
}
170+
return result;
171+
}
172+
173+
//==================================================================================================
174+
77175
// Additional checks (slowdowns execution!)
78176
static bool DNN_CHECK_NAN_INF = utils::getConfigurationParameterBool("OPENCV_DNN_CHECK_NAN_INF", false);
79177
static bool DNN_CHECK_NAN_INF_DUMP = utils::getConfigurationParameterBool("OPENCV_DNN_CHECK_NAN_INF_DUMP", false);

modules/dnn/test/test_backends.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,6 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
292292
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", inp, "", "", l1, lInf);
293293
}
294294

295-
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets(true, true, false));
295+
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets());
296296

297297
}} // namespace

modules/dnn/test/test_caffe_importer.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,11 @@ INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_ResNet50,
300300
typedef testing::TestWithParam<Target> Reproducibility_SqueezeNet_v1_1;
301301
TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy)
302302
{
303+
int targetId = GetParam();
304+
if(targetId == DNN_TARGET_OPENCL_FP16)
305+
throw SkipTestException("This test does not support FP16");
303306
Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt", false),
304307
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
305-
306-
int targetId = GetParam();
307308
net.setPreferableBackend(DNN_BACKEND_OPENCV);
308309
net.setPreferableTarget(targetId);
309310

@@ -324,7 +325,8 @@ TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy)
324325
Mat ref = blobFromNPY(_tf("squeezenet_v1.1_prob.npy"));
325326
normAssert(ref, out);
326327
}
327-
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1, availableDnnTargets());
328+
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1,
329+
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
328330

329331
TEST(Reproducibility_AlexNet_fp16, Accuracy)
330332
{

modules/dnn/test/test_common.hpp

+14-84
Original file line numberDiff line numberDiff line change
@@ -189,30 +189,6 @@ static inline void normAssertDetections(cv::Mat ref, cv::Mat out, const char *co
189189
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
190190
}
191191

192-
static inline bool checkIETarget(int target)
193-
{
194-
#ifndef HAVE_INF_ENGINE
195-
return false;
196-
#else
197-
cv::dnn::Net net;
198-
cv::dnn::LayerParams lp;
199-
net.addLayerToPrev("testLayer", "Identity", lp);
200-
net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
201-
net.setPreferableTarget(target);
202-
static int inpDims[] = {1, 2, 3, 4};
203-
net.setInput(cv::Mat(4, &inpDims[0], CV_32FC1, cv::Scalar(0)));
204-
try
205-
{
206-
net.forward();
207-
}
208-
catch(...)
209-
{
210-
return false;
211-
}
212-
return true;
213-
#endif
214-
}
215-
216192
static inline bool readFileInMemory(const std::string& filename, std::string& content)
217193
{
218194
std::ios::openmode mode = std::ios::in | std::ios::binary;
@@ -237,49 +213,31 @@ namespace opencv_test {
237213
using namespace cv::dnn;
238214

239215
static inline
240-
testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets(
216+
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
241217
bool withInferenceEngine = true,
242218
bool withHalide = false,
243219
bool withCpuOCV = true
244220
)
245221
{
246-
std::vector<tuple<Backend, Target> > targets;
247-
#ifdef HAVE_HALIDE
222+
std::vector< tuple<Backend, Target> > targets;
223+
std::vector< Target > available;
248224
if (withHalide)
249225
{
250-
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, DNN_TARGET_CPU));
251-
#ifdef HAVE_OPENCL
252-
if (cv::ocl::useOpenCL())
253-
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, DNN_TARGET_OPENCL));
254-
#endif
226+
available = getAvailableTargets(DNN_BACKEND_HALIDE);
227+
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
228+
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
255229
}
256-
#endif
257-
#ifdef HAVE_INF_ENGINE
258230
if (withInferenceEngine)
259231
{
260-
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_CPU));
261-
#ifdef HAVE_OPENCL
262-
if (cv::ocl::useOpenCL() && ocl::Device::getDefault().isIntel())
263-
{
264-
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL));
265-
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL_FP16));
266-
}
267-
#endif
268-
if (checkIETarget(DNN_TARGET_MYRIAD))
269-
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_MYRIAD));
232+
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
233+
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
234+
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, *i));
270235
}
271-
#endif
272-
if (withCpuOCV)
273-
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
274-
#ifdef HAVE_OPENCL
275-
if (cv::ocl::useOpenCL())
276236
{
277-
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL));
278-
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL_FP16));
237+
available = getAvailableTargets(DNN_BACKEND_OPENCV);
238+
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
239+
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
279240
}
280-
#endif
281-
if (targets.empty()) // validate at least CPU mode
282-
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
283241
return testing::ValuesIn(targets);
284242
}
285243

@@ -289,21 +247,6 @@ testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets
289247
namespace opencv_test {
290248
using namespace cv::dnn;
291249

292-
static inline
293-
testing::internal::ParamGenerator<Target> availableDnnTargets()
294-
{
295-
static std::vector<Target> targets;
296-
if (targets.empty())
297-
{
298-
targets.push_back(DNN_TARGET_CPU);
299-
#ifdef HAVE_OPENCL
300-
if (cv::ocl::useOpenCL())
301-
targets.push_back(DNN_TARGET_OPENCL);
302-
#endif
303-
}
304-
return testing::ValuesIn(targets);
305-
}
306-
307250
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
308251
{
309252
public:
@@ -332,23 +275,10 @@ class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
332275
}
333276
}
334277

335-
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
336-
{
337-
if (backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
338-
{
339-
#ifdef HAVE_OPENCL
340-
if (!cv::ocl::useOpenCL())
341-
#endif
342-
{
343-
throw SkipTestException("OpenCL is not available/disabled in OpenCV");
344-
}
345-
}
278+
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
279+
{
346280
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
347281
{
348-
if (!checkIETarget(DNN_TARGET_MYRIAD))
349-
{
350-
throw SkipTestException("Myriad is not available/disabled in OpenCV");
351-
}
352282
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018030000
353283
if (inp && ref && inp->size[0] != 1)
354284
{

modules/dnn/test/test_googlenet.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ static std::string _tf(TString filename)
5555
typedef testing::TestWithParam<Target> Reproducibility_GoogLeNet;
5656
TEST_P(Reproducibility_GoogLeNet, Batching)
5757
{
58+
const int targetId = GetParam();
59+
if(targetId == DNN_TARGET_OPENCL_FP16)
60+
throw SkipTestException("This test does not support FP16");
5861
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false),
5962
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
60-
int targetId = GetParam();
6163
net.setPreferableBackend(DNN_BACKEND_OPENCV);
6264
net.setPreferableTarget(targetId);
6365

@@ -84,9 +86,11 @@ TEST_P(Reproducibility_GoogLeNet, Batching)
8486

8587
TEST_P(Reproducibility_GoogLeNet, IntermediateBlobs)
8688
{
89+
const int targetId = GetParam();
90+
if(targetId == DNN_TARGET_OPENCL_FP16)
91+
throw SkipTestException("This test does not support FP16");
8792
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false),
8893
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
89-
int targetId = GetParam();
9094
net.setPreferableBackend(DNN_BACKEND_OPENCV);
9195
net.setPreferableTarget(targetId);
9296

@@ -113,9 +117,11 @@ TEST_P(Reproducibility_GoogLeNet, IntermediateBlobs)
113117

114118
TEST_P(Reproducibility_GoogLeNet, SeveralCalls)
115119
{
120+
const int targetId = GetParam();
121+
if(targetId == DNN_TARGET_OPENCL_FP16)
122+
throw SkipTestException("This test does not support FP16");
116123
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false),
117124
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
118-
int targetId = GetParam();
119125
net.setPreferableBackend(DNN_BACKEND_OPENCV);
120126
net.setPreferableTarget(targetId);
121127

@@ -143,6 +149,7 @@ TEST_P(Reproducibility_GoogLeNet, SeveralCalls)
143149
normAssert(outs[0], ref, "", 1E-4, 1E-2);
144150
}
145151

146-
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_GoogLeNet, availableDnnTargets());
152+
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_GoogLeNet,
153+
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
147154

148155
}} // namespace

0 commit comments

Comments
 (0)