diff --git a/paddle/fluid/operators/fc_mkldnn_op.cc b/paddle/fluid/operators/fc_mkldnn_op.cc index 3e006189ef99c319ddad4af58dce67753e703e91..d0023713b4e532a961458525bcc3748f6f0b2105 100644 --- a/paddle/fluid/operators/fc_mkldnn_op.cc +++ b/paddle/fluid/operators/fc_mkldnn_op.cc @@ -23,67 +23,56 @@ namespace operators { using paddle::framework::Tensor; using paddle::platform::MKLDNNDeviceContext; -struct MKLDNNMatrixSize final { - explicit MKLDNNMatrixSize(const std::vector& in, - const std::vector& w) - : mb{in[0]}, ic{in[1]}, oc{w[1]}, h{in[2]}, w{in[3]} {} - - bool is_spatial() const { return h > 2 && w > 2; } - - const int mb; - const int ic; - const int oc; - const int h, w; -}; - template class MKLDNNMD { public: explicit MKLDNNMD(const T* in, const T* w, bool bias) - : sz_(std::unique_ptr(new MKLDNNMatrixSize( - paddle::framework::vectorize2int(in->dims()), - paddle::framework::vectorize2int(w->dims())))) { + : in{paddle::framework::vectorize2int(in->dims())}, + w{paddle::framework::vectorize2int(w->dims())} { with_bias_ = bias; } mkldnn::memory::desc dst() const { - return platform::MKLDNNMemDesc({sz_->mb, sz_->oc}, + return platform::MKLDNNMemDesc({in[0], w[1]}, mkldnn::memory::data_type::f32, mkldnn::memory::format::nc); } mkldnn::memory::desc src() const { - return sz_->is_spatial() - ? platform::MKLDNNMemDesc({sz_->mb, sz_->ic, sz_->h, sz_->w}, + return is_spatial() + ? platform::MKLDNNMemDesc({in[0], in[1], in[2], in[3]}, mkldnn::memory::data_type::f32, mkldnn::memory::format::nchw) - : platform::MKLDNNMemDesc({sz_->mb, sz_->ic}, + : platform::MKLDNNMemDesc({in[0], in[1]}, mkldnn::memory::data_type::f32, mkldnn::memory::format::nc); } mkldnn::memory::desc weights() const { - return sz_->is_spatial() - ? platform::MKLDNNMemDesc({sz_->oc, sz_->ic, sz_->h, sz_->w}, + return is_spatial() + ? platform::MKLDNNMemDesc({w[1], in[1], in[2], in[3]}, mkldnn::memory::data_type::f32, mkldnn::memory::format::oihw) - : platform::MKLDNNMemDesc({sz_->oc, sz_->ic}, + : platform::MKLDNNMemDesc({w[1], in[1]}, mkldnn::memory::data_type::f32, mkldnn::memory::format::oi); } mkldnn::memory::desc bias() const { return with_bias_ - ? platform::MKLDNNMemDesc({sz_->oc}, - mkldnn::memory::data_type::f32, + ? platform::MKLDNNMemDesc({w[1]}, mkldnn::memory::data_type::f32, mkldnn::memory::format::format_undef) : platform::MKLDNNMemDesc({}, mkldnn::memory::data_type::f32, mkldnn::memory::format::format_undef); } private: - std::unique_ptr sz_; + bool is_spatial() const { return in.size() > 1 && w.size() > 1; } + + std::vector in; + std::vector w; bool with_bias_; + bool is_spatial_; }; class MKLDNNMemory { diff --git a/paddle/fluid/operators/fc_op.cc b/paddle/fluid/operators/fc_op.cc index 93b59854db04b2322fa668091ad3cf7289aff1f2..41f9c0b8a9bbca91c5c54a55ca652ce40f214f99 100644 --- a/paddle/fluid/operators/fc_op.cc +++ b/paddle/fluid/operators/fc_op.cc @@ -29,8 +29,8 @@ void FCOp::InferShape(framework::InferShapeContext* ctx) const { auto w_dims = ctx->GetInputDim("W"); std::vector output_shape({in_dims[0], w_dims[1]}); - PADDLE_ENFORCE(in_dims.size() == 4, - "Fully Connected input should be 4-D tensor."); + PADDLE_ENFORCE(in_dims.size() == 4 || in_dims.size() == 2, + "Fully Connected input should be 2-D or 4-D tensor."); PADDLE_ENFORCE(w_dims.size() == 2, "Fully Connected input should be 2-D tensor."); @@ -96,22 +96,11 @@ FCOpMaker::FCOpMaker(OpProto* proto, OpAttrChecker* op_checker) The fully connected operation calculates the output based on the input, weights and bias attribute. The size of each dimension of the parameters checked in the infer-shape. - Input(Input) is NCHW or NC format. Where N is batch size, C is the number of channels, - H is the height of the feature, and W is the width of the feature. - Weights(W) is OIHW or OI format. Where H is the height of the feature, W is the width of the feature, - O is the height of output, and I is the number of channels. - Output(Out) is NC format. Where N is batch size, and C is the number of channels. The matrix of bias is generated by the mkldnn framework, when the bias_attr is True. Additional parametrs are use_mkldnn and bias_attr. The input(X) size and output(Out) size may be diffrent. -Example: - Input: - Input shape: $(N, C_{in}, H_{in}, W_{in})$ - Weight shape: $(O_{out}, I_{in}, H_{in}, W_{in})$ - Bias shape: $(O_{out})$ - Output: - Output shape: $(N, C_{out})$ + The fully connected layer only supports MKLDNN version )DOC"); } diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index 40809b304fd9cc7d4fe012b976b602d8e8813fd3..d2e7d58524bfb11627b6acb36ef873c41b348f0f 100644 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -167,8 +167,9 @@ def fc(input, shape=param_shape, dtype=dtype, is_bias=False) - bias_attr = False - if bias_attr is not None: + if bias_attr is None or bias_attr is False: + bias_attr = False + else: bias_attr = True helper.append_op( type="fc",