From 02e04b44411a851a86217815e7d740c634d8324f Mon Sep 17 00:00:00 2001 From: xzl Date: Tue, 18 Jul 2017 22:04:53 +0800 Subject: [PATCH] fuse the conv and depthwise conv together --- paddle/function/ConvOpTest.cpp | 281 ++++++++++++--------------------- 1 file changed, 104 insertions(+), 177 deletions(-) diff --git a/paddle/function/ConvOpTest.cpp b/paddle/function/ConvOpTest.cpp index 61f0c18bed..27609fbbd4 100644 --- a/paddle/function/ConvOpTest.cpp +++ b/paddle/function/ConvOpTest.cpp @@ -25,11 +25,17 @@ enum TestType { kBackwardFilterTest = 2, }; +enum LayerType { + convolutionType = 0, + depthwiseConvolutionType = 1, +}; + template class ConvolutionTest { public: ConvolutionTest(const std::string& conv1, const std::string& conv2, + LayerType layerType, TestType type, std::string algo = "auto") { for (size_t batchSize : {1, 32}) { @@ -37,7 +43,17 @@ public: for (size_t filterSize : {1, 3, 5}) { for (size_t inputChannels : {3, 64}) { for (size_t outputChannels : {3, 64, 128}) { - if (inputChannels < outputChannels) break; + if (inputChannels > outputChannels) break; + if (layerType == depthwiseConvolutionType && + outputChannels % inputChannels != 0) + break; + + size_t groups = 1; + + if (layerType == depthwiseConvolutionType) { + groups = inputChannels; + } + for (size_t stride : {1, 2}) { for (size_t padding : {0, 1}) { if (padding >= filterSize) break; @@ -62,13 +78,24 @@ public: FuncConfig() .set("paddings", paddings) .set("strides", strides) - .set("groups", (size_t)1) + .set("groups", groups) .set("algo", algo)); TensorShape input{ batchSize, inputChannels, inputSize, inputSize}; - TensorShape filter{ - outputChannels, inputChannels, filterSize, filterSize}; + + TensorShape filter; + if (layerType == depthwiseConvolutionType) + filter = TensorShape({groups, + outputChannels / groups, + (size_t)1, + filterSize, + filterSize}); + else + filter = TensorShape({outputChannels, + inputChannels, + filterSize, + filterSize}); TensorShape output{ batchSize, outputChannels, outputSize, outputSize}; @@ -105,6 +132,7 @@ class ConvolutionTest2 { public: ConvolutionTest2(const std::string& conv1, const std::string& conv2, + LayerType layerType, TestType type, std::string algo = "auto") { for (size_t batchSize : {16}) { @@ -113,7 +141,16 @@ public: for (size_t filterHeight : {1, 5}) { for (size_t filterWidth : {3, 7}) { for (size_t inputChannels : {7}) { - for (size_t outputChannels : {32}) { + for (size_t outputChannels : {7, 32}) { + if (layerType == depthwiseConvolutionType && + outputChannels % inputChannels != 0) + break; + + size_t groups = 1; + + if (layerType == depthwiseConvolutionType) { + groups = inputChannels; + } size_t stride = 1; size_t padding = 0; size_t outputHeight = @@ -141,13 +178,24 @@ public: FuncConfig() .set("paddings", paddings) .set("strides", strides) - .set("groups", (size_t)1) + .set("groups", groups) .set("algo", algo)); TensorShape input{ batchSize, inputChannels, inputHeight, inputWidth}; - TensorShape filter{ - outputChannels, inputChannels, filterHeight, filterWidth}; + + TensorShape filter; + if (layerType == depthwiseConvolutionType) + filter = TensorShape({groups, + outputChannels / groups, + (size_t)1, + filterHeight, + filterWidth}); + else + filter = TensorShape({outputChannels, + inputChannels, + filterHeight, + filterWidth}); TensorShape output{ batchSize, outputChannels, outputHeight, outputWidth}; @@ -177,183 +225,46 @@ public: } }; -template -class DepthwiseConvolutionTest { -public: - DepthwiseConvolutionTest(const std::string& conv1, - const std::string& conv2, - TestType type, - std::string algo = "auto") { - for (size_t batchSize : {1, 32}) { - for (size_t inputSize : {7, 14, 54}) { - for (size_t filterSize : {1, 3, 5}) { - for (size_t inputChannels : {64, 128}) { - size_t outputChannels = inputChannels; - for (size_t stride : {1, 2}) { - for (size_t padding : {0, 1}) { - if (padding >= filterSize) break; - size_t outputSize = - (inputSize - filterSize + 2 * padding + stride) / stride; - VLOG(3) << " batchSize=" << batchSize - << " inputChannels=" << inputChannels - << " inputHeight=" << inputSize - << " inputWidth=" << inputSize - << " outputChannels=" << outputChannels - << " filterHeight=" << filterSize - << " filterWidth=" << filterSize - << " outputHeight=" << outputSize - << " outputWidth=" << outputSize << " stride=" << stride - << " padding=" << padding; - - std::vector paddings = {padding, padding}; - std::vector strides = {stride, stride}; - size_t groups = inputChannels; - Compare2Function test( - conv1, - conv2, - FuncConfig() - .set("paddings", paddings) - .set("strides", strides) - .set("groups", groups) - .set("algo", algo)); - - TensorShape input{ - batchSize, inputChannels, inputSize, inputSize}; - TensorShape filter{inputChannels, 1, 1, filterSize, filterSize}; - TensorShape output{ - batchSize, outputChannels, outputSize, outputSize}; - - if (type == kForwardTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.run(); - } else if (type == kBackwardInputTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, input), ADD_TO); - test.run(); - } else if (type == kBackwardFilterTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.run(); - } - } - } - } - } - } - } - } -}; - -// Mainly used to test cases where the height and width (input, filter) -// are not equal. -template -class DepthwiseConvolutionTest2 { -public: - DepthwiseConvolutionTest2(const std::string& conv1, - const std::string& conv2, - TestType type, - std::string algo = "auto") { - for (size_t batchSize : {16}) { - for (size_t inputHeight : {7, 31}) { - for (size_t inputWidth : {10, 54}) { - for (size_t filterHeight : {1, 5}) { - for (size_t filterWidth : {3, 7}) { - for (size_t inputChannels : {32}) { - size_t outputChannels = inputChannels; - size_t stride = 1; - size_t padding = 0; - size_t outputHeight = - (inputHeight - filterHeight + 2 * padding + stride) / - stride; - size_t outputWidth = - (inputWidth - filterWidth + 2 * padding + stride) / stride; - VLOG(3) << " batchSize=" << batchSize - << " inputChannels=" << inputChannels - << " inputHeight=" << inputHeight - << " inputWidth=" << inputWidth - << " outputChannels=" << outputChannels - << " filterHeight=" << filterHeight - << " filterWidth=" << filterWidth - << " outputHeight=" << outputHeight - << " outputWidth=" << outputWidth - << " stride=" << stride << " padding=" << padding; - - std::vector paddings = {padding, padding}; - std::vector strides = {stride, stride}; - size_t groups = inputChannels; - Compare2Function test( - conv1, - conv2, - FuncConfig() - .set("paddings", paddings) - .set("strides", strides) - .set("groups", groups) - .set("algo", algo)); - - TensorShape input{ - batchSize, inputChannels, inputHeight, inputWidth}; - TensorShape filter{ - inputChannels, 1, 1, filterHeight, filterWidth}; - TensorShape output{ - batchSize, outputChannels, outputHeight, outputWidth}; - - if (type == kForwardTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.run(); - } else if (type == kBackwardInputTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, input), ADD_TO); - test.run(); - } else if (type == kBackwardFilterTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.run(); - } - } - } - } - } - } - } - } -}; - // ======Start Convolution TEST====== TEST(Forward, GEMM) { ConvolutionTest test( - "NaiveConv-CPU", "GemmConv-CPU", kForwardTest); + "NaiveConv-CPU", "GemmConv-CPU", convolutionType, kForwardTest); ConvolutionTest2 test2( - "NaiveConv-CPU", "GemmConv-CPU", kForwardTest); + "NaiveConv-CPU", "GemmConv-CPU", convolutionType, kForwardTest); } #ifndef PADDLE_ONLY_CPU TEST(Forward, GEMM2) { ConvolutionTest test( - "GemmConv-CPU", "GemmConv-GPU", kForwardTest); + "GemmConv-CPU", "GemmConv-GPU", convolutionType, kForwardTest); ConvolutionTest2 test2( - "GemmConv-CPU", "GemmConv-GPU", kForwardTest); + "GemmConv-CPU", "GemmConv-GPU", convolutionType, kForwardTest); } TEST(BackwardInput, GEMM) { ConvolutionTest test( - "GemmConvGradInput-CPU", "GemmConvGradInput-GPU", kBackwardInputTest); + "GemmConvGradInput-CPU", + "GemmConvGradInput-GPU", + convolutionType, + kBackwardInputTest); ConvolutionTest2 test2( - "GemmConvGradInput-CPU", "GemmConvGradInput-GPU", kBackwardInputTest); + "GemmConvGradInput-CPU", + "GemmConvGradInput-GPU", + convolutionType, + kBackwardInputTest); } TEST(BackwardFilter, GEMM) { ConvolutionTest test( - "GemmConvGradFilter-CPU", "GemmConvGradFilter-GPU", kBackwardFilterTest); + "GemmConvGradFilter-CPU", + "GemmConvGradFilter-GPU", + convolutionType, + kBackwardFilterTest); ConvolutionTest2 test2( - "GemmConvGradFilter-CPU", "GemmConvGradFilter-GPU", kBackwardFilterTest); + "GemmConvGradFilter-CPU", + "GemmConvGradFilter-GPU", + convolutionType, + kBackwardFilterTest); } #endif // ======End Convolution TEST====== @@ -364,38 +275,54 @@ TEST(BackwardFilter, GEMM) { #ifndef PADDLE_ONLY_CPU TEST(DepthwiseConvForward, GEMM) { - DepthwiseConvolutionTest test( - "GemmConv-GPU", "DepthwiseConv-GPU", kForwardTest); - DepthwiseConvolutionTest2 test2( - "GemmConv-GPU", "DepthwiseConv-GPU", kForwardTest); + ConvolutionTest test( + "GemmConv-GPU", + "DepthwiseConv-GPU", + depthwiseConvolutionType, + kForwardTest); + ConvolutionTest2 test2( + "GemmConv-GPU", + "DepthwiseConv-GPU", + depthwiseConvolutionType, + kForwardTest); } TEST(DepthwiseConvForward, GEMM2) { - DepthwiseConvolutionTest test( - "DepthwiseConv-GPU", "DepthwiseConv-GPU", kForwardTest); - DepthwiseConvolutionTest2 test2( - "DepthwiseConv-GPU", "DepthwiseConv-GPU", kForwardTest); + ConvolutionTest test( + "DepthwiseConv-GPU", + "DepthwiseConv-GPU", + depthwiseConvolutionType, + kForwardTest); + ConvolutionTest2 test2( + "DepthwiseConv-GPU", + "DepthwiseConv-GPU", + depthwiseConvolutionType, + kForwardTest); } TEST(DepthwiseConvBackwardInput, GEMM) { - DepthwiseConvolutionTest test( + ConvolutionTest test( "DepthwiseConvGradInput-GPU", "DepthwiseConvGradInput-GPU", + depthwiseConvolutionType, kBackwardInputTest); - DepthwiseConvolutionTest2 test2( + ConvolutionTest2 test2( "DepthwiseConvGradInput-GPU", "DepthwiseConvGradInput-GPU", + depthwiseConvolutionType, kBackwardInputTest); } TEST(DepthwiseConvBackwardFilter, GEMM) { - DepthwiseConvolutionTest test( + ConvolutionTest test( "DepthwiseConvGradFilter-GPU", "DepthwiseConvGradFilter-GPU", + depthwiseConvolutionType, kBackwardFilterTest); - DepthwiseConvolutionTest2 test2( + ConvolutionTest2 test2( "DepthwiseConvGradFilter-GPU", "DepthwiseConvGradFilter-GPU", + depthwiseConvolutionType, kBackwardFilterTest); } #endif -- GitLab