From fd4491fcb10aaf42a41b6f1c7df946cdefb29aa5 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Sat, 18 Jul 2026 02:28:41 +0300 Subject: [PATCH] dnn: map FP16 input types to FP32 in getFLOPS for the new graph engine The new graph engine has no FP16 execution path yet and runs FP32 on CPU regardless of the requested target. When an OpenCL FP16 target is requested, callers may pass CV_16F input types to Net::getFLOPS(), which then flow through tryInferShapes() -> Layer::getTypes() and get rejected (CV_16F is only allowed when preferableTarget == DNN_TARGET_OPENCL_FP16, which the new engine never sets). Normalize FP16 input types to FP32 in the mainGraph path of getFLOPS via a small filterFP16InputTypes() helper. This fixes the OCL_FP16 parameterization of the DNNTestNetwork perf tests (e.g. YuNet_320/640/1280) which crashed in getFLOPS. Co-Authored-By: Claude Opus 4.8 (1M context) --- modules/dnn/src/net_impl.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/modules/dnn/src/net_impl.cpp b/modules/dnn/src/net_impl.cpp index 92445d657e..3cc13e497e 100644 --- a/modules/dnn/src/net_impl.cpp +++ b/modules/dnn/src/net_impl.cpp @@ -2466,6 +2466,21 @@ std::vector Net::Impl::getUnconnectedOutLayersNames() /*const*/ } +// The new graph engine has no FP16 execution path yet: it runs FP32 on CPU regardless +// of the requested (e.g. OpenCL FP16) target. Map FP16 input types to FP32 so that +// shape/FLOPS inference through Layer::getTypes() does not reject them. +static std::vector filterFP16InputTypes(const std::vector& types) +{ + std::vector result = types; + for (MatType& t : result) + { + if (t == CV_16F) + t = CV_32F; + } + return result; +} + + int64 Net::Impl::getFLOPSGraph(const Ptr& graph, const std::vector& shapeCache, const std::vector& typeCache) const @@ -2524,10 +2539,14 @@ int64 Net::Impl::getFLOPS(const std::vector& netInputShapes, const std::vector& netInputTypes) /*const*/ { if (mainGraph) { + // The new graph engine executes in FP32 on CPU regardless of the requested + // target, so FP16 input types (e.g. coming from an OpenCL FP16 target) would be + // rejected by Layer::getTypes(). Normalize them to FP32 for shape/FLOPS inference. + std::vector inputTypes = filterFP16InputTypes(netInputTypes); LayerShapes shapes; std::vector shapeCache; std::vector typeCache; - tryInferShapes(netInputShapes, netInputTypes, shapes, shapeCache, typeCache); + tryInferShapes(netInputShapes, inputTypes, shapes, shapeCache, typeCache); return getFLOPSGraph(mainGraph, shapeCache, typeCache); } @@ -2553,10 +2572,11 @@ int64 Net::Impl::getFLOPS( const std::vector& netInputTypes) /*const*/ { if (mainGraph) { + std::vector inputTypes = filterFP16InputTypes(netInputTypes); LayerShapes shapes; std::vector shapeCache; std::vector typeCache; - tryInferShapes(netInputShapes, netInputTypes, shapes, shapeCache, typeCache); + tryInferShapes(netInputShapes, inputTypes, shapes, shapeCache, typeCache); CV_Assert(0 <= layerId && layerId < (int)totalLayers); int localIdx = layerId;