From bd705d5bdb11618b619fc7d312cebc9111a7c954 Mon Sep 17 00:00:00 2001 From: nihuini Date: Fri, 9 Feb 2018 18:24:36 +0800 Subject: [PATCH] inplace binaryop with scalar --- src/layer/binaryop.cpp | 70 ++++++++++++++++++++++++++++++++++-------- src/layer/binaryop.h | 4 +++ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/layer/binaryop.cpp b/src/layer/binaryop.cpp index 25db41b74..eb02be93e 100644 --- a/src/layer/binaryop.cpp +++ b/src/layer/binaryop.cpp @@ -30,6 +30,14 @@ BinaryOp::BinaryOp() int BinaryOp::load_param(const ParamDict& pd) { op_type = pd.get(0, 0); + with_scalar = pd.get(1, 0); + b = pd.get(2, 0.f); + + if (with_scalar != 0) + { + one_blob_only = true; + support_inplace = true; + } return 0; } @@ -113,9 +121,6 @@ static int binary_op(const Mat& a, const Mat& b, Mat& c) { outptr[i] = op(ptr[i], b0); } - - ptr += w; - outptr += w; } return 0; @@ -132,9 +137,6 @@ static int binary_op(const Mat& a, const Mat& b, Mat& c) { outptr[i] = op(ptr[i], b0); } - - ptr += w; - outptr += w; } return 0; @@ -241,9 +243,6 @@ static int binary_op(const Mat& a, const Mat& b, Mat& c) { outptr[i] = op(a0, ptr1[i]); } - - ptr1 += w1; - outptr += w1; } return 0; @@ -297,9 +296,6 @@ static int binary_op(const Mat& a, const Mat& b, Mat& c) { outptr[i] = op(a0, ptr1[i]); } - - ptr1 += w1; - outptr += w1; } return 0; @@ -356,6 +352,30 @@ static int binary_op(const Mat& a, const Mat& b, Mat& c) return 0; } +template +static int binary_op_scalar_inplace(Mat& a, float b) +{ + Op op; + + int w = a.w; + int h = a.h; + int channels = a.c; + int size = w * h; + + #pragma omp parallel for + for (int q=0; q struct binary_op_max : std::binary_function { T operator() (const T& x, const T& y) const { return std::max(x, y); } @@ -402,4 +422,30 @@ int BinaryOp::forward(const std::vector& bottom_blobs, std::vector& to return 0; } +int BinaryOp::forward_inplace(Mat& bottom_top_blob) const +{ + if (op_type == Operation_ADD) + return binary_op_scalar_inplace< std::plus >(bottom_top_blob, b); + + if (op_type == Operation_SUB) + return binary_op_scalar_inplace< std::minus >(bottom_top_blob, b); + + if (op_type == Operation_MUL) + return binary_op_scalar_inplace< std::multiplies >(bottom_top_blob, b); + + if (op_type == Operation_DIV) + return binary_op_scalar_inplace< std::divides >(bottom_top_blob, b); + + if (op_type == Operation_MAX) + return binary_op_scalar_inplace< binary_op_max >(bottom_top_blob, b); + + if (op_type == Operation_MIN) + return binary_op_scalar_inplace< binary_op_min >(bottom_top_blob, b); + + if (op_type == Operation_POW) + return binary_op_scalar_inplace< binary_op_pow >(bottom_top_blob, b); + + return 0; +} + } // namespace ncnn diff --git a/src/layer/binaryop.h b/src/layer/binaryop.h index e6cb1dbed..5af4e8368 100644 --- a/src/layer/binaryop.h +++ b/src/layer/binaryop.h @@ -28,6 +28,8 @@ public: virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs) const; + virtual int forward_inplace(Mat& bottom_top_blob) const; + enum { Operation_ADD = 0, Operation_SUB = 1, @@ -41,6 +43,8 @@ public: public: // param int op_type; + int with_scalar; + float b; }; } // namespace ncnn