From cdcf7e62f37f8476eb209439fe94b51e8a93846c Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 9 Oct 2020 16:33:48 +0000 Subject: [PATCH] dnn(opencl): bypass unsupported fusion cases 2 --- modules/dnn/src/dnn.cpp | 59 +++++++++++++++----- modules/dnn/src/layers/convolution_layer.cpp | 2 +- modules/dnn/test/test_layers.cpp | 8 +-- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 9ee688f497..c789638793 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -2413,14 +2413,42 @@ struct Net::Impl : public detail::NetImplBase } // fuse convolution layer followed by eltwise + relu - if ( IS_DNN_OPENCL_TARGET(preferableTarget) && ld.layerInstance->type == "Convolution" ) + while (nextData && IS_DNN_OPENCL_TARGET(preferableTarget) && ld.layerInstance->type == "Convolution") // semantic of 'if' { - Ptr nextEltwiseLayer; - if( nextData ) - nextEltwiseLayer = nextData->layerInstance.dynamicCast(); + Ptr nextEltwiseLayer = nextData->layerInstance.dynamicCast(); + if (nextEltwiseLayer.empty()) + break; + + if (pinsToKeep.count(lpNext) != 0) + break; + if (nextData->inputBlobsId.size() != 2) + break; + + if (!nextData->params.has("operation") || nextData->params.get("operation").toLowerCase() == "sum") + { + if (nextData->params.has("coeff")) + { + DictValue paramCoeff = nextData->params.get("coeff"); + int n = paramCoeff.size(); + bool isCoeffOneOne = (n == 2); + for (int i = 0; isCoeffOneOne && i < n; i++) + { + float c = paramCoeff.get(i); + isCoeffOneOne &= (c == 1.0f); + } + if (!isCoeffOneOne) + { + CV_LOG_DEBUG(NULL, "DNN/OpenCL: fusion of 'Sum' without coeffs (or {1.0, 1.0}) is supported only"); + break; + } + } + } + else + { + CV_LOG_DEBUG(NULL, "DNN/OpenCL: fusion with eltwise operation is not supported: " << nextData->params.get("operation")); + break; + } - if( !nextEltwiseLayer.empty() && pinsToKeep.count(lpNext) == 0 && - nextData && nextData->inputBlobsId.size() == 2 ) { LayerData *eltwiseData = nextData; @@ -2517,6 +2545,8 @@ struct Net::Impl : public detail::NetImplBase } } } + + break; } } @@ -2698,11 +2728,11 @@ struct Net::Impl : public detail::NetImplBase Ptr layer = ld.layerInstance; - TickMeter tm; - tm.start(); - if( !ld.skip ) { + TickMeter tm; + tm.start(); + std::map >::iterator it = ld.backendNodes.find(preferableBackend); if (preferableBackend == DNN_BACKEND_OPENCV || it == ld.backendNodes.end() || it->second.empty()) { @@ -2881,12 +2911,15 @@ struct Net::Impl : public detail::NetImplBase CV_Error(Error::StsNotImplemented, "Unknown backend identifier"); } } + + tm.stop(); + int64 t = tm.getTimeTicks(); + layersTimings[ld.id] = (t > 0) ? t : t + 1; // zero for skipped layers only } else - tm.reset(); - - tm.stop(); - layersTimings[ld.id] = tm.getTimeTicks(); + { + layersTimings[ld.id] = 0; + } ld.flag = 1; } diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 206ce72fa0..473c07b755 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -376,7 +376,7 @@ public: if (activ_power->scale != 1.0f) // not supported well by implementation, #17964 { // FIXIT no way to check number of blobs (like, eltwise input) - CV_LOG_INFO(NULL, "DNN/OpenCL: can't configure Power activation (scale != 1.0f)"); + CV_LOG_DEBUG(NULL, "DNN/OpenCL: can't configure Power activation (scale != 1.0f)"); activ.release(); newActiv = false; return false; diff --git a/modules/dnn/test/test_layers.cpp b/modules/dnn/test/test_layers.cpp index 3872f562ef..327f3e9abd 100644 --- a/modules/dnn/test/test_layers.cpp +++ b/modules/dnn/test/test_layers.cpp @@ -2341,10 +2341,6 @@ TEST_P(ConvolutionEltwiseActivationFusion, Accuracy) Backend backendId = get<0>(get<4>(GetParam())); Target targetId = get<1>(get<4>(GetParam())); - // bug: https://github.com/opencv/opencv/issues/17945 - if ((eltwiseOp != "sum" || weightedEltwise) && backendId == DNN_BACKEND_OPENCV && (targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16)) - applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL); - Net net; int convId = net.addLayer(convParams.name, convParams.type, convParams); int eltwiseId = net.addLayer(eltwiseParams.name, eltwiseParams.type, eltwiseParams); @@ -2361,7 +2357,9 @@ TEST_P(ConvolutionEltwiseActivationFusion, Accuracy) expectedFusedLayers.push_back(activId); // activation is fused with eltwise layer else if (targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16) { - if (actType == "ReLU" || actType == "ChannelsPReLU" /*|| actType == "Power"*/) + if (eltwiseOp == "sum" && !weightedEltwise && + (actType == "ReLU" || actType == "ChannelsPReLU" /*|| actType == "Power"*/) + ) { expectedFusedLayers.push_back(eltwiseId); expectedFusedLayers.push_back(activId); -- 2.34.1