diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 080de30d21..011631f54e 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -409,8 +409,44 @@ struct LayerData struct DataLayer : public Layer { void finalize(const std::vector&, std::vector&) CV_OVERRIDE {} - void forward(std::vector&, std::vector&, std::vector &) CV_OVERRIDE {} - void forward(InputArrayOfArrays inputs, OutputArrayOfArrays outputs, OutputArrayOfArrays internals) CV_OVERRIDE {} + + void forward(InputArrayOfArrays inputs, OutputArrayOfArrays outputs, OutputArrayOfArrays internals) CV_OVERRIDE + { + CV_TRACE_FUNCTION(); + CV_TRACE_ARG_VALUE(name, "name", name.c_str()); + + CV_OCL_RUN(IS_DNN_OPENCL_TARGET(preferableTarget), + forward_ocl(inputs, outputs, internals)); + + Layer::forward_fallback(inputs, outputs, internals); + } + + void forward(std::vector&, std::vector& outputs, std::vector &) CV_OVERRIDE + { + for (int i = 0; i < inputsData.size(); ++i) + { + if (inputsData[i].type() == CV_32F && outputs[i].type() == CV_16S) + { + convertFp16(inputsData[i], outputs[i]); + } + } + } + +#ifdef HAVE_OPENCL + bool forward_ocl(InputArrayOfArrays, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) + { + if (outputs_.depth() == CV_16S) + { + std::vector outputs; + outputs_.getUMatVector(outputs); + for (int i = 0; i < inputsData.size(); ++i) + { + convertFp16(inputsData[i], outputs[i]); + } + } + return true; + } +#endif int outputNameToIndex(const String& tgtName) CV_OVERRIDE { @@ -434,6 +470,7 @@ struct DataLayer : public Layer } std::vector outNames; + std::vector inputsData; }; struct BlobManager @@ -848,9 +885,6 @@ struct Net::Impl poolingLayer->computeMaxIdx = true; } } - it = layers.find(0); - CV_Assert(it != layers.end()); - it->second.skip = true; layersTimings.clear(); } @@ -1355,15 +1389,27 @@ struct Net::Impl allocateLayer(*i, layersShapes); //bind inputs - ld.inputBlobs.resize(ninputs); - ld.inputBlobsWrappers.resize(ninputs); - for (size_t i = 0; i < ninputs; i++) + if (ld.id == 0) // DataLayer + { + ninputs = netInputLayer->inputsData.size(); + ld.inputBlobsWrappers.resize(ninputs); + for (size_t i = 0; i < ninputs; i++) + { + ld.inputBlobsWrappers[i] = wrap(netInputLayer->inputsData[i]); + } + } + else { - LayerPin from = ld.inputBlobsId[i]; - CV_Assert(from.valid()); - CV_DbgAssert(layers.count(from.lid) && (int)layers[from.lid].outputBlobs.size() > from.oid); - ld.inputBlobs[i] = &layers[from.lid].outputBlobs[from.oid]; - ld.inputBlobsWrappers[i] = layers[from.lid].outputBlobsWrappers[from.oid]; + ld.inputBlobs.resize(ninputs); + ld.inputBlobsWrappers.resize(ninputs); + for (size_t i = 0; i < ninputs; i++) + { + LayerPin from = ld.inputBlobsId[i]; + CV_Assert(from.valid()); + CV_DbgAssert(layers.count(from.lid) && (int)layers[from.lid].outputBlobs.size() > from.oid); + ld.inputBlobs[i] = &layers[from.lid].outputBlobs[from.oid]; + ld.inputBlobsWrappers[i] = layers[from.lid].outputBlobsWrappers[from.oid]; + } } LayersShapesMap::const_iterator layerShapesIt = layersShapes.find(lid); @@ -1731,15 +1777,14 @@ struct Net::Impl ShapesVec inputShapes; for(int i = 0; i < layers[0].outputBlobs.size(); i++) { - CV_Assert(layers[0].outputBlobs[i].total()); - if (layers[0].outputBlobs[i].depth() == CV_32F && - preferableBackend == DNN_BACKEND_OPENCV && + Mat& inp = layers[0].outputBlobs[i]; + CV_Assert(inp.total()); + if (preferableBackend == DNN_BACKEND_OPENCV && preferableTarget == DNN_TARGET_OPENCL_FP16) { - Mat mat = layers[0].outputBlobs[i].clone(); - convertFp16(mat, layers[0].outputBlobs[i]); + layers[0].outputBlobs[i].create(inp.dims, inp.size, CV_16S); } - inputShapes.push_back(shape(layers[0].outputBlobs[i])); + inputShapes.push_back(shape(inp)); } LayersShapesMap layersShapes; getLayersShapes(inputShapes, layersShapes); @@ -2271,28 +2316,22 @@ void Net::setInput(InputArray blob, const String& name) CV_Error(Error::StsObjectNotFound, "Requested blob \"" + name + "\" not found"); LayerData &ld = impl->layers[pin.lid]; - ld.outputBlobs.resize( std::max(pin.oid+1, (int)ld.requiredOutputs.size()) ); - ld.outputBlobsWrappers.resize(ld.outputBlobs.size()); - MatShape prevShape = shape(ld.outputBlobs[pin.oid]); - Mat blob_; - if (impl->preferableBackend == DNN_BACKEND_OPENCV && - impl->preferableTarget == DNN_TARGET_OPENCL_FP16) - { - Mat blob_mat = blob.getMat(); - convertFp16(blob_mat, blob_); - } - else - { - blob_ = blob.getMat(); - } + const int numInputs = std::max(pin.oid+1, (int)ld.requiredOutputs.size()); + ld.outputBlobs.resize(numInputs); + ld.outputBlobsWrappers.resize(numInputs); + impl->netInputLayer->inputsData.resize(numInputs); + + MatShape prevShape = shape(impl->netInputLayer->inputsData[pin.oid]); + Mat blob_ = blob.getMat(); bool oldShape = prevShape == shape(blob_); if (oldShape) { - blob_.copyTo(ld.outputBlobs[pin.oid]); + blob_.copyTo(impl->netInputLayer->inputsData[pin.oid]); } else { ld.outputBlobs[pin.oid] = blob_.clone(); + impl->netInputLayer->inputsData[pin.oid] = ld.outputBlobs[pin.oid]; } if (!ld.outputBlobsWrappers[pin.oid].empty())