diff --git a/paddle/gserver/layers/ConvBaseOperator.cpp b/paddle/gserver/layers/ConvBaseOperator.cpp index 8ba4ee5d7adb648e7ef66b9c15b236e8b7cb43c2..5c231986292d2cd26ee30ccc122142fccd5b4949 100644 --- a/paddle/gserver/layers/ConvBaseOperator.cpp +++ b/paddle/gserver/layers/ConvBaseOperator.cpp @@ -49,7 +49,22 @@ ConvBaseOperator::ConvBaseOperator(const OperatorConfig &config, bool useGpu) isSelectAlgo_ = false; } -void ConvBaseOperator::allocConvWorkSpace(size_t maxWorkSpace) { +void ConvBaseOperator::allocConvWorkSpace() { + hl_conv_workspace(imageDesc_, + outputDesc_, + filterDesc_, + convDesc_, + &fwdAlgo_, + &fwdLimitBytes_, + &bwdDataAlgo_, + &bwdDataLimitBytes_, + &bwdFilterAlgo_, + &bwdFilterLimitBytes_); + + size_t maxWorkSpace = 0; + maxWorkSpace = std::max(fwdLimitBytes_, bwdDataLimitBytes_); + maxWorkSpace = std::max(maxWorkSpace, bwdFilterLimitBytes_); + if (maxWorkSpace > workSpaceInBytes_) { if (workSpaceInBytes_ != 0) { hl_free_mem_device(workSpace_); @@ -60,59 +75,6 @@ void ConvBaseOperator::allocConvWorkSpace(size_t maxWorkSpace) { } } -void ConvBaseOperator::reshape(int batchSize) { - if (isDeconv_) { - outputH_ = ins_[0]->getFrameHeight(); - outputW_ = ins_[0]->getFrameWidth(); - if (outputH_ == 0) outputH_ = outputY_; - if (outputW_ == 0) outputW_ = outputX_; - imageH_ = - imageSize(outputH_, filterSizeY_, paddingY_, strideY_, caffeMode_); - imageW_ = imageSize(outputW_, filterSize_, padding_, stride_, caffeMode_); - /// Check that the imageSizes are consistent with config - CHECK_EQ(imageH_, imgSizeY_); - CHECK_EQ(imageW_, imgSize_); - out_->setFrameHeight(imageH_); - out_->setFrameWidth(imageW_); - } else { - imageH_ = ins_[0]->getFrameHeight(); - imageW_ = ins_[0]->getFrameWidth(); - if (imageH_ == 0) imageH_ = imgSizeY_; - if (imageW_ == 0) imageW_ = imgSize_; - outputH_ = - outputSize(imageH_, filterSizeY_, paddingY_, strideY_, caffeMode_); - outputW_ = outputSize(imageW_, filterSize_, padding_, stride_, caffeMode_); - /// Check that the outputSizes are consistent with config - CHECK_EQ(outputH_, outputY_); - CHECK_EQ(outputW_, outputX_); - out_->setFrameHeight(outputH_); - out_->setFrameWidth(outputW_); - } - - reshapeImageDescriptors(); - - if (!isSelectAlgo_) { - hl_conv_workspace(imageDesc_, - outputDesc_, - filterDesc_, - convDesc_, - &fwdAlgo_, - &fwdLimitBytes_, - &bwdDataAlgo_, - &bwdDataLimitBytes_, - &bwdFilterAlgo_, - &bwdFilterLimitBytes_); - - size_t maxWorkSpace = 0; - maxWorkSpace = std::max(fwdLimitBytes_, bwdDataLimitBytes_); - maxWorkSpace = std::max(maxWorkSpace, bwdFilterLimitBytes_); - - allocConvWorkSpace(maxWorkSpace); - } - - isSelectAlgo_ = true; -} - void ConvBaseOperator::computeConvSizes() { hl_create_filter_descriptor( &filterDesc_, channels_, numFilters_, filterSizeY_, filterSize_); @@ -153,15 +115,6 @@ void ConvBaseOperator::reshapeImageDescriptors() { padding_, strideY_, stride_); - - if (isDeconv_) { - inputOffset_ = numFilters_ * outputH_ * outputW_; - outputOffset_ = channels_ * imageH_ * imageW_; - } else { - inputOffset_ = channels_ * imageH_ * imageW_; - outputOffset_ = numFilters_ * outputH_ * outputW_; - } - weightOffset_ = numFilters_ * channels_ * filterSize_ * filterSizeY_; } void ConvBaseOperator::getConvParams() { diff --git a/paddle/gserver/layers/ConvBaseOperator.h b/paddle/gserver/layers/ConvBaseOperator.h index 7cbe707c3256e7984e74fe71d15085ed796b015d..2d42169cde2a80a26edcf98bc2d728e00b075728 100644 --- a/paddle/gserver/layers/ConvBaseOperator.h +++ b/paddle/gserver/layers/ConvBaseOperator.h @@ -56,7 +56,7 @@ protected: /** * Allocate Gpu Memory for cudnn convolution algorithms. */ - void allocConvWorkSpace(size_t maxWorkSpace); + void allocConvWorkSpace(); /** * Create cudnn tensor descriptor for convolution operation. @@ -71,7 +71,7 @@ protected: /** * Reshape cudnn tensor descriptor. */ - void reshape(int batchSize); + virtual void reshape(int batchSize) = 0; /** * Check filter size is equal to the size calculated by parameters from diff --git a/paddle/gserver/layers/ConvBaseProjection.cpp b/paddle/gserver/layers/ConvBaseProjection.cpp index f01cfeaf6e633c6cfff275df63d29a97d20c5d38..d1e932ded595c90cbe6040c330c5c8663d81e2b4 100644 --- a/paddle/gserver/layers/ConvBaseProjection.cpp +++ b/paddle/gserver/layers/ConvBaseProjection.cpp @@ -140,19 +140,7 @@ void ConvBaseProjection::reshapeTensorDesc(int batchSize) { void ConvBaseProjection::reshape(int batchSize) { size_t width = calOutputSize(); CHECK_EQ(width, out_->value->getWidth()); - if (isDeconv_) { - CHECK_EQ(static_cast(configChannels_ * outputH_ * outputW_), - in_->value->getWidth()) - << "Wrong input size for convolution transpose" - << " channels=" << configChannels_ << " outputH=" << outputH_ - << " outputW=" << outputW_ << " inputSize=" << in_->value->getWidth(); - } else { - CHECK_EQ(static_cast(configChannels_ * imageH_ * imageW_), - in_->value->getWidth()) - << "Wrong input size for convolution" - << " channels=" << configChannels_ << " imageH=" << imageH_ - << " imageW=" << imageW_ << " inputSize=" << in_->value->getWidth(); - } + CHECK_EQ(calInputSize(), in_->value->getWidth()); isSelectAlgo_ = (batchSize == batchNum_); batchNum_ = batchSize; diff --git a/paddle/gserver/layers/ConvBaseProjection.h b/paddle/gserver/layers/ConvBaseProjection.h index d55769a284a6932a8d848b28e9127d446caced7d..4a33aa1837dfc36dbead60deaccbc6b772fe4754 100644 --- a/paddle/gserver/layers/ConvBaseProjection.h +++ b/paddle/gserver/layers/ConvBaseProjection.h @@ -40,54 +40,8 @@ protected: void reshapeTensorDesc(int batchSize); void reshape(int batchSize); - size_t calOutputSize() { - if (isDeconv_) { - outputH_ = in_->getFrameHeight(); - outputW_ = in_->getFrameWidth(); - if (outputH_ == 0) outputH_ = configOutH_; - if (outputW_ == 0) outputW_ = configOutW_; - imageH_ = imageSize(outputH_, - filterH_, - paddingH_, - strideH_, - /* caffeMode */ true); - - imageW_ = imageSize(outputW_, - filterW_, - paddingW_, - strideW_, - /* caffeMode */ true); - - const_cast(out_)->setFrameHeight(imageH_); - const_cast(out_)->setFrameWidth(imageW_); - - inputOffset_ = (configChannels_ / groups_) * outputH_ * outputW_; - outputOffset_ = (configNumFilters_ / groups_) * imageH_ * imageW_; - return imageH_ * imageW_ * configNumFilters_; - } else { - imageH_ = in_->getFrameHeight(); - imageW_ = in_->getFrameWidth(); - if (imageH_ == 0) imageH_ = configImgH_; - if (imageW_ == 0) imageW_ = configImgW_; - outputH_ = outputSize(imageH_, - filterH_, - paddingH_, - strideH_, - /* caffeMode */ true); - outputW_ = outputSize(imageW_, - filterW_, - paddingW_, - strideW_, - /* caffeMode */ true); - - const_cast(out_)->setFrameHeight(outputH_); - const_cast(out_)->setFrameWidth(outputW_); - - inputOffset_ = (configChannels_ / groups_) * imageH_ * imageW_; - outputOffset_ = (configNumFilters_ / groups_) * outputH_ * outputW_; - return outputH_ * outputW_ * configNumFilters_; - } - } + virtual size_t calOutputSize() = 0; + virtual size_t calInputSize() = 0; static void* getSpaceBytes(size_t size); diff --git a/paddle/gserver/layers/ConvOperator.cpp b/paddle/gserver/layers/ConvOperator.cpp index e08b065c34aab7d876e2a9801756886956e33283..80932c8c509e3cb013c7e0051cbf4d8ccced0228 100644 --- a/paddle/gserver/layers/ConvOperator.cpp +++ b/paddle/gserver/layers/ConvOperator.cpp @@ -29,6 +29,32 @@ namespace paddle { REGISTER_OPERATOR(conv, ConvOperator); +void ConvOperator::reshape(int batchSize) { + imageH_ = ins_[0]->getFrameHeight(); + imageW_ = ins_[0]->getFrameWidth(); + if (imageH_ == 0) imageH_ = imgSizeY_; + if (imageW_ == 0) imageW_ = imgSize_; + outputH_ = outputSize(imageH_, filterSizeY_, paddingY_, strideY_, caffeMode_); + outputW_ = outputSize(imageW_, filterSize_, padding_, stride_, caffeMode_); + /// Check that the outputSizes are consistent with config + CHECK_EQ(outputH_, outputY_); + CHECK_EQ(outputW_, outputX_); + out_->setFrameHeight(outputH_); + out_->setFrameWidth(outputW_); + + reshapeImageDescriptors(); + + inputOffset_ = channels_ * imageH_ * imageW_; + outputOffset_ = numFilters_ * outputH_ * outputW_; + weightOffset_ = numFilters_ * channels_ * filterSize_ * filterSizeY_; + + if (!isSelectAlgo_) { + allocConvWorkSpace(); + } + + isSelectAlgo_ = true; +} + void ConvOperator::forward() { size_t batchSize = ins_[0]->value->getHeight(); reshape(batchSize); diff --git a/paddle/gserver/layers/ConvOperator.h b/paddle/gserver/layers/ConvOperator.h index 0901c00f40b312063f22102b71f513aee67c913d..0f3546c67ac174628044d5fb6e5c7bce06f37995 100644 --- a/paddle/gserver/layers/ConvOperator.h +++ b/paddle/gserver/layers/ConvOperator.h @@ -38,6 +38,7 @@ public: virtual ~ConvOperator() {} void forward() override; void backward() override; + void reshape(int batchSize) override; }; } // namespace paddle diff --git a/paddle/gserver/layers/ConvProjection.cpp b/paddle/gserver/layers/ConvProjection.cpp index e106c238ab6d72488eecb48ddba3c77e568a7342..5b7ecc5560c1e7431305b34a331fe1fbc96c6b06 100644 --- a/paddle/gserver/layers/ConvProjection.cpp +++ b/paddle/gserver/layers/ConvProjection.cpp @@ -19,6 +19,34 @@ namespace paddle { REGISTER_PROJECTION(conv, ConvProjection); +size_t ConvProjection::calOutputSize() { + imageH_ = in_->getFrameHeight(); + imageW_ = in_->getFrameWidth(); + if (imageH_ == 0) imageH_ = configImgH_; + if (imageW_ == 0) imageW_ = configImgW_; + outputH_ = outputSize(imageH_, + filterH_, + paddingH_, + strideH_, + /* caffeMode */ true); + outputW_ = outputSize(imageW_, + filterW_, + paddingW_, + strideW_, + /* caffeMode */ true); + + const_cast(out_)->setFrameHeight(outputH_); + const_cast(out_)->setFrameWidth(outputW_); + + inputOffset_ = (configChannels_ / groups_) * imageH_ * imageW_; + outputOffset_ = (configNumFilters_ / groups_) * outputH_ * outputW_; + return outputH_ * outputW_ * configNumFilters_; +} + +size_t ConvProjection::calInputSize() { + return static_cast(configChannels_ * imageH_ * imageW_); +} + void ConvProjection::forward() { int batchSize = in_->value->getHeight(); reshape(batchSize); diff --git a/paddle/gserver/layers/ConvProjection.h b/paddle/gserver/layers/ConvProjection.h index c7d91789781a5478f65a4dfcfc61cfbdb2dac69b..b7d7cc9a275529a02a5d8e82d28ed79cb7ce0b43 100644 --- a/paddle/gserver/layers/ConvProjection.h +++ b/paddle/gserver/layers/ConvProjection.h @@ -36,6 +36,8 @@ public: virtual void forward(); virtual void backward(const UpdateCallback& callback); + virtual size_t calOutputSize(); + virtual size_t calInputSize(); }; } // namespace paddle diff --git a/paddle/gserver/layers/ConvTransOperator.cpp b/paddle/gserver/layers/ConvTransOperator.cpp index 1bb0abdabc755d43bbc0170b7da9aa0ec240d7e1..db026337a473f7edf1a7c0db320f60ff3048eb9c 100644 --- a/paddle/gserver/layers/ConvTransOperator.cpp +++ b/paddle/gserver/layers/ConvTransOperator.cpp @@ -29,6 +29,32 @@ namespace paddle { REGISTER_OPERATOR(convt, ConvTransOperator); +void ConvTransOperator::reshape(int batchSize) { + outputH_ = ins_[0]->getFrameHeight(); + outputW_ = ins_[0]->getFrameWidth(); + if (outputH_ == 0) outputH_ = outputY_; + if (outputW_ == 0) outputW_ = outputX_; + imageH_ = imageSize(outputH_, filterSizeY_, paddingY_, strideY_, caffeMode_); + imageW_ = imageSize(outputW_, filterSize_, padding_, stride_, caffeMode_); + /// Check that the imageSizes are consistent with config + CHECK_EQ(imageH_, imgSizeY_); + CHECK_EQ(imageW_, imgSize_); + out_->setFrameHeight(imageH_); + out_->setFrameWidth(imageW_); + + reshapeImageDescriptors(); + + inputOffset_ = numFilters_ * outputH_ * outputW_; + outputOffset_ = channels_ * imageH_ * imageW_; + weightOffset_ = numFilters_ * channels_ * filterSize_ * filterSizeY_; + + if (!isSelectAlgo_) { + allocConvWorkSpace(); + } + + isSelectAlgo_ = true; +} + void ConvTransOperator::forward() { size_t batchSize = ins_[0]->value->getHeight(); reshape(batchSize); diff --git a/paddle/gserver/layers/ConvTransOperator.h b/paddle/gserver/layers/ConvTransOperator.h index ca0aa6b8bd6e1659187f6372680754d5278fd0d3..ca08dc9aa77d59b45635c16cdd5064c5c3b5f96d 100644 --- a/paddle/gserver/layers/ConvTransOperator.h +++ b/paddle/gserver/layers/ConvTransOperator.h @@ -38,6 +38,7 @@ public: virtual ~ConvTransOperator() {} void forward() override; void backward() override; + void reshape(int batchSize) override; }; } // namespace paddle diff --git a/paddle/gserver/layers/ConvTransProjection.cpp b/paddle/gserver/layers/ConvTransProjection.cpp index 675528acefbd921bb98cec5ef974b7b29a7bc59c..48132a3ce4cc4b50fea6d755d84d7254d2055bec 100644 --- a/paddle/gserver/layers/ConvTransProjection.cpp +++ b/paddle/gserver/layers/ConvTransProjection.cpp @@ -18,6 +18,34 @@ limitations under the License. */ namespace paddle { REGISTER_PROJECTION(convt, ConvTransProjection); +size_t ConvTransProjection::calOutputSize() { + outputH_ = in_->getFrameHeight(); + outputW_ = in_->getFrameWidth(); + if (outputH_ == 0) outputH_ = configOutH_; + if (outputW_ == 0) outputW_ = configOutW_; + imageH_ = imageSize(outputH_, + filterH_, + paddingH_, + strideH_, + /* caffeMode */ true); + + imageW_ = imageSize(outputW_, + filterW_, + paddingW_, + strideW_, + /* caffeMode */ true); + + const_cast(out_)->setFrameHeight(imageH_); + const_cast(out_)->setFrameWidth(imageW_); + + inputOffset_ = (configChannels_ / groups_) * outputH_ * outputW_; + outputOffset_ = (configNumFilters_ / groups_) * imageH_ * imageW_; + return imageH_ * imageW_ * configNumFilters_; +} + +size_t ConvTransProjection::calInputSize() { + return static_cast(configChannels_ * outputH_ * outputW_); +} void ConvTransProjection::forward() { int batchSize = in_->value->getHeight(); diff --git a/paddle/gserver/layers/ConvTransProjection.h b/paddle/gserver/layers/ConvTransProjection.h index 7a4f30024cf030178a057e44fef352d6e74b78aa..6508d17b2409aa0cc11cdafb306604816f010718 100644 --- a/paddle/gserver/layers/ConvTransProjection.h +++ b/paddle/gserver/layers/ConvTransProjection.h @@ -36,6 +36,8 @@ public: virtual void forward(); virtual void backward(const UpdateCallback& callback); + virtual size_t calOutputSize(); + virtual size_t calInputSize(); }; } // namespace paddle