提交 abf9832c 编写于 作者: S sneaxiy

tiny change to save memory

上级 f86198e6
...@@ -129,6 +129,9 @@ class GradOpDescMakerBase { ...@@ -129,6 +129,9 @@ class GradOpDescMakerBase {
std::string ForwardOpType() const { return this->fwd_op_.Type(); } std::string ForwardOpType() const { return this->fwd_op_.Type(); }
protected:
const OpDesc& ForwardOp() const { return fwd_op_; }
private: private:
const OpDesc& fwd_op_; const OpDesc& fwd_op_;
const std::unordered_set<std::string>& no_grad_set_; const std::unordered_set<std::string>& no_grad_set_;
......
...@@ -13,9 +13,46 @@ See the License for the specific language governing permissions and ...@@ -13,9 +13,46 @@ See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#include "paddle/fluid/operators/elementwise_mul_op.h" #include "paddle/fluid/operators/elementwise_mul_op.h"
#include <string>
#include "paddle/fluid/operators/elementwise_op.h" #include "paddle/fluid/operators/elementwise_op.h"
namespace paddle {
namespace operators {
class ElementwiseMulOpGradDescMaker : public framework::SingleGradOpDescMaker {
public:
using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;
protected:
std::unique_ptr<framework::OpDesc> Apply() const override {
std::unique_ptr<framework::OpDesc> op(new framework::OpDesc());
op->SetType("elementwise_mul_grad");
op->SetInput("X", Input("X"));
op->SetInput("Y", Input("Y"));
op->SetInput(framework::GradVarName("Out"), OutputGrad("Out"));
op->SetAttrMap(Attrs());
op->SetOutput(::paddle::framework::GradVarName("X"), InputGrad("X"));
op->SetOutput(::paddle::framework::GradVarName("Y"), InputGrad("Y"));
return op;
}
};
class ElementwiseMulOpMaker : public ElementwiseOpMaker {
protected:
virtual std::string GetName() const { return "Mul"; }
virtual std::string GetEquation() const { return "Out = X \\\\odot Y"; }
};
} // namespace operators
} // namespace paddle
namespace ops = paddle::operators; namespace ops = paddle::operators;
REGISTER_ELEMWISE_OP(elementwise_mul, "Mul", "Out = X \\\\odot Y"); // REGISTER_ELEMWISE_OP(elementwise_mul, "Mul", "Out = X \\\\odot Y");
REGISTER_OPERATOR(elementwise_mul, ops::ElementwiseOp,
ops::ElementwiseMulOpMaker, ops::ElementwiseOpInferVarType,
ops::ElementwiseMulOpGradDescMaker);
REGISTER_OPERATOR(elementwise_mul_grad, ops::ElementwiseOpGrad);
REGISTER_OP_CPU_KERNEL( REGISTER_OP_CPU_KERNEL(
elementwise_mul, elementwise_mul,
ops::ElementwiseMulKernel<paddle::platform::CPUDeviceContext, float>, ops::ElementwiseMulKernel<paddle::platform::CPUDeviceContext, float>,
......
...@@ -57,8 +57,9 @@ class ElementwiseMulGradKernel : public framework::OpKernel<T> { ...@@ -57,8 +57,9 @@ class ElementwiseMulGradKernel : public framework::OpKernel<T> {
auto* x = ctx.Input<Tensor>("X"); auto* x = ctx.Input<Tensor>("X");
auto* y = ctx.Input<Tensor>("Y"); auto* y = ctx.Input<Tensor>("Y");
auto* out = ctx.Input<Tensor>("Out"); // auto* out = ctx.Input<Tensor>("Out");
auto* dout = ctx.Input<Tensor>(framework::GradVarName("Out")); auto* dout = ctx.Input<Tensor>(framework::GradVarName("Out"));
auto* out = dout; // out is not necessary
auto* dx = ctx.Output<Tensor>(framework::GradVarName("X")); auto* dx = ctx.Output<Tensor>(framework::GradVarName("X"));
auto* dy = ctx.Output<Tensor>(framework::GradVarName("Y")); auto* dy = ctx.Output<Tensor>(framework::GradVarName("Y"));
int axis = ctx.Attr<int>("axis"); int axis = ctx.Attr<int>("axis");
......
...@@ -59,7 +59,9 @@ class MatMulKernel : public framework::OpKernel<T> { ...@@ -59,7 +59,9 @@ class MatMulKernel : public framework::OpKernel<T> {
RowMatrixFromVector(x.dims()), 0, context.Attr<bool>("transpose_X")); RowMatrixFromVector(x.dims()), 0, context.Attr<bool>("transpose_X"));
auto mat_dim_b = math::CreateMatrixDescriptor( auto mat_dim_b = math::CreateMatrixDescriptor(
ColumnMatrixFromVector(y.dims()), 0, context.Attr<bool>("transpose_Y")); ColumnMatrixFromVector(y.dims()), 0, context.Attr<bool>("transpose_Y"));
blas.MatMul(x, mat_dim_a, y, mat_dim_b, T(1), out, T(0)); auto scale = static_cast<T>(context.Attr<float>("scale"));
auto bias = static_cast<T>(context.Attr<float>("bias"));
blas.MatMul(x, mat_dim_a, y, mat_dim_b, scale, out, bias);
} }
}; };
...@@ -185,7 +187,8 @@ class MatMulGradKernel : public framework::OpKernel<T> { ...@@ -185,7 +187,8 @@ class MatMulGradKernel : public framework::OpKernel<T> {
auto blas = math::GetBlas<DeviceContext, T>(context); auto blas = math::GetBlas<DeviceContext, T>(context);
auto mat_dim_a = math::CreateMatrixDescriptor(a.dims(), 0, trans_a); auto mat_dim_a = math::CreateMatrixDescriptor(a.dims(), 0, trans_a);
auto mat_dim_b = math::CreateMatrixDescriptor(b.dims(), 0, trans_b); auto mat_dim_b = math::CreateMatrixDescriptor(b.dims(), 0, trans_b);
blas.MatMul(a, mat_dim_a, b, mat_dim_b, T(1), out, T(0)); blas.MatMul(a, mat_dim_a, b, mat_dim_b,
static_cast<T>(context.Attr<float>("scale")), out, T(0));
} }
void CalcInputGrad(const framework::ExecutionContext &context, void CalcInputGrad(const framework::ExecutionContext &context,
...@@ -334,6 +337,8 @@ class MatMulOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -334,6 +337,8 @@ class MatMulOpMaker : public framework::OpProtoAndCheckerMaker {
R"DOC(If true, use the transpose of `Y`. R"DOC(If true, use the transpose of `Y`.
)DOC") )DOC")
.SetDefault(false); .SetDefault(false);
AddAttr<float>("scale", "Scale").SetDefault(1.0f);
AddAttr<float>("bias", "Bias").SetDefault(0.0f);
AddComment(R"DOC( AddComment(R"DOC(
MatMul Operator. MatMul Operator.
......
...@@ -156,12 +156,29 @@ class MulGradOp : public framework::OperatorWithKernel { ...@@ -156,12 +156,29 @@ class MulGradOp : public framework::OperatorWithKernel {
} }
}; };
class MulOpGradMaker : public framework::SingleGradOpDescMaker {
public:
using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;
protected:
std::unique_ptr<framework::OpDesc> Apply() const override {
std::unique_ptr<framework::OpDesc> retv(new framework::OpDesc());
retv->SetType("mul_grad");
retv->SetInput("X", Input("X"));
retv->SetInput("Y", Input("Y"));
retv->SetInput(framework::GradVarName("Out"), OutputGrad("Out"));
retv->SetOutput(framework::GradVarName("X"), InputGrad("X"));
retv->SetOutput(framework::GradVarName("Y"), InputGrad("Y"));
retv->SetAttrMap(Attrs());
return retv;
}
};
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle
namespace ops = paddle::operators; namespace ops = paddle::operators;
REGISTER_OPERATOR(mul, ops::MulOp, ops::MulOpMaker, REGISTER_OPERATOR(mul, ops::MulOp, ops::MulOpMaker, ops::MulOpGradMaker);
paddle::framework::DefaultGradOpDescMaker<true>);
REGISTER_OPERATOR(mul_grad, ops::MulGradOp); REGISTER_OPERATOR(mul_grad, ops::MulGradOp);
REGISTER_OP_CPU_KERNEL( REGISTER_OP_CPU_KERNEL(
mul, ops::MulKernel<paddle::platform::CPUDeviceContext, float>, mul, ops::MulKernel<paddle::platform::CPUDeviceContext, float>,
......
...@@ -49,6 +49,7 @@ $$Out = scale*X$$ ...@@ -49,6 +49,7 @@ $$Out = scale*X$$
)DOC"); )DOC");
AddAttr<float>("scale", "The scaling factor of the scale operator.") AddAttr<float>("scale", "The scaling factor of the scale operator.")
.SetDefault(1.0); .SetDefault(1.0);
AddAttr<float>("bias", "The bias of the scale operator.").SetDefault(0.0);
} }
}; };
...@@ -62,6 +63,7 @@ class ScaleGradMaker : public framework::SingleGradOpDescMaker { ...@@ -62,6 +63,7 @@ class ScaleGradMaker : public framework::SingleGradOpDescMaker {
grad_op->SetInput("X", OutputGrad("Out")); grad_op->SetInput("X", OutputGrad("Out"));
grad_op->SetOutput("Out", InputGrad("X")); grad_op->SetOutput("Out", InputGrad("X"));
grad_op->SetAttr("scale", GetAttr("scale")); grad_op->SetAttr("scale", GetAttr("scale"));
grad_op->SetAttr("bias", 0.0f);
return std::unique_ptr<framework::OpDesc>(grad_op); return std::unique_ptr<framework::OpDesc>(grad_op);
} }
}; };
......
...@@ -29,11 +29,24 @@ class ScaleKernel : public framework::OpKernel<T> { ...@@ -29,11 +29,24 @@ class ScaleKernel : public framework::OpKernel<T> {
auto scale = static_cast<T>(context.Attr<float>("scale")); auto scale = static_cast<T>(context.Attr<float>("scale"));
auto eigen_out = framework::EigenVector<T>::Flatten(*tensor); PADDLE_ENFORCE_EQ(in->dims(), out->dims(),
"in and out should have the same dim");
auto scale = static_cast<T>(ctx.Attr<float>("scale"));
auto bias = static_cast<T>(ctx.Attr<float>("bias"));
if (in_var->IsType<framework::SelectedRows>() && in_var != out_var) {
auto& in_slr = in_var->Get<framework::SelectedRows>();
auto* out_slr = out_var->GetMutable<framework::SelectedRows>();
out_slr->set_rows(in_slr.rows());
out_slr->set_height(in_slr.height());
}
auto eigen_out = framework::EigenVector<T>::Flatten(*out);
auto eigen_in = framework::EigenVector<T>::Flatten(*in); auto eigen_in = framework::EigenVector<T>::Flatten(*in);
auto& dev = auto& dev = *ctx.template device_context<DeviceContext>().eigen_device();
*context.template device_context<DeviceContext>().eigen_device(); eigen_out.device(dev) =
eigen_out.device(dev) = scale * eigen_in; static_cast<T>(scale) * eigen_in + static_cast<T>(bias);
} }
}; };
......
...@@ -3314,7 +3314,13 @@ def l2_normalize(x, axis, epsilon=1e-12, name=None): ...@@ -3314,7 +3314,13 @@ def l2_normalize(x, axis, epsilon=1e-12, name=None):
return out return out
def matmul(x, y, transpose_x=False, transpose_y=False, name=None): def matmul(x,
y,
transpose_x=False,
transpose_y=False,
scale=1.0,
bias=0.0,
name=None):
""" """
Applies matrix multiplication to two tensors. Applies matrix multiplication to two tensors.
...@@ -3348,6 +3354,8 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None): ...@@ -3348,6 +3354,8 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None):
y (Variable): The input variable which is a Tensor or LoDTensor. y (Variable): The input variable which is a Tensor or LoDTensor.
transpose_x (bool): Whether to transpose :math:`x` before multiplication. transpose_x (bool): Whether to transpose :math:`x` before multiplication.
transpose_y (bool): Whether to transpose :math:`y` before multiplication. transpose_y (bool): Whether to transpose :math:`y` before multiplication.
scale (float): The scale of output. Default 1.0.
bias (float): The bias added to output. Default 0.0.
name(str|None): A name for this layer(optional). If set None, the layer name(str|None): A name for this layer(optional). If set None, the layer
will be named automatically. will be named automatically.
...@@ -3415,8 +3423,12 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None): ...@@ -3415,8 +3423,12 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None):
inputs={'X': x, inputs={'X': x,
'Y': y}, 'Y': y},
outputs={'Out': out}, outputs={'Out': out},
attrs={'transpose_X': transpose_x, attrs={
'transpose_Y': transpose_y}) 'transpose_X': transpose_x,
'transpose_Y': transpose_y,
'scale': scale,
'bias': bias
})
return out return out
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册