diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 979802f98..ad0eb8504 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,6 +119,8 @@ ncnn_add_layer(Threshold) ncnn_add_layer(Tile OFF) ncnn_add_layer(RNN OFF) ncnn_add_layer(LSTM OFF) +ncnn_add_layer(BinaryOp) +ncnn_add_layer(UnaryOp) add_library(ncnn STATIC ${ncnn_SRCS}) diff --git a/src/layer.h b/src/layer.h index 13bb2e552..ca3e1298d 100644 --- a/src/layer.h +++ b/src/layer.h @@ -130,6 +130,8 @@ enum Tile = 37, RNN = 38, LSTM = 39, + BinaryOp = 40, + UnaryOp = 41, CustomBit = (1<<8), }; diff --git a/src/layer/binaryop.cpp b/src/layer/binaryop.cpp new file mode 100644 index 000000000..36f006fb2 --- /dev/null +++ b/src/layer/binaryop.cpp @@ -0,0 +1,182 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "binaryop.h" +#include + +namespace ncnn { + +DEFINE_LAYER_CREATOR(BinaryOp) + +BinaryOp::BinaryOp() +{ + one_blob_only = false; + support_inplace = false; +} + +#if NCNN_STDIO +#if NCNN_STRING +int BinaryOp::load_param(FILE* paramfp) +{ + int nscan = fscanf(paramfp, "%d", &op_type); + if (nscan != 1) + { + fprintf(stderr, "BinaryOp load_param failed %d\n", nscan); + return -1; + } + + return 0; +} +#endif // NCNN_STRING +int BinaryOp::load_param_bin(FILE* paramfp) +{ + fread(&op_type, sizeof(int), 1, paramfp); + + return 0; +} +#endif // NCNN_STDIO + +int BinaryOp::load_param(const unsigned char*& mem) +{ + op_type = *(int*)(mem); + mem += 4; + + return 0; +} + +int BinaryOp::forward(const std::vector& bottom_blobs, std::vector& top_blobs) const +{ + const Mat& bottom_blob = bottom_blobs[0]; + const Mat& bottom_blob1 = bottom_blobs[1]; + + int w = bottom_blob.w; + int h = bottom_blob.h; + int channels = bottom_blob.c; + int size = w * h; + + Mat& top_blob = top_blobs[0]; + top_blob.create(w, h, channels); + if (top_blob.empty()) + return -100; + + if (op_type == Operation_ADD) + { + #pragma omp parallel for + for (int q=0; q& bottom_blobs, std::vector& top_blobs) const; + + enum { + Operation_ADD = 0, + Operation_SUB = 1, + Operation_MUL = 2, + Operation_DIV = 3, + Operation_MAX = 4, + Operation_MIN = 5, + Operation_POW = 6 + }; + +public: + // param + int op_type; +}; + +} // namespace ncnn + +#endif // LAYER_BINARYOP_H diff --git a/src/layer/unaryop.cpp b/src/layer/unaryop.cpp new file mode 100644 index 000000000..4fbcca737 --- /dev/null +++ b/src/layer/unaryop.cpp @@ -0,0 +1,489 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "unaryop.h" +#include + +namespace ncnn { + +DEFINE_LAYER_CREATOR(UnaryOp) + +UnaryOp::UnaryOp() +{ + one_blob_only = true; + support_inplace = true; +} + +#if NCNN_STDIO +#if NCNN_STRING +int UnaryOp::load_param(FILE* paramfp) +{ + int nscan = fscanf(paramfp, "%d", &op_type); + if (nscan != 1) + { + fprintf(stderr, "UnaryOp load_param failed %d\n", nscan); + return -1; + } + + return 0; +} +#endif // NCNN_STRING +int UnaryOp::load_param_bin(FILE* paramfp) +{ + fread(&op_type, sizeof(int), 1, paramfp); + + return 0; +} +#endif // NCNN_STDIO + +int UnaryOp::load_param(const unsigned char*& mem) +{ + op_type = *(int*)(mem); + mem += 4; + + return 0; +} + +int UnaryOp::forward(const Mat& bottom_blob, Mat& top_blob) const +{ + int w = bottom_blob.w; + int h = bottom_blob.h; + int channels = bottom_blob.c; + int size = w * h; + + top_blob.create(w, h, channels); + if (top_blob.empty()) + return -100; + + if (op_type == Operation_ABS) + { + #pragma omp parallel for + for (int q=0; q