From 0c951176bd16ade7b347f1f251e8374dca01a6da Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Mon, 7 Aug 2017 21:13:41 +0800 Subject: [PATCH] pass mkldnn gtest --- paddle/gserver/layers/MkldnnFcLayer.cpp | 24 ++++++++-- paddle/gserver/layers/MkldnnFcLayer.h | 11 +++-- paddle/gserver/layers/MkldnnLayer.cpp | 62 ++++++++++++++++--------- paddle/gserver/layers/MkldnnLayer.h | 27 ++++++++++- paddle/gserver/tests/MkldnnTester.cpp | 30 +++++------- paddle/gserver/tests/test_Mkldnn.cpp | 12 ++--- 6 files changed, 112 insertions(+), 54 deletions(-) diff --git a/paddle/gserver/layers/MkldnnFcLayer.cpp b/paddle/gserver/layers/MkldnnFcLayer.cpp index c3b1f83d7d..29b2cc184d 100644 --- a/paddle/gserver/layers/MkldnnFcLayer.cpp +++ b/paddle/gserver/layers/MkldnnFcLayer.cpp @@ -42,7 +42,6 @@ bool MkldnnFcLayer::init(const LayerMap& layerMap, // create weight weight_ = std::unique_ptr(new Weight(oc_, iLayerSize_, parameters_[0], 0)); - initWgt(); // create biases if (biasParameter_.get() != NULL) { @@ -51,20 +50,36 @@ bool MkldnnFcLayer::init(const LayerMap& layerMap, return true; } -void MkldnnFcLayer::initWgt() { +void MkldnnFcLayer::cvtWgtFromPaddle() { + if (hasInitedWgt_) { + return; + } + // The weight_ is transposed from initial paddle weight MatrixPtr paddleWgt = Matrix::create( weight_->getW()->getData(), iLayerSize_, oc_, false, false); std::ostringstream ostr; paddleWgt->print(ostr); - VLOG(DNN_BASE) << ostr.str(); + VLOG(DNN_ALL) << "Initial Weight from paddle: " << std::endl << ostr.str(); - // Firstly in mkldnn, the matrix is transposed from initial paddle weight + // The mkldnn weight is transposed from initial paddle matrix MatrixPtr paddleWgtT; paddleWgt->transpose(paddleWgtT, true); weight_->getW()->copyFrom(*paddleWgtT); + hasInitedWgt_ = true; +} + +void MkldnnFcLayer::cvtWgtToPaddle() { + MatrixPtr dnnWgt = weight_->getW(); + MatrixPtr paddleWgt; + dnnWgt->transpose(paddleWgt, true); + + // copy paddle weight and override on weight_ + MatrixPtr dnnWgtT = Matrix::create( + dnnWgt->getData(), dnnWgt->getWidth(), dnnWgt->getHeight(), false, false); + dnnWgtT->copyFrom(*paddleWgt); } void MkldnnFcLayer::reshape() { @@ -86,6 +101,7 @@ void MkldnnFcLayer::reshape() { ic_ = iLayerSize_ / (ih_ * iw_); CHECK_EQ(size_t(ic_ * ih_ * iw_), iLayerSize_) << "not divisible"; CHECK_EQ(size_t(oc_), getSize()); + printSizeInfo(); // reset output output_.setFrameHeight(oh_); diff --git a/paddle/gserver/layers/MkldnnFcLayer.h b/paddle/gserver/layers/MkldnnFcLayer.h index 4cc445e87b..0064fc4727 100644 --- a/paddle/gserver/layers/MkldnnFcLayer.h +++ b/paddle/gserver/layers/MkldnnFcLayer.h @@ -29,25 +29,30 @@ protected: // input layer size, can not be change after init size_t iLayerSize_; // == ic * ih * iw + bool hasInitedWgt_; + // fc weight and bias std::unique_ptr weight_; std::unique_ptr biases_; public: - explicit MkldnnFcLayer(const LayerConfig& config) : MkldnnLayer(config) {} + explicit MkldnnFcLayer(const LayerConfig& config) + : MkldnnLayer(config), hasInitedWgt_(false) {} ~MkldnnFcLayer() {} bool init(const LayerMap& layerMap, const ParameterMap& parameterMap) override; - void initWgt(); + void cvtWgtFromPaddle() override; - void reshape(); + void cvtWgtToPaddle() override; void forward(PassType passType) override; void backward(const UpdateCallback& callback) override; + + void reshape(); }; } // namespace paddle diff --git a/paddle/gserver/layers/MkldnnLayer.cpp b/paddle/gserver/layers/MkldnnLayer.cpp index cead3d87ea..0e1e1c3061 100644 --- a/paddle/gserver/layers/MkldnnLayer.cpp +++ b/paddle/gserver/layers/MkldnnLayer.cpp @@ -25,11 +25,18 @@ namespace paddle { bool MkldnnLayer::init(const LayerMap& layerMap, const ParameterMap& parameterMap) { + if (!Layer::init(layerMap, parameterMap)) { + return false; + } + CHECK(FLAGS_use_mkldnn) << "MkldnnLayers only support use_mkldnn." << "Please set WITH_MKLDNN=ON " << "and set use_mkldnn=True"; + stream_.reset(new MkldnnStream()); + engine_ = CpuEngine::Instance().getEngine(); + // TODO(TJ): deivecId - return Layer::init(layerMap, parameterMap); + return true; } void MkldnnLayer::resetForwardFC(int bs, @@ -42,7 +49,6 @@ void MkldnnLayer::resetForwardFC(int bs, real* wgtData, real* biasData) { bool hasSpatial = ih == 1 && iw == 1 ? false : true; - engine_ = CpuEngine::Instance().getEngine(); mem::desc botMD = hasSpatial ? createMD({bs, ic, ih, iw}, format::nchw) : createMD({bs, ic}, format::nc); @@ -52,21 +58,21 @@ void MkldnnLayer::resetForwardFC(int bs, : createMD({}, format::format_undef); mem::desc topMD = createMD({bs, oc}, format::nc); + inVal_.reset(new mem(mem::primitive_desc(botMD, engine_), botData)); + wgtVal_.reset(new mem(mem::primitive_desc(wgtMD, engine_), wgtData)); + outVal_.reset(new mem(mem::primitive_desc(topMD, engine_), topData)); + mkldnn::prop_kind pk = mkldnn::prop_kind::forward; fc_fwd::desc fwdDesc = biasData != NULL ? fc_fwd::desc(pk, botMD, wgtMD, biasMD, topMD) : fc_fwd::desc(pk, botMD, wgtMD, topMD); fc_fwd::primitive_desc fwdPD = fc_fwd::primitive_desc(fwdDesc, engine_); - mem bot = mem(mem::primitive_desc(botMD, engine_), botData); - mem wgt = mem(mem::primitive_desc(wgtMD, engine_), wgtData); - mem top = mem(mem::primitive_desc(topMD, engine_), topData); - if (biasData != NULL) { - mem bias = mem(mem::primitive_desc(biasMD, engine_), biasData); - fwd_.reset(new fc_fwd(fwdPD, bot, wgt, bias, top)); + biasVal_.reset(new mem(mem::primitive_desc(biasMD, engine_), biasData)); + fwd_.reset(new fc_fwd(fwdPD, *inVal_, *wgtVal_, *biasVal_, *outVal_)); } else { - fwd_.reset(new fc_fwd(fwdPD, bot, wgt, top)); + fwd_.reset(new fc_fwd(fwdPD, *inVal_, *wgtVal_, *outVal_)); } pipelineFwd_.clear(); pipelineFwd_.push_back(*fwd_); @@ -84,8 +90,12 @@ void MkldnnLayer::mkldnnForwardFC(int bs, // if input size changed, reset it resetForwardFC(bs, ic, ih, iw, botData, oc, topData, wgtData, biasData); + this->cvtWgtFromPaddle(); + + // update input, since the data might be changed if this is after data layer + inVal_->set_data_handle(botData); + // just forward - // update botdata stream_->submit(pipelineFwd_); } @@ -112,6 +122,10 @@ void MkldnnLayer::resetBackwardFC(int bs, mem::desc biasMD = biasDiff != NULL ? createMD({oc}, format::x) : createMD({}, format::format_undef); + inVal_.reset(new mem(mem::primitive_desc(botMD, engine_), botData)); + wgtGrad_.reset(new mem(mem::primitive_desc(wgtMD, engine_), wgtDiff)); + outGrad_.reset(new mem(mem::primitive_desc(topMD, engine_), topDiff)); + fc_fwd::desc fwdDesc = fc_fwd::desc(mkldnn::prop_kind::forward, botMD, wgtMD, topMD); fc_fwd::primitive_desc fwdPD = fc_fwd::primitive_desc(fwdDesc, engine_); @@ -121,15 +135,12 @@ void MkldnnLayer::resetBackwardFC(int bs, fc_bwdWgt::primitive_desc bwdWgtPD = fc_bwdWgt::primitive_desc(bwdWgtDesc, engine_, fwdPD); - mem botVal = mem(mem::primitive_desc(botMD, engine_), botData); - mem wgtGrad = mem(mem::primitive_desc(wgtMD, engine_), wgtDiff); - mem topGrad = mem(mem::primitive_desc(topMD, engine_), topDiff); - if (biasDiff != NULL) { - mem biasGrad = mem(mem::primitive_desc(biasMD, engine_), biasDiff); - bwdWgt_.reset(new fc_bwdWgt(bwdWgtPD, botVal, topGrad, wgtGrad, biasGrad)); + biasGrad_.reset(new mem(mem::primitive_desc(biasMD, engine_), biasDiff)); + bwdWgt_.reset( + new fc_bwdWgt(bwdWgtPD, *inVal_, *outGrad_, *wgtGrad_, *biasGrad_)); } else { - bwdWgt_.reset(new fc_bwdWgt(bwdWgtPD, botVal, topGrad, wgtGrad)); + bwdWgt_.reset(new fc_bwdWgt(bwdWgtPD, *inVal_, *outGrad_, *wgtGrad_)); } pipelineBwd_.clear(); pipelineBwd_.push_back(*bwdWgt_); @@ -142,9 +153,9 @@ void MkldnnLayer::resetBackwardFC(int bs, fc_bwdData::desc bwdDataDesc = fc_bwdData::desc(botMD, wgtMD, topMD); fc_bwdData::primitive_desc bwdDataPD = fc_bwdData::primitive_desc(bwdDataDesc, engine_, fwdPD); - mem botGrad = mem(mem::primitive_desc(botMD, engine_), botDiff); - mem wgtVal = mem(mem::primitive_desc(wgtMD, engine_), wgtData); - bwdData_.reset(new fc_bwdData(bwdDataPD, topGrad, wgtVal, botGrad)); + inGrad_.reset(new mem(mem::primitive_desc(botMD, engine_), botDiff)); + wgtVal_.reset(new mem(mem::primitive_desc(wgtMD, engine_), wgtData)); + bwdData_.reset(new fc_bwdData(bwdDataPD, *outGrad_, *wgtVal_, *inGrad_)); pipelineBwd_.push_back(*bwdData_); } @@ -172,11 +183,18 @@ void MkldnnLayer::mkldnnBackwardFC(int bs, wgtData, biasDiff); - // just forward - // update botdata + // update data + outGrad_->set_data_handle(topDiff); + stream_->submit(pipelineBwd_); } +void MkldnnLayer::printSizeInfo() { + VLOG(DNN_SIZES) << "bs: " << bs_ << ", ic: " << ic_ << ", ih: " << ih_ + << ", iw: " << iw_ << ", oc: " << oc_ << ", oh: " << oh_ + << ", ow: " << ow_; +} + mem::desc MkldnnLayer::createMD(mem::dims dims, mem::format fmt, mem::data_type type) { diff --git a/paddle/gserver/layers/MkldnnLayer.h b/paddle/gserver/layers/MkldnnLayer.h index 5927bd6d52..a9eb9f79da 100644 --- a/paddle/gserver/layers/MkldnnLayer.h +++ b/paddle/gserver/layers/MkldnnLayer.h @@ -40,13 +40,24 @@ protected: // mkldnn engine, stream and primivtives mkldnn::engine engine_; std::shared_ptr stream_; - std::shared_ptr fwd_; std::shared_ptr bwdWgt_; std::shared_ptr bwdData_; std::vector pipelineFwd_; std::vector pipelineBwd_; + // TODO(TJ): change below memory as MkldnnMatrixPtr type + // input == bottom, output == top + // value == data, grad == diff + std::shared_ptr inVal_; + std::shared_ptr inGrad_; + std::shared_ptr outVal_; + std::shared_ptr outGrad_; + std::shared_ptr wgtVal_; + std::shared_ptr wgtGrad_; + std::shared_ptr biasVal_; + std::shared_ptr biasGrad_; + public: explicit MkldnnLayer(const LayerConfig& config) : Layer(config), @@ -67,6 +78,20 @@ public: virtual bool init(const LayerMap& layerMap, const ParameterMap& parameterMap); + virtual void printSizeInfo(); + + /** + * convert weight from paddle format to mkldnn format + * weight_ will be override + */ + virtual void cvtWgtFromPaddle() { ; } + + /** + * convert mkldnn weight to paddle format + * weight_ will be override + */ + virtual void cvtWgtToPaddle() { ; } + void resetForwardFC(int bs, int ic, int ih, diff --git a/paddle/gserver/tests/MkldnnTester.cpp b/paddle/gserver/tests/MkldnnTester.cpp index 38e5bc75be..ecf0f9124d 100644 --- a/paddle/gserver/tests/MkldnnTester.cpp +++ b/paddle/gserver/tests/MkldnnTester.cpp @@ -14,6 +14,7 @@ limitations under the License. */ #include "MkldnnTester.h" #include "paddle/gserver/layers/MkldnnBase.h" +#include "paddle/gserver/layers/MkldnnLayer.h" namespace paddle { @@ -145,7 +146,10 @@ void MkldnnTester::checkBackwardWgts() { vector dnnWgts; // used to temply save mkldnn weights saveWgt(parameters_[DNN], dnnWgts); - // TODO(TJ): cvtWgtToPaddle + const MkldnnLayerPtr dnnlayer = + std::dynamic_pointer_cast(dnnLayer_); + CHECK(dnnlayer); + dnnlayer->cvtWgtToPaddle(); for (size_t i = 0; i < parameters_[DNN].size(); ++i) { const VectorPtr& dnn = parameters_[DNN][i]->getBuf(PARAMETER_VALUE); const VectorPtr& ref = parameters_[REF][i]->getBuf(PARAMETER_VALUE); @@ -233,11 +237,10 @@ void MkldnnTester::printMatrix(const MatrixPtr& m) { if (!log_) { return; } -#ifdef _DEBUG - std::ostream str; - m->print(str); - VLOG(lvl_) << str; -#endif + + std::ostringstream ostr; + m->print(ostr); + VLOG(lvl_) << std::endl << ostr.str(); } void MkldnnTester::printVector(const VectorPtr& v) { @@ -245,15 +248,9 @@ void MkldnnTester::printVector(const VectorPtr& v) { return; } - CHECK(v); - CHECK(v->getData()); - const real* pd = v->getData(); - const size_t sz = v->getSize(); - std::stringstream row; - for (size_t i = 0; i < sz; ++i) { - row << pd[i] << ", "; - } - VLOG(lvl_) << row.str(); + std::ostringstream ostr; + v->print(ostr, v->getSize()); + VLOG(lvl_) << std::endl << ostr.str(); } double MkldnnTester::getDelta(const real* d1, @@ -335,7 +332,6 @@ void MkldnnTester::run(const TestConfig& dnn, // Firstly always set flag false to initial from paddle weight TestConfig first = dnn; - // first.layerConfig.set_init_wgt_from_mkldnn(false); // reset and run once reset(first, ref, batchSize); @@ -348,8 +344,6 @@ void MkldnnTester::run(const TestConfig& dnn, // firstly get the flag bool initWgtFromMkldnn = false; - // dnn.layerConfig.has_init_wgt_from_mkldnn() && - // dnn.layerConfig.init_wgt_from_mkldnn(); if (initWgtFromMkldnn) { // after run once the mkldnn weight has been stored in dnnlayer diff --git a/paddle/gserver/tests/test_Mkldnn.cpp b/paddle/gserver/tests/test_Mkldnn.cpp index c2c6b701ec..1d367e6180 100644 --- a/paddle/gserver/tests/test_Mkldnn.cpp +++ b/paddle/gserver/tests/test_Mkldnn.cpp @@ -55,12 +55,12 @@ void testFcLayer(const testFCDesc& pm) { } TEST(MkldnnLayer, fcLayer) { - testFcLayer({2, 2, 3, 1, 1}); /* - testFcLayer({16, 32, 64, 1, 1}); - testFcLayer({8, 16, 32, 13, 13}); - testFcLayer({4, 12, 18, 13, 11}); - testFcLayer({2, 64, 32, 16, 16}); - testFcLayer({15, 3, 6, 16, 16});*/ + testFcLayer({2, 2, 3, 1, 1}); + testFcLayer({3, 7, 19, 1, 1}); + testFcLayer({8, 16, 32, 13, 13}); + testFcLayer({4, 12, 18, 13, 11}); + testFcLayer({2, 64, 32, 16, 16}); + testFcLayer({15, 3, 6, 16, 16}); } // TODO(TJ): add branch test -- GitLab