|
|
|
@ -30,7 +30,7 @@ class LoDResetOp : public framework::OperatorWithKernel {
|
|
|
|
if (!ctx->HasInput("Y")) {
|
|
|
|
if (!ctx->HasInput("Y")) {
|
|
|
|
auto level0 = ctx->Attrs().Get<std::vector<int>>("target_lod");
|
|
|
|
auto level0 = ctx->Attrs().Get<std::vector<int>>("target_lod");
|
|
|
|
PADDLE_ENFORCE_GT(level0.size(), 1,
|
|
|
|
PADDLE_ENFORCE_GT(level0.size(), 1,
|
|
|
|
"If Input(Y) is not provided, the target lod should be "
|
|
|
|
"If Input(Y) not provided, the target lod should be "
|
|
|
|
"specified by attribute `target_lod`.");
|
|
|
|
"specified by attribute `target_lod`.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
|
|
|
|
ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
|
|
|
|
@ -54,9 +54,10 @@ class LoDResetOpMaker : public framework::OpProtoAndCheckerMaker {
|
|
|
|
"could be a Tensor or LoDTensor, where the data of output "
|
|
|
|
"could be a Tensor or LoDTensor, where the data of output "
|
|
|
|
"variable inherits from.");
|
|
|
|
"variable inherits from.");
|
|
|
|
AddInput("Y",
|
|
|
|
AddInput("Y",
|
|
|
|
"(Tensor, LoDTensor, optional) If provided, lod of Input(Y) would "
|
|
|
|
"(Tensor, LoDTensor, optional) If provided and Y is LoDTensor, "
|
|
|
|
"be considered as the target lod first, otherwise data of "
|
|
|
|
"lod of Input(Y) would be considered as the target lod first, "
|
|
|
|
"Input(Y) would be considered as the target lod.")
|
|
|
|
"otherwise data of Input(Y) would be considered as the "
|
|
|
|
|
|
|
|
"target lod.")
|
|
|
|
.AsDispensable();
|
|
|
|
.AsDispensable();
|
|
|
|
AddOutput("Out",
|
|
|
|
AddOutput("Out",
|
|
|
|
"(LoDTensor) Output variable of LoDResetOp which should be a "
|
|
|
|
"(LoDTensor) Output variable of LoDResetOp which should be a "
|
|
|
|
@ -67,25 +68,59 @@ class LoDResetOpMaker : public framework::OpProtoAndCheckerMaker {
|
|
|
|
AddComment(R"DOC(LoDReset operator
|
|
|
|
AddComment(R"DOC(LoDReset operator
|
|
|
|
|
|
|
|
|
|
|
|
Set LoD of `X` to a new one specified by `Y` or attribute `target_lod`. When `Y`
|
|
|
|
Set LoD of `X` to a new one specified by `Y` or attribute `target_lod`. When `Y`
|
|
|
|
provided, `Y.lod` would be considered as target LoD first, otherwise `Y.data`
|
|
|
|
provided and `Y` is a LoDTensor, `Y.lod` would be considered as target LoD
|
|
|
|
would be considered as target LoD. If `Y` is not provided, target LoD should be
|
|
|
|
first, otherwise `Y.data` would be considered as target LoD. If `Y` is not
|
|
|
|
specified by attribute `target_lod`. If target LoD is specified by `Y.data` or
|
|
|
|
provided, target LoD should be specified by attribute `target_lod`.
|
|
|
|
`target_lod`, only one level LoD is supported.
|
|
|
|
If target LoD is specified by `Y.data` or `target_lod`, only one level LoD
|
|
|
|
|
|
|
|
is supported.
|
|
|
|
|
|
|
|
|
|
|
|
An example:
|
|
|
|
Example 1:
|
|
|
|
|
|
|
|
|
|
|
|
Given a 1-level LoDTensor input(X)
|
|
|
|
Given a 1-level LoDTensor input(X):
|
|
|
|
X.lod = [[ 0, 2, 5 6 ]]
|
|
|
|
X.lod = [[ 0, 2, 5 6 ]]
|
|
|
|
X.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
X.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
X.dims = [6, 1]
|
|
|
|
X.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
target_lod: [0, 4, 6]
|
|
|
|
attr(target_lod): [0, 4, 6]
|
|
|
|
|
|
|
|
|
|
|
|
then we get an 1-level LoDTensor
|
|
|
|
then we get a 1-level LoDTensor:
|
|
|
|
Out.lod = [[ 0, 4, 6 ]]
|
|
|
|
Out.lod = [[ 0, 4, 6 ]]
|
|
|
|
Out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
Out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
Out.dims = [6, 1]
|
|
|
|
Out.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example 2:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Given a 1-level LoDTensor input(X):
|
|
|
|
|
|
|
|
X.lod = [[ 0, 2, 5 6 ]]
|
|
|
|
|
|
|
|
X.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
|
|
|
|
X.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
input(Y) is a Tensor:
|
|
|
|
|
|
|
|
Y.data = [[0, 2, 6]]
|
|
|
|
|
|
|
|
Y.dims = [1, 3]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
then we get a 1-level LoDTensor:
|
|
|
|
|
|
|
|
Out.lod = [[ 0, 2, 6 ]]
|
|
|
|
|
|
|
|
Out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
|
|
|
|
Out.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example 3:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Given a 1-level LoDTensor input(X):
|
|
|
|
|
|
|
|
X.lod = [[ 0, 2, 5 6 ]]
|
|
|
|
|
|
|
|
X.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
|
|
|
|
X.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
input(Y) is a 2-level LoDTensor:
|
|
|
|
|
|
|
|
Y.lod = [[0, 2, 4], [0, 2, 5, 6]]
|
|
|
|
|
|
|
|
Y.data = [[1.1], [2.1], [3.1], [4.1], [5.1], [6.1]]
|
|
|
|
|
|
|
|
Y.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
then we get a 2-level LoDTensor:
|
|
|
|
|
|
|
|
Out.lod = [[0, 2, 4], [0, 2, 5, 6]]
|
|
|
|
|
|
|
|
Out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
|
|
|
|
|
|
|
|
Out.dims = [6, 1]
|
|
|
|
|
|
|
|
|
|
|
|
)DOC");
|
|
|
|
)DOC");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|