mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
ocl support for Deconvolution layer
Signed-off-by: Li Peng <peng.li@intel.com>
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#include "opencv2/core/hal/hal.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include <iostream>
|
||||
#include "opencl_kernels_dnn.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
using namespace cv::dnn::ocl4dnn;
|
||||
@@ -1051,6 +1052,8 @@ class DeConvolutionLayerImpl : public BaseConvolutionLayerImpl
|
||||
{
|
||||
public:
|
||||
Mat weightsMat, biasesMat;
|
||||
UMat umat_weights;
|
||||
UMat umat_biases;
|
||||
|
||||
MatShape computeColRowShape(const MatShape &inpShape, const MatShape &outShape) const
|
||||
{
|
||||
@@ -1341,11 +1344,107 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_)
|
||||
{
|
||||
std::vector<UMat> inputs;
|
||||
std::vector<UMat> outputs;
|
||||
std::vector<UMat> internals;
|
||||
|
||||
inputs_.getUMatVector(inputs);
|
||||
outputs_.getUMatVector(outputs);
|
||||
internals_.getUMatVector(internals);
|
||||
|
||||
int outCn = numOutput;
|
||||
int inpCn = inputs[0].size[1];
|
||||
|
||||
if (is1x1())
|
||||
return false;
|
||||
|
||||
if (umat_weights.empty())
|
||||
{
|
||||
transpose(blobs[0].reshape(1, inpCn), umat_weights);
|
||||
umat_biases = hasBias() ? blobs[1].reshape(1, outCn).getUMat(ACCESS_READ) :
|
||||
UMat::zeros(outCn, 1, CV_32F);
|
||||
}
|
||||
|
||||
String buildopt = format("-DT=%s ", ocl::typeToStr(inputs[0].type()));
|
||||
buildopt += format("-DPAD_H=%d -DPAD_W=%d -DKERNEL_H=%d -DKERNEL_W=%d -DSTRIDE_H=%d -DSTRIDE_W=%d ",
|
||||
pad.height, pad.width, kernel.height, kernel.width, stride.height, stride.width);
|
||||
|
||||
for (size_t ii = 0; ii < outputs.size(); ii++)
|
||||
{
|
||||
int ngroups = outCn / blobs[0].size[1];
|
||||
int inpGroupCn = inpCn / ngroups;
|
||||
int outGroupCn = blobs[0].size[1];
|
||||
const UMat& inp = inputs[ii];
|
||||
UMat& out = outputs[ii];
|
||||
int numImg = inp.size[0];
|
||||
int inpH = inp.size[2], inpW = inp.size[3];
|
||||
int outH = out.size[2], outW = out.size[3];
|
||||
|
||||
MatShape inpshape = shape(numImg*inpCn, inpH*inpW);
|
||||
MatShape outshape = shape(numImg*outCn, outH*outW);
|
||||
UMat convBlob = inputs[ii].reshape(1, inpshape.size(), &inpshape[0]);
|
||||
UMat decnBlob = out.reshape(1, outshape.size(), &outshape[0]);
|
||||
int rows = internals[0].rows / ngroups;
|
||||
|
||||
for (int n = 0; n < numImg; n++)
|
||||
{
|
||||
for (int g = 0; g < ngroups; g++)
|
||||
{
|
||||
UMat colMat = internals[0].rowRange(_Range(g * rows, rows));
|
||||
UMat convMat = convBlob.rowRange(_Range((g + n * ngroups) * inpGroupCn, inpGroupCn));
|
||||
UMat wghtMat = umat_weights.colRange(_Range(g * inpGroupCn, inpGroupCn));
|
||||
gemm(wghtMat, convMat, 1, noArray(), 0, colMat, 0);
|
||||
}
|
||||
|
||||
for (int g = 0; g < ngroups; g++)
|
||||
{
|
||||
int total = outGroupCn * decnBlob.cols;
|
||||
int index = 0;
|
||||
int height_col = (outH + 2 * pad.height - kernel.height) / stride.height + 1;
|
||||
int width_col = (outW + 2 * pad.width - kernel.width) / stride.width + 1;
|
||||
int coeff_h = (1 - stride.height * kernel.width * height_col) * width_col;
|
||||
int coeff_w = (1 - stride.width * height_col * width_col);
|
||||
|
||||
ocl::Kernel k("col2im", ocl::dnn::col2im_oclsrc, buildopt);
|
||||
k.set(index++, total);
|
||||
k.set(index++, ocl::KernelArg::PtrReadOnly(internals[0]));
|
||||
k.set(index++, (int)(g * rows * internals[0].cols));
|
||||
k.set(index++, outGroupCn);
|
||||
k.set(index++, outH);
|
||||
k.set(index++, outW);
|
||||
k.set(index++, height_col);
|
||||
k.set(index++, width_col);
|
||||
k.set(index++, coeff_h);
|
||||
k.set(index++, coeff_w);
|
||||
k.set(index++, ocl::KernelArg::PtrReadOnly(umat_biases));
|
||||
k.set(index++, (int)(g * outGroupCn * umat_biases.cols));
|
||||
k.set(index++, ocl::KernelArg::PtrWriteOnly(decnBlob));
|
||||
k.set(index++, (int)((g + n * ngroups) * outGroupCn * decnBlob.cols));
|
||||
|
||||
size_t global[] = { (size_t)total };
|
||||
bool ret = k.run(1, global, NULL, false);
|
||||
if (!ret)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
|
||||
|
||||
CV_OCL_RUN((preferableTarget == DNN_TARGET_OPENCL) &&
|
||||
OCL_PERFORMANCE_CHECK(ocl::Device::getDefault().isIntel()),
|
||||
forward_ocl(inputs_arr, outputs_arr, internals_arr))
|
||||
|
||||
Layer::forward_fallback(inputs_arr, outputs_arr, internals_arr);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user