未验证 提交 648f1d5b 编写于 作者: Y Yang Zhang 提交者: GitHub

API/OP error message enhancement (#23684)

* `l1_norm` error message enhancement

test=develop

* `norm` error message enhancement

test=develop

* `squared_l2_norm` error message enhancement

test=develop

* `squared_l2_distance` error message enhancement

test=develop

* `conv_shift_op` error message enhancement

test=develop

* `sample_logits_op` error message enhancement

test=develop

* Fix format

test=develop

* use `PADDLE_ENFORCE_EQ` for '||' conditional

test=develop

* Fix string format

test=develop

* Add test for `sample_logits`

test=develop

* Add error message

test=develop

* Use ordered dict for outputs

test=develop

* Hard code fetch list so that order is deterministic

test=develop

* Fix license header year

test=develop
上级 14e7041c
......@@ -29,25 +29,50 @@ class ConvShiftOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext *ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
PADDLE_ENFORCE(ctx->HasInput("Y"), "Input(Y) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"), "Output(Out) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "ConvShiftOp");
OP_INOUT_CHECK(ctx->HasInput("Y"), "Input", "Y", "ConvShiftOp");
OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "ConvShiftOp");
auto x_dims = ctx->GetInputDim("X");
auto y_dims = ctx->GetInputDim("Y");
PADDLE_ENFORCE_EQ(x_dims.size(), 2, "Input(X)'s rank should be 2.");
PADDLE_ENFORCE_EQ(y_dims.size(), 2, "Input(Y)'s rank should be 2.");
PADDLE_ENFORCE_EQ(
x_dims.size(), 2,
platform::errors::InvalidArgument(
"Input(X)'s dimensions of ConvShiftOp should be 2."
"But received X's shape = [%s] and the dimension is %d.",
x_dims, x_dims.size()));
PADDLE_ENFORCE_EQ(
y_dims.size(), 2,
platform::errors::InvalidArgument(
"Input(Y)'s dimensions of ConvShiftOp should be 2.",
"But received Y's shape = [%s] and the dimension is %d.", y_dims,
y_dims.size()));
if (ctx->IsRuntime() || (x_dims[0] > 0 && y_dims[0] > 0))
PADDLE_ENFORCE_EQ(x_dims[0], y_dims[0],
"The 1st dimension of Input(X) and Input(Y) should "
"be equal.");
PADDLE_ENFORCE_EQ(
x_dims[0], y_dims[0],
platform::errors::InvalidArgument(
"The first dimension of Input(X) and Input(Y) of ConvShiftOp ",
"should be equal.",
"But received X's shape = [%s], Y's shape = [%s],",
"and the first dimensions are %d and %d respectively.", x_dims,
y_dims, x_dims[0], y_dims[0]));
if (ctx->IsRuntime() || y_dims[1] > 0)
PADDLE_ENFORCE_EQ(y_dims[1] % 2, 1,
"The 2nd dimension of Input(Y) should be odd.");
PADDLE_ENFORCE_EQ(
y_dims[1] % 2, 1,
platform::errors::InvalidArgument(
"The second dimension of Input(Y) of ConvShiftOp should be odd."
"But received Y's shape = [%s] and the second dimension is %d.",
y_dims, y_dims[1]));
if (ctx->IsRuntime() || (x_dims[1] > 0 && y_dims[1] > 0))
PADDLE_ENFORCE_LE(y_dims[1], x_dims[1],
"The 2nd dimension of Input(Y) should be less than or "
"equal to the 2nd dimension of Input(X).");
PADDLE_ENFORCE_LE(
y_dims[1], x_dims[1],
platform::errors::InvalidArgument(
"The second dimension of Input(Y) of ConvShiftOp should be less "
"than or "
"equal to the 2nd dimension of Input(X)."
"But received X's shape = [%s], Y's shape = [%s],",
"and the second dimensions are %d and %d respectively.", x_dims,
y_dims, x_dims[1], y_dims[1]));
ctx->ShareDim("X", /*->*/ "Out");
ctx->ShareLoD("X", /*->*/ "Out");
}
......@@ -58,10 +83,10 @@ class ConvShiftGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext *ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
PADDLE_ENFORCE(ctx->HasInput("Y"), "Input(Y) should be not null.");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")),
"Input(Out@GRAD) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "ConvShiftGradOp");
OP_INOUT_CHECK(ctx->HasInput("Y"), "Input", "Y", "ConvShiftGradOp");
OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Out@GRAD", "ConvShiftGradOp");
auto x_grad_name = framework::GradVarName("X");
if (ctx->HasOutput(x_grad_name)) {
......
......@@ -25,8 +25,8 @@ class L1NormOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"), "Output(Out) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "L1NormOp");
OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "L1NormOp");
ctx->SetOutputDim("Out", {1});
}
......@@ -37,11 +37,11 @@ class L1NormGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")),
"Input(Out@GRAD) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")),
"Output(X@GRAD) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "L1NormGradOp");
OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Out@GRAD", "L1NormGradOp");
OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("X")), "Output",
"X@GRAD", "L1NormGradOp");
ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
}
......
......@@ -45,7 +45,10 @@ class L1NormGradKernel : public framework::OpKernel<T> {
const framework::Tensor *x = context.Input<framework::Tensor>("X");
const framework::Tensor *d_out =
context.Input<framework::Tensor>(framework::GradVarName("Out"));
PADDLE_ENFORCE(d_out->numel() == 1, "L1 Norm Gradient should be scalar");
PADDLE_ENFORCE_EQ(
d_out->numel(), 1,
platform::errors::InvalidArgument(
"Input(GRAD@Out) of L1NormGradOP should be a scalar."));
framework::Tensor *dx =
context.Output<framework::Tensor>(framework::GradVarName("X"));
dx->mutable_data<T>(context.GetPlace());
......
......@@ -55,10 +55,8 @@ class NormOp : public framework::OperatorWithKernel {
public:
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"),
"Input(X) of NormOp should not be null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of NormOp should not be null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "NormOp");
OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "NormOp");
auto xdim = ctx->GetInputDim("X");
ctx->SetOutputDim("Out", xdim);
int axis = ctx->Attrs().Get<int>("axis");
......@@ -72,9 +70,9 @@ class NormOpGrad : public framework::OperatorWithKernel {
public:
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) must not be null.");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")),
"Input(X@GRAD) should not be null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "NormOpGrad");
OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("X")), "Input",
"X@GRAD", "NormOpGrad");
ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
}
};
......
......@@ -112,32 +112,37 @@ class SampleLogitsOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("Logits"),
"Input(Logits) should be not null.");
PADDLE_ENFORCE(ctx->HasInput("Labels"),
"Input(Labels) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("Samples"),
"Output(Samples) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("Probabilities"),
"Output(Probabilities) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("SampledLogits"),
"Output(SampledLogits) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("SampledLabels"),
"Output(SampledLabels) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("LogitsDim"),
"Output(LogitsDim) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("LabelsDim"),
"Output(LabelsDim) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("Labels"), "Input", "Logits",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasInput("Labels"), "Input", "Logits",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasOutput("Samples"), "Output", "Samples",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasOutput("Probabilities"), "Output", "Probabilities",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasOutput("SampledLogits"), "Output", "SampledLogits",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasOutput("SampledLabels"), "Output", "SampledLabels",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasOutput("LogitsDim"), "Output", "LogitsDim",
"SampleLogitsOp");
OP_INOUT_CHECK(ctx->HasOutput("LabelsDim"), "Output", "LabelsDim",
"SampleLogitsOp");
auto logits_dims = ctx->GetInputDim("Logits");
auto labels_dims = ctx->GetInputDim("Labels");
PADDLE_ENFORCE_EQ(
logits_dims.size(), 2UL,
"The logits of softmax_with_cross_entropy should be a 2-D tensor.");
PADDLE_ENFORCE_EQ(logits_dims.size(), 2UL,
platform::errors::InvalidArgument(
"Input(Logits) of SampleLogitsOp should be 2D.",
"But received shape = [%s] and dimension is %d.",
logits_dims, logits_dims.size()));
PADDLE_ENFORCE_EQ(labels_dims.size(), 2UL,
"The labels should be a 2-D tensor.");
platform::errors::InvalidArgument(
"Input(Labels) of SampleLogitsOp should be 2D.",
"But received shape = [%s] and dimension is %d.",
labels_dims, labels_dims.size()));
const int num_samples = ctx->Attrs().Get<int>("num_samples");
int num_sampled_classes = labels_dims[1] + num_samples;
......@@ -175,25 +180,33 @@ class SampleLogitsOpGrad : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("LogitsDim"),
"Input(LogitsDim) should not be null.");
PADDLE_ENFORCE(ctx->HasInput("LabelsDim"),
"Input(LabelsDim) should be not null.");
PADDLE_ENFORCE(ctx->HasInput("Samples"),
"Input(Samples) should be not null.");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("SampledLogits")),
"Input(SampledLogits@Grad) should not be null.");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("Logits")),
"Output(Logits@Grad) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("LogitsDim"), "Input", "LogitsDim",
"SampleLogitsOpGrad");
OP_INOUT_CHECK(ctx->HasInput("LabelsDim"), "Input", "LabelsDim",
"SampleLogitsOpGrad");
OP_INOUT_CHECK(ctx->HasInput("Samples"), "Input", "SamplesabelsDim",
"SampleLogitsOpGrad");
OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("SampledLogits")),
"Input", "SampledLogits@GRAD", "SampleLogitsOpGrad");
OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("Logits")), "Output",
"Logits@GRAD", "SampleLogitsOpGrad");
auto logits_dims = ctx->GetInputDim("LogitsDim");
logits_dims = framework::DDim(logits_dims.Get(), logits_dims.size() - 1);
auto labels_dims = ctx->GetInputDim("LabelsDim");
labels_dims = framework::DDim(labels_dims.Get(), labels_dims.size() - 1);
PADDLE_ENFORCE_EQ(labels_dims.size(), 2UL,
"The label should be a 2-D tensor.");
PADDLE_ENFORCE_EQ(logits_dims.size(), 2UL,
"The logits should be a 2-D tensor.");
PADDLE_ENFORCE_EQ(
logits_dims.size(), 2UL,
platform::errors::InvalidArgument(
"Input(LogitsDim) of SampleLogitsOpGrad should be 2D.",
"But received shape = [%s] and dimension is %d.", logits_dims,
logits_dims.size()));
PADDLE_ENFORCE_EQ(
labels_dims.size(), 2UL,
platform::errors::InvalidArgument(
"Input(LabelsDim) of SampleLogitsOpGrad should be 2D.",
"But received shape = [%s] and dimension is %d.", labels_dims,
labels_dims.size()));
ctx->SetOutputDim(framework::GradVarName("Logits"), logits_dims);
}
......
......@@ -49,17 +49,37 @@ static void CPUTakeAlongD1(const platform::DeviceContext& ctx,
const framework::Tensor& array,
const framework::Tensor& index,
framework::Tensor* value) {
PADDLE_ENFORCE_EQ(platform::is_cpu_place(ctx.GetPlace()), true);
PADDLE_ENFORCE_EQ(
platform::is_cpu_place(ctx.GetPlace()), true,
platform::errors::InvalidArgument("This kernel only runs on CPU."));
// UNDERSTAND: check shape src(B, C), index(B, K), out should also be (B, K)
PADDLE_ENFORCE_EQ(index.dims().size(), 2);
PADDLE_ENFORCE_EQ(array.dims().size(), 2);
PADDLE_ENFORCE_EQ(index.dims()[0], array.dims()[0]);
PADDLE_ENFORCE_EQ(index.dims(), value->dims());
const auto batch_size = index.dims()[0];
const auto num_take = index.dims()[1];
const auto array_dims = array.dims();
const auto idx_dims = index.dims();
PADDLE_ENFORCE_EQ(idx_dims.size(), 2,
platform::errors::InvalidArgument(
"index of CPUTakeAlongD1 should be 2D.",
"But received shape = [%s] and dimension is %d.",
idx_dims, idx_dims.size()));
PADDLE_ENFORCE_EQ(array_dims.size(), 2,
platform::errors::InvalidArgument(
"array of CPUTakeAlongD1 should be 2D.",
"But received shape = [%s] and dimension is %d.",
array_dims, array_dims.size()));
PADDLE_ENFORCE_EQ(idx_dims[0], array_dims[0],
platform::errors::InvalidArgument(
"The first dimension of index and array of ",
"CPUTakeAlongD1 should be equal.",
"But received index shape = [%s], array shape = [%s],",
"and the first dimensions are %d and %d.", idx_dims,
array_dims, idx_dims[0], array_dims[0]));
PADDLE_ENFORCE_EQ(
idx_dims, value->dims(),
platform::errors::InvalidArgument(
"index and array of CPUTakeAlongD1 should have ", "the same shape.",
"But received index shape = [%s], array shape = [%s].", idx_dims,
value->dims()));
// UNDERSTAND: no allocations here
const T* p_array = array.data<T>();
......@@ -89,16 +109,37 @@ static void CPUPutAlongD1(const platform::DeviceContext& ctx,
framework::Tensor* array,
const framework::Tensor& index,
const framework::Tensor& value) {
PADDLE_ENFORCE_EQ(platform::is_cpu_place(ctx.GetPlace()), true);
PADDLE_ENFORCE_EQ(
platform::is_cpu_place(ctx.GetPlace()), true,
platform::errors::InvalidArgument("This kernel only runs on CPU."));
// UNDERSTAND: check shape src(B, C), index(B, K), out should also be (B, K)
PADDLE_ENFORCE_EQ(index.dims().size(), 2);
PADDLE_ENFORCE_EQ(array->dims().size(), 2);
PADDLE_ENFORCE_EQ(index.dims()[0], array->dims()[0]);
PADDLE_ENFORCE_EQ(index.dims(), value.dims());
const auto batch_size = index.dims()[0];
const auto num_put = index.dims()[1];
auto array_dims = array->dims();
auto idx_dims = index.dims();
PADDLE_ENFORCE_EQ(idx_dims.size(), 2,
platform::errors::InvalidArgument(
"index of CPUPutAlongD1 should be 2D.",
"But received shape = [%s] and dimension is %d.",
idx_dims, idx_dims.size()));
PADDLE_ENFORCE_EQ(array_dims.size(), 2,
platform::errors::InvalidArgument(
"array of CPUPutAlongD1 should be 2D.",
"But received shape = [%s] and dimension is %d.",
array_dims, array_dims.size()));
PADDLE_ENFORCE_EQ(idx_dims[0], array_dims[0],
platform::errors::InvalidArgument(
"The first dimension of index and array of ",
"CPUPutAlongD1 should be equal.",
"But received index shape = [%s], array shape = [%s],",
"and the first dimensions are %d and %d.", idx_dims,
array_dims, idx_dims[0], array_dims[0]));
PADDLE_ENFORCE_EQ(
idx_dims, value.dims(),
platform::errors::InvalidArgument(
"index and array of CPUPutAlongD1 should have ", "the same shape.",
"But received index shape = [%s], array shape = [%s].", idx_dims,
value.dims()));
// UNDERSTAND: no allocations here
T* p_array = array->data<T>();
......@@ -149,8 +190,9 @@ class SampleLogitsKernel : public framework::OpKernel<T> {
public:
using Tensor = framework::Tensor;
void Compute(const framework::ExecutionContext& context) const override {
PADDLE_ENFORCE_EQ(platform::is_cpu_place(context.GetPlace()), true,
"This kernel only runs on CPU.");
PADDLE_ENFORCE_EQ(
platform::is_cpu_place(context.GetPlace()), true,
platform::errors::InvalidArgument("this kernel only runs on cpu."));
VLOG(3) << "Enter SampleLogitsKernel";
// get necessary inputs
const Tensor* logits = context.Input<Tensor>("Logits");
......
......@@ -26,44 +26,59 @@ class SquaredL2DistanceOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"),
"Input(X) of SquaredL2DistanceOp should not be null.");
PADDLE_ENFORCE(ctx->HasInput("Y"),
"Input(Y) of SquaredL2DistanceOp should not be null.");
PADDLE_ENFORCE(
ctx->HasOutput("sub_result"),
"Output(sub_result) of SquaredL2DistanceOp should not be null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of SquaredL2DistanceOp should not be null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SquaredL2DistanceOp");
OP_INOUT_CHECK(ctx->HasInput("Y"), "Input", "Y", "SquaredL2DistanceOp");
OP_INOUT_CHECK(ctx->HasOutput("sub_result"), "Output", "sub_result",
"SquaredL2DistanceOp");
OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out",
"SquaredL2DistanceOp");
auto x_dims = ctx->GetInputDim("X");
auto y_dims = ctx->GetInputDim("Y");
PADDLE_ENFORCE_EQ(framework::arity(x_dims), framework::arity(y_dims),
"Tensor rank of both SquaredL2DistanceOp's "
"inputs must be same.");
PADDLE_ENFORCE_EQ(
framework::arity(x_dims), framework::arity(y_dims),
platform::errors::InvalidArgument(
"Input(X) and Input(X) of SquaredL2DistanceOp should ",
"have same dimensions.",
"But received X's shape = [%s] and Y's shape = [%s],",
"the dimensions are %d and %d respectively", x_dims, y_dims,
framework::arity(x_dims), framework::arity(y_dims)));
int rank = framework::arity(x_dims);
PADDLE_ENFORCE_GE(rank, 2, "Tensor rank should be at least equal to 2.");
PADDLE_ENFORCE_GE(
rank, 2,
platform::errors::InvalidArgument(
"Input dimensions of SquaredL2DistanceOp should be ", "at least 2.",
"But received shape = [%s] and dimension is %d.", x_dims, rank));
bool check = true;
if ((!ctx->IsRuntime()) &&
(framework::product(x_dims) <= 0 || framework::product(y_dims) <= 0)) {
check = false;
}
if (check) {
PADDLE_ENFORCE_EQ(product(x_dims) / x_dims[0],
product(y_dims) / y_dims[0],
"Product of dimensions expcet the first dimension of "
"input and target must be equal.");
PADDLE_ENFORCE_EQ(
product(x_dims) / x_dims[0], product(y_dims) / y_dims[0],
platform::errors::InvalidArgument(
"Input(X) and Input(Y) of SquaredL2DistanceOp should ",
"have same dimensions.",
"But received X's shape = [%s] and Y's shape = [%s]",
", the products are %d and %d respectively", x_dims, y_dims,
product(x_dims) / x_dims[0], product(y_dims) / y_dims[0]));
}
check = true;
if ((!ctx->IsRuntime()) && (y_dims[0] <= 0 || x_dims[0] <= 0)) {
check = false;
}
if (check) {
PADDLE_ENFORCE(y_dims[0] == 1 || y_dims[0] == x_dims[0],
"First dimension of target must be equal to input "
"or to 1.");
PADDLE_ENFORCE_EQ(
y_dims[0] == 1 || y_dims[0] == x_dims[0], true,
platform::errors::InvalidArgument(
"First dimension of Input(Y) of SquaredL2DistanceOp ",
"must be equal to 1", "or to first dimension of Input(X).",
"But received X's shape = [%s] and Y's shape = [%s],",
"the first dimensions are %d and %d respectively", x_dims, y_dims,
x_dims[0], y_dims[0]));
}
ctx->SetOutputDim("sub_result", {x_dims[0], product(x_dims) / x_dims[0]});
ctx->SetOutputDim("Out", {x_dims[0], 1});
......@@ -126,19 +141,28 @@ class SquaredL2DistanceGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")),
"Gradient of Out should not be null");
PADDLE_ENFORCE(ctx->HasInput("sub_result"), "SubResult should not be null");
OP_INOUT_CHECK(ctx->HasInput("sub_result"), "Input", "sub_result",
"SquaredL2DistanceGradOp");
OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Out@GRAD", "SquaredL2DistanceGradOp");
auto out_dims = ctx->GetInputDim(framework::GradVarName("Out"));
auto x_dims = ctx->GetInputDim("X");
auto y_dims = ctx->GetInputDim("Y");
if (ctx->IsRuntime()) {
PADDLE_ENFORCE_EQ(out_dims[0], x_dims[0],
"First dimension of output gradient and "
"input value must be equal.");
PADDLE_ENFORCE_EQ(
out_dims[0], x_dims[0],
platform::errors::InvalidArgument(
"First dimension of output gradient and Input(X) ",
"of SquaredL2DistanceGradOp must be equal",
"But received X's shape = [%s] and grad's shape = [%s],",
"the first dimensions are %d and %d respectively", x_dims,
out_dims, x_dims[0], out_dims[0]));
PADDLE_ENFORCE_EQ(out_dims[1], 1,
"Second dimension of output gradient "
"must be 1.");
platform::errors::InvalidArgument(
"Second dimension of output gradient of ",
"SquaredL2DistanceGradOp must be 1."
"But received grad's shape = [%s],",
"with first dimensions %d", out_dims, out_dims[1]));
}
auto x_grad_name = framework::GradVarName("X");
auto y_grad_name = framework::GradVarName("Y");
......
......@@ -26,8 +26,8 @@ class SquaredL2NormOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"), "Output(Out) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SquaredL2NormOp");
OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "SquaredL2NormOp");
ctx->SetOutputDim("Out", {1});
}
......@@ -56,11 +56,11 @@ class SquaredL2NormGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")),
"Input(Out@GRAD) should be not null.");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")),
"Output(X@GRAD) should be not null.");
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SquaredL2NormGradOp");
OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Out@GRAD", "SquaredL2NormGradOp");
OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("X")), "Output",
"X@GRAD", "SquaredL2NormGradOp");
ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
}
......
......@@ -45,8 +45,10 @@ class SquaredL2NormGradKernel : public framework::OpKernel<T> {
const framework::Tensor *X = context.Input<framework::Tensor>("X");
const framework::Tensor *dOut =
context.Input<framework::Tensor>(framework::GradVarName("Out"));
PADDLE_ENFORCE(dOut->numel() == 1,
"Squared L2 Norm Gradient should be scalar");
PADDLE_ENFORCE_EQ(
dOut->numel(), 1,
platform::errors::InvalidArgument(
"Input(GRAD@Out) of SquaredL2NormGradOP should be a scalar."));
framework::Tensor *dX =
context.Output<framework::Tensor>(framework::GradVarName("X"));
dX->mutable_data<T>(context.GetPlace());
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import collections
import numpy as np
from op_test import OpTest
class TestSampleLogitsOp(OpTest):
def setUp(self):
self.op_type = "sample_logits"
self.dtype = np.float64
self.use_mkldnn = False
bs = 2
K = 20
NT = 10
S = 5
Samples = np.random.random([bs, NT + S]).astype('int64')
Probabilities = np.random.random([bs, NT + S]).astype('float64')
LogitsDim = np.array([bs, K], dtype=np.int64)
LabelsDim = np.array([bs, NT], dtype=np.int64)
SampledLogits = np.random.random([bs, NT + S]).astype('float64')
SampledLabels = np.random.random([bs, NT]).astype('int64')
self.bs = bs
self.K = K
self.NT = NT
self.S = S
Labels = np.array(list(range(self.NT)) * self.bs).astype('int64')
self.Labels = Labels.reshape(self.bs, -1)
self.Logits = np.random.random([self.bs, self.K]).astype('float64')
self.inputs = {"Logits": self.Logits, "Labels": self.Labels}
self.fetch_list = [
'Samples', 'Probabilities', 'SampledLogits', 'SampledLabels'
]
self.outputs = collections.OrderedDict(
(('Samples', Samples), ('Probabilities', Probabilities),
('LogitsDim', LogitsDim), ('LabelsDim', LabelsDim),
('SampledLogits', SampledLogits), ('SampledLabels',
SampledLabels)))
self.attrs = {'num_samples': self.S}
def test_check_output(self):
places = self._get_places()
for p in places:
(Samples, Probabilities, SampledLogits,
SampledLabels) = [np.array(o) for o in self.calc_output(p)]
assert Samples.dtype == np.int64, \
"Samples dtype is {}, not int64".format(Samples.dtype)
assert Probabilities.dtype == np.float64, \
"Probabilities dtype is {}, not float64".format(
Probabilities.dtype)
assert SampledLogits.dtype == np.float64, \
"SampledLogits dtype is {}, not float64".format(
SampledLogits.dtype)
assert SampledLabels.dtype == np.int64, \
"SampledLabels dtype is {}, not int64".format(
SampledLabels.dtype)
assert Samples.shape == (self.bs, self.NT + self.S)
assert Probabilities.shape == (self.bs, self.NT + self.S)
assert SampledLogits.shape == (self.bs, self.NT + self.S)
assert SampledLabels.shape == (self.bs, self.NT)
assert (SampledLabels == self.Labels).all()
sampled_logits = self.Logits[:, Samples[0][:self.NT]]
sampled_logits -= np.log(Probabilities[:, :self.NT])
np.testing.assert_almost_equal(sampled_logits,
SampledLogits[:, :self.NT])
def test_check_grad(self):
self._check_grad_helper()
for p in self._get_places():
grads = self._get_gradient(['Logits'], p, ['SampledLogits'], [])
np.testing.assert_almost_equal(grads[0].sum(), np.array([1.]))
class TestSampleLogitsOpNoUniq(TestSampleLogitsOp):
def setUp(self):
super(TestSampleLogitsOpNoUniq, self).setUp()
self.attrs = {'num_samples': self.S, 'uniq': False}
class TestSampleLogitsOpWithAccidentalHits(TestSampleLogitsOp):
def setUp(self):
super(TestSampleLogitsOpWithAccidentalHits, self).setUp()
self.attrs = {'num_samples': self.S, 'remove_accidental_hits': False}
if __name__ == "__main__":
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册