• Vadim Pisarevsky's avatar
    refactored DNN (#1102) · 3f5b4655
    Vadim Pisarevsky authored
    * the first commit in the merged dnn: convert some public API from Blob's to Mat's
    
    * temporarily or permantently removed OpenCL optimizations, which are not always stable nor usually very efficient; we'll likely use Halide instead
    
    * got rid of Blob and BlobShape completely; use cv::Mat and std::vector<int> instead
    
    * fixed a few compile errors
    
    * got rid of separate .hpp files with layer declarations; instead, put everything into the respective .cpp files
    
    * normalized all the layers' constructors; we concentrate on loading deep networks layers from files instead of constructing them from scratch, so we retained only SomeLayer::SomeLayer(const LayerParams& params); constructors
    
    * fixed sample compilation
    
    * suppress doxygen warnings
    
    * trying to fix python bindings generation for DNN module
    
    * temporarily disable python bindings while we refactor the module
    
    * fix win32/win64 compile errors; remove trailing whitespaces
    
    * fix win32/win64 compile errors; remove trailing whitespaces
    3f5b4655
shift_layer.cpp 3.09 KB
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.

/*
Implementation of shift layer, which adds up const values to blob.
*/

#include "../precomp.hpp"
#include "op_blas.hpp"

namespace cv
{
namespace dnn
{

class ShiftLayerImpl : public ShiftLayer
{
public:
    ShiftLayerImpl(const LayerParams &params)
    {
        setParamsFrom(params);
        CV_Assert(blobs.size() == 1);

#ifdef HAVE_LAPACK
        {
            if (getBlasThreads() != cv::getThreadNum())
            {
                setBlasThreads(cv::getThreadNum());
            }
        }
#endif
    }

    virtual void allocate(const std::vector<Mat*> &inputs, std::vector<Mat> &outputs)
    {
        CV_Assert(inputs.size() > 0);
        CV_Assert(blobs.size() > 0);
        const Mat &inpBlob = *inputs[0];
        CV_Assert(inpBlob.dims == 4 && inpBlob.type() == CV_32F);
        const Mat &biasBlob = blobs[0];
        outputs.resize(inputs.size());

        if(inpBlob.dims == biasBlob.dims)
        {
            for (size_t i = 0; i < inputs.size(); i++)
            {
                CV_Assert(inputs[i]->type() == inpBlob.type());
                CV_Assert(inputs[i]->dims == inpBlob.dims);

                outputs[i] = *inputs[i];
            }
        }
        else
        {
            CV_Assert(biasBlob.total() == (size_t)inpBlob.size[1]);

            for (size_t i = 0; i < inputs.size(); i++)
            {
                CV_Assert(inputs[i]->type() == inpBlob.type());
                CV_Assert(inputs[i]->dims == 4 && inputs[i]->size[1] == inpBlob.size[1]);

                outputs[i] = *inputs[i];
            }

            biasOnesMat = Mat::ones(1, inpBlob.size[2] * inpBlob.size[3], inpBlob.type());
        }
    }

    virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs)
    {
        CV_Assert(inputs.size() > 0);
        CV_Assert(blobs.size() > 0);

        if(inputs[0]->dims == blobs[0].dims)
        {
            for (size_t ii = 0; ii < outputs.size(); ii++)
            {
                Mat &inpBlob = *inputs[ii];
                Mat &outBlob = outputs[ii];

                outBlob = inpBlob + blobs[0];
            }
        }
        else
        {
            for (size_t ii = 0; ii < outputs.size(); ii++)
            {
                Mat &inpBlob = *inputs[ii];
                Mat &outBlob = outputs[ii];

                inpBlob.copyTo(outBlob);

                for (int n = 0; n < inpBlob.size[0]; n++)
                {
                    Mat dstMat(inpBlob.size[1], inpBlob.size[2] * inpBlob.size[3],
                               outBlob.type(), outBlob.ptr(n));
                    dnn::gemm(blobs[0], biasOnesMat, 1, dstMat, 1); //TODO: gemv
                }
            }
        }
    }

    Mat biasOnesMat;
};

Ptr<ShiftLayer> ShiftLayer::create(const LayerParams& params)
{
    return Ptr<ShiftLayer>(new ShiftLayerImpl(params));
}

}
}