提交 fe459c82 编写于 作者: M Maksim Shabunin 提交者: Alexander Alekhin

Merge pull request #13332 from mshabunin:dnn-backends

DNN backends registry (#13332)

* Added dnn backends registry

* dnn: process DLIE/FPGA target
上级 cdf906b2
......@@ -93,6 +93,9 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
DNN_TARGET_FPGA
};
CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
CV_EXPORTS std::vector<Target> getAvailableTargets(Backend be);
/** @brief This class provides all data needed to initialize layer.
*
* It includes dictionary with scalar params (which can be read by using Dict interface),
......
......@@ -31,23 +31,6 @@ public:
void processNet(std::string weights, std::string proto, std::string halide_scheduler,
const Mat& input, const std::string& outputLayer = "")
{
if (backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
{
#if defined(HAVE_OPENCL)
if (!cv::ocl::useOpenCL())
#endif
{
throw cvtest::SkipTestException("OpenCL is not available/disabled in OpenCV");
}
}
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{
if (!checkIETarget(DNN_TARGET_MYRIAD))
{
throw SkipTestException("Myriad is not available/disabled in OpenCV");
}
}
randu(input, 0.0f, 1.0f);
weights = findDataFile(weights, false);
......
......@@ -74,6 +74,104 @@ static int PARAM_DNN_BACKEND_DEFAULT = (int)utils::getConfigurationParameterSize
#endif
);
//==================================================================================================
class BackendRegistry
{
public:
typedef std::vector< std::pair<Backend, Target> > BackendsList;
const BackendsList & getBackends() const { return backends; }
static BackendRegistry & getRegistry()
{
static BackendRegistry impl;
return impl;
}
private:
BackendRegistry()
{
#ifdef HAVE_HALIDE
backends.push_back(std::make_pair(DNN_BACKEND_HALIDE, DNN_TARGET_CPU));
# ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL())
backends.push_back(std::make_pair(DNN_BACKEND_HALIDE, DNN_TARGET_OPENCL));
# endif
#endif // HAVE_HALIDE
#ifdef HAVE_INF_ENGINE
if (checkIETarget(DNN_TARGET_CPU))
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_CPU));
if (checkIETarget(DNN_TARGET_MYRIAD))
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_MYRIAD));
if (checkIETarget(DNN_TARGET_FPGA))
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_FPGA));
# ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL() && ocl::Device::getDefault().isIntel())
{
if (checkIETarget(DNN_TARGET_OPENCL))
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL));
if (checkIETarget(DNN_TARGET_OPENCL_FP16))
backends.push_back(std::make_pair(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL_FP16));
}
# endif
#endif // HAVE_INF_ENGINE
#ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL())
{
backends.push_back(std::make_pair(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL));
backends.push_back(std::make_pair(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL_FP16));
}
#endif
backends.push_back(std::make_pair(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
}
static inline bool checkIETarget(int target)
{
#ifndef HAVE_INF_ENGINE
return false;
#else
cv::dnn::Net net;
cv::dnn::LayerParams lp;
net.addLayerToPrev("testLayer", "Identity", lp);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(target);
static int inpDims[] = {1, 2, 3, 4};
net.setInput(cv::Mat(4, &inpDims[0], CV_32FC1, cv::Scalar(0)));
try
{
net.forward();
}
catch(...)
{
return false;
}
return true;
#endif
}
BackendsList backends;
};
std::vector< std::pair<Backend, Target> > getAvailableBackends()
{
return BackendRegistry::getRegistry().getBackends();
}
std::vector<Target> getAvailableTargets(Backend be)
{
std::vector<Target> result;
const BackendRegistry::BackendsList all_backends = getAvailableBackends();
for(BackendRegistry::BackendsList::const_iterator i = all_backends.begin(); i != all_backends.end(); ++i )
{
if (i->first == be)
result.push_back(i->second);
}
return result;
}
//==================================================================================================
// Additional checks (slowdowns execution!)
static bool DNN_CHECK_NAN_INF = utils::getConfigurationParameterBool("OPENCV_DNN_CHECK_NAN_INF", false);
static bool DNN_CHECK_NAN_INF_DUMP = utils::getConfigurationParameterBool("OPENCV_DNN_CHECK_NAN_INF_DUMP", false);
......
......@@ -292,6 +292,6 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", inp, "", "", l1, lInf);
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets(true, true, false));
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets());
}} // namespace
......@@ -300,10 +300,11 @@ INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_ResNet50,
typedef testing::TestWithParam<Target> Reproducibility_SqueezeNet_v1_1;
TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy)
{
int targetId = GetParam();
if(targetId == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("This test does not support FP16");
Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt", false),
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
int targetId = GetParam();
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(targetId);
......@@ -324,7 +325,8 @@ TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy)
Mat ref = blobFromNPY(_tf("squeezenet_v1.1_prob.npy"));
normAssert(ref, out);
}
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1, availableDnnTargets());
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1,
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
TEST(Reproducibility_AlexNet_fp16, Accuracy)
{
......
......@@ -189,30 +189,6 @@ static inline void normAssertDetections(cv::Mat ref, cv::Mat out, const char *co
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
}
static inline bool checkIETarget(int target)
{
#ifndef HAVE_INF_ENGINE
return false;
#else
cv::dnn::Net net;
cv::dnn::LayerParams lp;
net.addLayerToPrev("testLayer", "Identity", lp);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(target);
static int inpDims[] = {1, 2, 3, 4};
net.setInput(cv::Mat(4, &inpDims[0], CV_32FC1, cv::Scalar(0)));
try
{
net.forward();
}
catch(...)
{
return false;
}
return true;
#endif
}
static inline bool readFileInMemory(const std::string& filename, std::string& content)
{
std::ios::openmode mode = std::ios::in | std::ios::binary;
......@@ -237,49 +213,31 @@ namespace opencv_test {
using namespace cv::dnn;
static inline
testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets(
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
bool withInferenceEngine = true,
bool withHalide = false,
bool withCpuOCV = true
)
{
std::vector<tuple<Backend, Target> > targets;
#ifdef HAVE_HALIDE
std::vector< tuple<Backend, Target> > targets;
std::vector< Target > available;
if (withHalide)
{
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, DNN_TARGET_CPU));
#ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL())
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, DNN_TARGET_OPENCL));
#endif
available = getAvailableTargets(DNN_BACKEND_HALIDE);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
}
#endif
#ifdef HAVE_INF_ENGINE
if (withInferenceEngine)
{
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_CPU));
#ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL() && ocl::Device::getDefault().isIntel())
{
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL));
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL_FP16));
}
#endif
if (checkIETarget(DNN_TARGET_MYRIAD))
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_MYRIAD));
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, *i));
}
#endif
if (withCpuOCV)
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
#ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL())
{
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL));
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_OPENCL_FP16));
available = getAvailableTargets(DNN_BACKEND_OPENCV);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
}
#endif
if (targets.empty()) // validate at least CPU mode
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
return testing::ValuesIn(targets);
}
......@@ -289,21 +247,6 @@ testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets
namespace opencv_test {
using namespace cv::dnn;
static inline
testing::internal::ParamGenerator<Target> availableDnnTargets()
{
static std::vector<Target> targets;
if (targets.empty())
{
targets.push_back(DNN_TARGET_CPU);
#ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL())
targets.push_back(DNN_TARGET_OPENCL);
#endif
}
return testing::ValuesIn(targets);
}
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
{
public:
......@@ -332,23 +275,10 @@ public:
}
}
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
{
if (backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
{
#ifdef HAVE_OPENCL
if (!cv::ocl::useOpenCL())
#endif
{
throw SkipTestException("OpenCL is not available/disabled in OpenCV");
}
}
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{
if (!checkIETarget(DNN_TARGET_MYRIAD))
{
throw SkipTestException("Myriad is not available/disabled in OpenCV");
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018030000
if (inp && ref && inp->size[0] != 1)
{
......
......@@ -55,9 +55,11 @@ static std::string _tf(TString filename)
typedef testing::TestWithParam<Target> Reproducibility_GoogLeNet;
TEST_P(Reproducibility_GoogLeNet, Batching)
{
const int targetId = GetParam();
if(targetId == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("This test does not support FP16");
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false),
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
int targetId = GetParam();
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(targetId);
......@@ -84,9 +86,11 @@ TEST_P(Reproducibility_GoogLeNet, Batching)
TEST_P(Reproducibility_GoogLeNet, IntermediateBlobs)
{
const int targetId = GetParam();
if(targetId == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("This test does not support FP16");
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false),
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
int targetId = GetParam();
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(targetId);
......@@ -113,9 +117,11 @@ TEST_P(Reproducibility_GoogLeNet, IntermediateBlobs)
TEST_P(Reproducibility_GoogLeNet, SeveralCalls)
{
const int targetId = GetParam();
if(targetId == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("This test does not support FP16");
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt", false),
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
int targetId = GetParam();
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(targetId);
......@@ -143,6 +149,7 @@ TEST_P(Reproducibility_GoogLeNet, SeveralCalls)
normAssert(outs[0], ref, "", 1E-4, 1E-2);
}
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_GoogLeNet, availableDnnTargets());
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_GoogLeNet,
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
}} // namespace
......@@ -203,7 +203,8 @@ TEST_P(DNNTestOpenVINO, models)
std::map<std::string, cv::Mat> inputsMap;
std::map<std::string, cv::Mat> ieOutputsMap, cvOutputsMap;
// Single Myriad device cannot be shared across multiple processes.
resetMyriadDevice();
if (target == DNN_TARGET_MYRIAD)
resetMyriadDevice();
runIE(target, xmlPath, binPath, inputsMap, ieOutputsMap);
runCV(target, xmlPath, binPath, inputsMap, cvOutputsMap);
......@@ -245,27 +246,10 @@ static testing::internal::ParamGenerator<String> intelModels()
return ValuesIn(modelsNames);
}
static testing::internal::ParamGenerator<Target> dnnDLIETargets()
{
std::vector<Target> targets;
targets.push_back(DNN_TARGET_CPU);
#ifdef HAVE_OPENCL
if (cv::ocl::useOpenCL() && ocl::Device::getDefault().isIntel())
{
targets.push_back(DNN_TARGET_OPENCL);
targets.push_back(DNN_TARGET_OPENCL_FP16);
}
#endif
if (checkIETarget(DNN_TARGET_MYRIAD))
targets.push_back(DNN_TARGET_MYRIAD);
if (checkIETarget(DNN_TARGET_FPGA))
targets.push_back(DNN_TARGET_FPGA);
return testing::ValuesIn(targets);
}
INSTANTIATE_TEST_CASE_P(/**/, DNNTestOpenVINO, Combine(
dnnDLIETargets(), intelModels()
));
INSTANTIATE_TEST_CASE_P(/**/,
DNNTestOpenVINO,
Combine(testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)), intelModels())
);
}}
#endif // HAVE_INF_ENGINE
......@@ -157,8 +157,6 @@ TEST_P(setInput, normalization)
const int target = get<1>(get<3>(GetParam()));
const bool kSwapRB = true;
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD && !checkIETarget(DNN_TARGET_MYRIAD))
throw SkipTestException("Myriad is not available/disabled in OpenCV");
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16 && dtype != CV_32F)
throw SkipTestException("");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册