Commit 0d117312 authored by Dmitry Kurtaev's avatar Dmitry Kurtaev

DNN_TARGET_FPGA using Intel's Inference Engine

parent 183bc5c2
...@@ -88,7 +88,9 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN ...@@ -88,7 +88,9 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
DNN_TARGET_CPU, DNN_TARGET_CPU,
DNN_TARGET_OPENCL, DNN_TARGET_OPENCL,
DNN_TARGET_OPENCL_FP16, DNN_TARGET_OPENCL_FP16,
DNN_TARGET_MYRIAD DNN_TARGET_MYRIAD,
//! FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
DNN_TARGET_FPGA
}; };
/** @brief This class provides all data needed to initialize layer. /** @brief This class provides all data needed to initialize layer.
...@@ -501,6 +503,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN ...@@ -501,6 +503,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
* | DNN_TARGET_OPENCL | + | + | + | * | DNN_TARGET_OPENCL | + | + | + |
* | DNN_TARGET_OPENCL_FP16 | + | + | | * | DNN_TARGET_OPENCL_FP16 | + | + | |
* | DNN_TARGET_MYRIAD | | + | | * | DNN_TARGET_MYRIAD | | + | |
* | DNN_TARGET_FPGA | | + | |
*/ */
CV_WRAP void setPreferableTarget(int targetId); CV_WRAP void setPreferableTarget(int targetId);
......
...@@ -42,7 +42,7 @@ public: ...@@ -42,7 +42,7 @@ public:
} }
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{ {
if (!checkMyriadTarget()) if (!checkIETarget(DNN_TARGET_MYRIAD))
{ {
throw SkipTestException("Myriad is not available/disabled in OpenCV"); throw SkipTestException("Myriad is not available/disabled in OpenCV");
} }
......
...@@ -1077,7 +1077,8 @@ struct Net::Impl ...@@ -1077,7 +1077,8 @@ struct Net::Impl
preferableTarget == DNN_TARGET_CPU || preferableTarget == DNN_TARGET_CPU ||
preferableTarget == DNN_TARGET_OPENCL || preferableTarget == DNN_TARGET_OPENCL ||
preferableTarget == DNN_TARGET_OPENCL_FP16 || preferableTarget == DNN_TARGET_OPENCL_FP16 ||
preferableTarget == DNN_TARGET_MYRIAD); preferableTarget == DNN_TARGET_MYRIAD ||
preferableTarget == DNN_TARGET_FPGA);
if (!netWasAllocated || this->blobsToKeep != blobsToKeep_) if (!netWasAllocated || this->blobsToKeep != blobsToKeep_)
{ {
if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget)) if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget))
...@@ -1512,7 +1513,9 @@ struct Net::Impl ...@@ -1512,7 +1513,9 @@ struct Net::Impl
ieNode->net = net; ieNode->net = net;
auto weightableLayer = std::dynamic_pointer_cast<InferenceEngine::WeightableLayer>(ieNode->layer); auto weightableLayer = std::dynamic_pointer_cast<InferenceEngine::WeightableLayer>(ieNode->layer);
if ((preferableTarget == DNN_TARGET_OPENCL_FP16 || preferableTarget == DNN_TARGET_MYRIAD) && !fused) if ((preferableTarget == DNN_TARGET_OPENCL_FP16 ||
preferableTarget == DNN_TARGET_MYRIAD ||
preferableTarget == DNN_TARGET_FPGA) && !fused)
{ {
ieNode->layer->precision = InferenceEngine::Precision::FP16; ieNode->layer->precision = InferenceEngine::Precision::FP16;
if (weightableLayer) if (weightableLayer)
......
...@@ -219,9 +219,14 @@ public: ...@@ -219,9 +219,14 @@ public:
virtual bool supportBackend(int backendId) CV_OVERRIDE virtual bool supportBackend(int backendId) CV_OVERRIDE
{ {
#ifdef HAVE_INF_ENGINE
if (backendId == DNN_BACKEND_INFERENCE_ENGINE) if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
return preferableTarget != DNN_TARGET_MYRIAD || dilation.width == dilation.height; {
return INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R4) ||
(preferableTarget != DNN_TARGET_MYRIAD || dilation.width == dilation.height);
}
else else
#endif
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE; return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE;
} }
......
...@@ -302,7 +302,8 @@ void InfEngineBackendNet::setTargetDevice(InferenceEngine::TargetDevice device) ...@@ -302,7 +302,8 @@ void InfEngineBackendNet::setTargetDevice(InferenceEngine::TargetDevice device)
{ {
if (device != InferenceEngine::TargetDevice::eCPU && if (device != InferenceEngine::TargetDevice::eCPU &&
device != InferenceEngine::TargetDevice::eGPU && device != InferenceEngine::TargetDevice::eGPU &&
device != InferenceEngine::TargetDevice::eMYRIAD) device != InferenceEngine::TargetDevice::eMYRIAD &&
device != InferenceEngine::TargetDevice::eFPGA)
CV_Error(Error::StsNotImplemented, ""); CV_Error(Error::StsNotImplemented, "");
targetDevice = device; targetDevice = device;
} }
...@@ -314,7 +315,8 @@ InferenceEngine::TargetDevice InfEngineBackendNet::getTargetDevice() noexcept ...@@ -314,7 +315,8 @@ InferenceEngine::TargetDevice InfEngineBackendNet::getTargetDevice() noexcept
InferenceEngine::TargetDevice InfEngineBackendNet::getTargetDevice() const noexcept InferenceEngine::TargetDevice InfEngineBackendNet::getTargetDevice() const noexcept
{ {
return targetDevice; return targetDevice == InferenceEngine::TargetDevice::eFPGA ?
InferenceEngine::TargetDevice::eHETERO : targetDevice;
} }
InferenceEngine::StatusCode InfEngineBackendNet::setBatchSize(const size_t) noexcept InferenceEngine::StatusCode InfEngineBackendNet::setBatchSize(const size_t) noexcept
...@@ -466,6 +468,11 @@ void InfEngineBackendNet::init(int targetId) ...@@ -466,6 +468,11 @@ void InfEngineBackendNet::init(int targetId)
setPrecision(InferenceEngine::Precision::FP16); setPrecision(InferenceEngine::Precision::FP16);
setTargetDevice(InferenceEngine::TargetDevice::eMYRIAD); break; setTargetDevice(InferenceEngine::TargetDevice::eMYRIAD); break;
} }
case DNN_TARGET_FPGA:
{
setPrecision(InferenceEngine::Precision::FP16);
setTargetDevice(InferenceEngine::TargetDevice::eFPGA); break;
}
default: default:
CV_Error(Error::StsError, format("Unknown target identifier: %d", targetId)); CV_Error(Error::StsError, format("Unknown target identifier: %d", targetId));
} }
...@@ -489,10 +496,15 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) ...@@ -489,10 +496,15 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net)
} }
else else
{ {
enginePtr = InferenceEngine::PluginDispatcher({""}).getSuitablePlugin(targetDevice); auto dispatcher = InferenceEngine::PluginDispatcher({""});
if (targetDevice == InferenceEngine::TargetDevice::eFPGA)
enginePtr = dispatcher.getPluginByDevice("HETERO:FPGA,CPU");
else
enginePtr = dispatcher.getSuitablePlugin(targetDevice);
sharedPlugins[targetDevice] = enginePtr; sharedPlugins[targetDevice] = enginePtr;
if (targetDevice == InferenceEngine::TargetDevice::eCPU) if (targetDevice == InferenceEngine::TargetDevice::eCPU ||
targetDevice == InferenceEngine::TargetDevice::eFPGA)
{ {
std::string suffixes[] = {"_avx2", "_sse4", ""}; std::string suffixes[] = {"_avx2", "_sse4", ""};
bool haveFeature[] = { bool haveFeature[] = {
......
...@@ -66,6 +66,7 @@ static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os) ...@@ -66,6 +66,7 @@ static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os)
case DNN_TARGET_OPENCL: *os << "OCL"; return; case DNN_TARGET_OPENCL: *os << "OCL"; return;
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return; case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return; case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
case DNN_TARGET_FPGA: *os << "FPGA"; return;
} // don't use "default:" to emit compiler warnings } // don't use "default:" to emit compiler warnings
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")"; *os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
} }
...@@ -188,7 +189,7 @@ static inline void normAssertDetections(cv::Mat ref, cv::Mat out, const char *co ...@@ -188,7 +189,7 @@ static inline void normAssertDetections(cv::Mat ref, cv::Mat out, const char *co
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff); testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
} }
static inline bool checkMyriadTarget() static inline bool checkIETarget(int target)
{ {
#ifndef HAVE_INF_ENGINE #ifndef HAVE_INF_ENGINE
return false; return false;
...@@ -197,7 +198,7 @@ static inline bool checkMyriadTarget() ...@@ -197,7 +198,7 @@ static inline bool checkMyriadTarget()
cv::dnn::LayerParams lp; cv::dnn::LayerParams lp;
net.addLayerToPrev("testLayer", "Identity", lp); net.addLayerToPrev("testLayer", "Identity", lp);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE); net.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(cv::dnn::DNN_TARGET_MYRIAD); net.setPreferableTarget(target);
static int inpDims[] = {1, 2, 3, 4}; static int inpDims[] = {1, 2, 3, 4};
net.setInput(cv::Mat(4, &inpDims[0], CV_32FC1, cv::Scalar(0))); net.setInput(cv::Mat(4, &inpDims[0], CV_32FC1, cv::Scalar(0)));
try try
...@@ -264,7 +265,7 @@ testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets ...@@ -264,7 +265,7 @@ testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL_FP16)); targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_OPENCL_FP16));
} }
#endif #endif
if (checkMyriadTarget()) if (checkIETarget(DNN_TARGET_MYRIAD))
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_MYRIAD)); targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, DNN_TARGET_MYRIAD));
} }
#endif #endif
...@@ -344,7 +345,7 @@ public: ...@@ -344,7 +345,7 @@ public:
} }
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{ {
if (!checkMyriadTarget()) if (!checkIETarget(DNN_TARGET_MYRIAD))
{ {
throw SkipTestException("Myriad is not available/disabled in OpenCV"); throw SkipTestException("Myriad is not available/disabled in OpenCV");
} }
......
...@@ -57,28 +57,29 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath ...@@ -57,28 +57,29 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
InferencePlugin plugin; InferencePlugin plugin;
ExecutableNetwork netExec; ExecutableNetwork netExec;
InferRequest infRequest; InferRequest infRequest;
TargetDevice targetDevice;
switch (target)
{
case DNN_TARGET_CPU:
targetDevice = TargetDevice::eCPU;
break;
case DNN_TARGET_OPENCL:
case DNN_TARGET_OPENCL_FP16:
targetDevice = TargetDevice::eGPU;
break;
case DNN_TARGET_MYRIAD:
targetDevice = TargetDevice::eMYRIAD;
break;
default:
CV_Error(Error::StsNotImplemented, "Unknown target");
};
try try
{ {
enginePtr = PluginDispatcher({""}).getSuitablePlugin(targetDevice); auto dispatcher = InferenceEngine::PluginDispatcher({""});
switch (target)
if (targetDevice == TargetDevice::eCPU) {
case DNN_TARGET_CPU:
enginePtr = dispatcher.getSuitablePlugin(TargetDevice::eCPU);
break;
case DNN_TARGET_OPENCL:
case DNN_TARGET_OPENCL_FP16:
enginePtr = dispatcher.getSuitablePlugin(TargetDevice::eGPU);
break;
case DNN_TARGET_MYRIAD:
enginePtr = dispatcher.getSuitablePlugin(TargetDevice::eMYRIAD);
break;
case DNN_TARGET_FPGA:
enginePtr = dispatcher.getPluginByDevice("HETERO:FPGA,CPU");
break;
default:
CV_Error(Error::StsNotImplemented, "Unknown target");
};
if (target == DNN_TARGET_CPU || target == DNN_TARGET_FPGA)
{ {
std::string suffixes[] = {"_avx2", "_sse4", ""}; std::string suffixes[] = {"_avx2", "_sse4", ""};
bool haveFeature[] = { bool haveFeature[] = {
...@@ -255,8 +256,10 @@ static testing::internal::ParamGenerator<Target> dnnDLIETargets() ...@@ -255,8 +256,10 @@ static testing::internal::ParamGenerator<Target> dnnDLIETargets()
targets.push_back(DNN_TARGET_OPENCL_FP16); targets.push_back(DNN_TARGET_OPENCL_FP16);
} }
#endif #endif
if (checkMyriadTarget()) if (checkIETarget(DNN_TARGET_MYRIAD))
targets.push_back(DNN_TARGET_MYRIAD); targets.push_back(DNN_TARGET_MYRIAD);
if (checkIETarget(DNN_TARGET_FPGA))
targets.push_back(DNN_TARGET_FPGA);
return testing::ValuesIn(targets); return testing::ValuesIn(targets);
} }
......
...@@ -351,7 +351,7 @@ TEST_P(Test_Caffe_layers, Conv_Elu) ...@@ -351,7 +351,7 @@ TEST_P(Test_Caffe_layers, Conv_Elu)
{ {
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{ {
if (!checkMyriadTarget()) if (!checkIETarget(DNN_TARGET_MYRIAD))
throw SkipTestException("Myriad is not available/disabled in OpenCV"); throw SkipTestException("Myriad is not available/disabled in OpenCV");
} }
......
...@@ -157,7 +157,7 @@ TEST_P(setInput, normalization) ...@@ -157,7 +157,7 @@ TEST_P(setInput, normalization)
const int target = get<1>(get<3>(GetParam())); const int target = get<1>(get<3>(GetParam()));
const bool kSwapRB = true; const bool kSwapRB = true;
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD && !checkMyriadTarget()) if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD && !checkIETarget(DNN_TARGET_MYRIAD))
throw SkipTestException("Myriad is not available/disabled in OpenCV"); throw SkipTestException("Myriad is not available/disabled in OpenCV");
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16 && dtype != CV_32F) if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16 && dtype != CV_32F)
throw SkipTestException(""); throw SkipTestException("");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment