未验证 提交 91fb0156 编写于 作者: D dzhwinter 提交者: GitHub

Memory/reshape op (#12414)

* "remove inplace in single op"

* "fix ci"

* "add transpiler case"

* fix conflict

* "fix reshape"

* "delete reshape inplace attr"

* "follo the comments"

* "rerun ci"
上级 97513451
...@@ -127,12 +127,6 @@ class ReshapeOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -127,12 +127,6 @@ class ReshapeOpMaker : public framework::OpProtoAndCheckerMaker {
AddOutput("Out", "(Tensor). The output tensor of reshape operator."); AddOutput("Out", "(Tensor). The output tensor of reshape operator.");
AddAttr<std::vector<int>>( AddAttr<std::vector<int>>(
"shape", "(std::vector<int>) Target shape of reshape operator."); "shape", "(std::vector<int>) Target shape of reshape operator.");
AddAttr<bool>("inplace",
"(default: false) Change the source tensor's shape without "
"memory copy. When Attr(inplace) is set true, the output "
"tensor shares memory with Input(X), otherwise, a new output "
"tensor is created, and its data are copied from Input(x).")
.SetDefault(false);
AddComment(R"DOC( AddComment(R"DOC(
Reshape Operator. Reshape Operator.
...@@ -233,16 +227,9 @@ class ReshapeKernel { ...@@ -233,16 +227,9 @@ class ReshapeKernel {
"sequence_reshape op."); "sequence_reshape op.");
} }
bool inplace = ctx.Attr<bool>("inplace"); out->mutable_data(ctx.GetPlace(), in->type());
framework::TensorCopySync(*in, ctx.GetPlace(), out);
out->Resize(out_dims); out->Resize(out_dims);
if (!inplace) {
out->mutable_data(ctx.GetPlace(), in->type());
framework::TensorCopySync(*in, ctx.GetPlace(), out);
out->Resize(out_dims);
} else {
out->ShareDataWith(*in);
out->Resize(out_dims);
}
} }
}; };
...@@ -251,19 +238,11 @@ class ReshapeGradKernel { ...@@ -251,19 +238,11 @@ class ReshapeGradKernel {
void operator()(const framework::ExecutionContext &ctx) const { void operator()(const framework::ExecutionContext &ctx) const {
auto *d_out = ctx.Input<framework::Tensor>(framework::GradVarName("Out")); auto *d_out = ctx.Input<framework::Tensor>(framework::GradVarName("Out"));
auto *d_x = ctx.Output<framework::Tensor>(framework::GradVarName("X")); auto *d_x = ctx.Output<framework::Tensor>(framework::GradVarName("X"));
auto in_dims = d_x->dims();
d_x->mutable_data(ctx.GetPlace(), d_out->type()); d_x->mutable_data(ctx.GetPlace(), d_out->type());
bool inplace = ctx.Attr<bool>("inplace"); framework::TensorCopySync(*d_out, ctx.GetPlace(), d_x);
d_x->Resize(in_dims);
auto in_dims = d_x->dims();
if (!inplace) {
framework::TensorCopy(*d_out, ctx.GetPlace(), ctx.device_context(), d_x);
ctx.device_context().Wait();
d_x->Resize(in_dims);
} else {
d_x->ShareDataWith(*d_out);
d_x->Resize(in_dims);
}
} }
}; };
......
...@@ -4473,15 +4473,14 @@ def reshape(x, shape, actual_shape=None, act=None, inplace=True, name=None): ...@@ -4473,15 +4473,14 @@ def reshape(x, shape, actual_shape=None, act=None, inplace=True, name=None):
"except one unknown dimension.") "except one unknown dimension.")
helper = LayerHelper("reshape", **locals()) helper = LayerHelper("reshape", **locals())
reshaped = helper.create_tmp_variable(dtype=x.dtype) out = helper.create_tmp_variable(dtype=x.dtype)
helper.append_op( helper.append_op(
type="reshape", type="reshape",
inputs=inputs, inputs=inputs,
attrs={"shape": shape, attrs={"shape": shape},
"inplace": inplace}, outputs={"Out": out})
outputs={"Out": reshaped})
return helper.append_activation(reshaped) return helper.append_activation(out)
def lod_reset(x, y=None, target_lod=None): def lod_reset(x, y=None, target_lod=None):
......
...@@ -43,5 +43,29 @@ class TestControlFlowGraph(unittest.TestCase): ...@@ -43,5 +43,29 @@ class TestControlFlowGraph(unittest.TestCase):
print(str(result_program)) print(str(result_program))
class TestMemoryTranspiler2(unittest.TestCase):
def setUp(self):
program = Program()
with program_guard(program, startup_program=Program()):
x = layers.data(name='x', shape=[13], dtype='float32')
fc = layers.fc(input=x, size=10, act=None)
reshape = layers.reshape(x=fc, shape=[-1, 2, 5])
fc = layers.reshape(x=reshape, shape=[-1, 5, 2])
y_predict = layers.fc(input=fc, size=1, act=None)
y = layers.data(name='y', shape=[1], dtype='float32')
cost = layers.square_error_cost(input=y_predict, label=y)
avg_cost = layers.mean(cost)
opt = optimizer.SGD(learning_rate=0.001)
opt.minimize(avg_cost)
self.program = program
def test_inplace_ops(self):
print("before optimization")
print(str(self.program))
result_program = memory_optimize(self.program)
print("after optimization")
print(str(result_program))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
...@@ -25,7 +25,7 @@ class TestReshapeOp(OpTest): ...@@ -25,7 +25,7 @@ class TestReshapeOp(OpTest):
self.op_type = "reshape" self.op_type = "reshape"
self.inputs = {"X": np.random.random(ori_shape).astype("float32")} self.inputs = {"X": np.random.random(ori_shape).astype("float32")}
self.attrs = {"shape": new_shape, "inplace": False} self.attrs = {"shape": new_shape}
self.outputs = {"Out": self.inputs["X"].reshape(new_shape)} self.outputs = {"Out": self.inputs["X"].reshape(new_shape)}
def test_check_output(self): def test_check_output(self):
...@@ -42,7 +42,7 @@ class TestReshapeOpDimInfer1(OpTest): ...@@ -42,7 +42,7 @@ class TestReshapeOpDimInfer1(OpTest):
self.op_type = "reshape" self.op_type = "reshape"
self.inputs = {"X": np.random.random(ori_shape).astype("float32")} self.inputs = {"X": np.random.random(ori_shape).astype("float32")}
self.attrs = {"shape": new_shape, "inplace": False} self.attrs = {"shape": new_shape}
self.outputs = {"Out": self.inputs["X"].reshape(self.attrs["shape"])} self.outputs = {"Out": self.inputs["X"].reshape(self.attrs["shape"])}
def test_check_output(self): def test_check_output(self):
...@@ -60,7 +60,7 @@ class TestReshapeOpDimInfer2(OpTest): ...@@ -60,7 +60,7 @@ class TestReshapeOpDimInfer2(OpTest):
self.op_type = "reshape" self.op_type = "reshape"
self.inputs = {"X": np.random.random(ori_shape).astype("float32")} self.inputs = {"X": np.random.random(ori_shape).astype("float32")}
self.attrs = {"shape": new_shape, "inplace": False} self.attrs = {"shape": new_shape}
self.outputs = {"Out": self.inputs["X"].reshape(infered_shape)} self.outputs = {"Out": self.inputs["X"].reshape(infered_shape)}
def test_check_output(self): def test_check_output(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册