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

Refine error message for some ops (#24479)

test=release/1.8

l1_norm
norm
squared_l2_norm
squared_l2_distance
conv_shift
sample_logits
上级 db8f4082
...@@ -29,25 +29,49 @@ class ConvShiftOp : public framework::OperatorWithKernel { ...@@ -29,25 +29,49 @@ class ConvShiftOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext *ctx) const override { void InferShape(framework::InferShapeContext *ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "ConvShiftOp");
PADDLE_ENFORCE(ctx->HasInput("Y"), "Input(Y) should be not null."); OP_INOUT_CHECK(ctx->HasInput("Y"), "Input", "Y", "ConvShiftOp");
PADDLE_ENFORCE(ctx->HasOutput("Out"), "Output(Out) should be not null."); OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "ConvShiftOp");
auto x_dims = ctx->GetInputDim("X"); auto x_dims = ctx->GetInputDim("X");
auto y_dims = ctx->GetInputDim("Y"); auto y_dims = ctx->GetInputDim("Y");
PADDLE_ENFORCE_EQ(x_dims.size(), 2, "Input(X)'s rank should be 2."); PADDLE_ENFORCE_EQ(
PADDLE_ENFORCE_EQ(y_dims.size(), 2, "Input(Y)'s rank should be 2."); 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)) if (ctx->IsRuntime() || (x_dims[0] > 0 && y_dims[0] > 0))
PADDLE_ENFORCE_EQ(x_dims[0], y_dims[0], PADDLE_ENFORCE_EQ(
"The 1st dimension of Input(X) and Input(Y) should " x_dims[0], y_dims[0],
"be equal."); 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) if (ctx->IsRuntime() || y_dims[1] > 0)
PADDLE_ENFORCE_EQ(y_dims[1] % 2, 1, PADDLE_ENFORCE_EQ(
"The 2nd dimension of Input(Y) should be odd."); 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)) if (ctx->IsRuntime() || (x_dims[1] > 0 && y_dims[1] > 0))
PADDLE_ENFORCE_LE(y_dims[1], x_dims[1], PADDLE_ENFORCE_LE(
"The 2nd dimension of Input(Y) should be less than or " y_dims[1], x_dims[1],
"equal to the 2nd dimension of Input(X)."); 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->ShareDim("X", /*->*/ "Out");
ctx->ShareLoD("X", /*->*/ "Out"); ctx->ShareLoD("X", /*->*/ "Out");
} }
...@@ -58,10 +82,10 @@ class ConvShiftGradOp : public framework::OperatorWithKernel { ...@@ -58,10 +82,10 @@ class ConvShiftGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext *ctx) const override { void InferShape(framework::InferShapeContext *ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "ConvShiftGradOp");
PADDLE_ENFORCE(ctx->HasInput("Y"), "Input(Y) should be not null."); OP_INOUT_CHECK(ctx->HasInput("Y"), "Input", "Y", "ConvShiftGradOp");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")), OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Input(Out@GRAD) should be not null."); "Out@GRAD", "ConvShiftGradOp");
auto x_grad_name = framework::GradVarName("X"); auto x_grad_name = framework::GradVarName("X");
if (ctx->HasOutput(x_grad_name)) { if (ctx->HasOutput(x_grad_name)) {
......
...@@ -25,8 +25,8 @@ class L1NormOp : public framework::OperatorWithKernel { ...@@ -25,8 +25,8 @@ class L1NormOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "L1NormOp");
PADDLE_ENFORCE(ctx->HasOutput("Out"), "Output(Out) should be not null."); OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "L1NormOp");
ctx->SetOutputDim("Out", {1}); ctx->SetOutputDim("Out", {1});
} }
...@@ -37,11 +37,11 @@ class L1NormGradOp : public framework::OperatorWithKernel { ...@@ -37,11 +37,11 @@ class L1NormGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "L1NormGradOp");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")), OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Input(Out@GRAD) should be not null."); "Out@GRAD", "L1NormGradOp");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")), OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("X")), "Output",
"Output(X@GRAD) should be not null."); "X@GRAD", "L1NormGradOp");
ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X")); ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
} }
......
...@@ -45,7 +45,10 @@ class L1NormGradKernel : public framework::OpKernel<T> { ...@@ -45,7 +45,10 @@ class L1NormGradKernel : public framework::OpKernel<T> {
const framework::Tensor *x = context.Input<framework::Tensor>("X"); const framework::Tensor *x = context.Input<framework::Tensor>("X");
const framework::Tensor *d_out = const framework::Tensor *d_out =
context.Input<framework::Tensor>(framework::GradVarName("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 = framework::Tensor *dx =
context.Output<framework::Tensor>(framework::GradVarName("X")); context.Output<framework::Tensor>(framework::GradVarName("X"));
dx->mutable_data<T>(context.GetPlace()); dx->mutable_data<T>(context.GetPlace());
......
...@@ -55,10 +55,8 @@ class NormOp : public framework::OperatorWithKernel { ...@@ -55,10 +55,8 @@ class NormOp : public framework::OperatorWithKernel {
public: public:
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "NormOp");
"Input(X) of NormOp should not be null."); OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "NormOp");
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of NormOp should not be null.");
auto xdim = ctx->GetInputDim("X"); auto xdim = ctx->GetInputDim("X");
ctx->SetOutputDim("Out", xdim); ctx->SetOutputDim("Out", xdim);
int axis = ctx->Attrs().Get<int>("axis"); int axis = ctx->Attrs().Get<int>("axis");
...@@ -72,9 +70,9 @@ class NormOpGrad : public framework::OperatorWithKernel { ...@@ -72,9 +70,9 @@ class NormOpGrad : public framework::OperatorWithKernel {
public: public:
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) must not be null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "NormOpGrad");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")), OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("X")), "Input",
"Input(X@GRAD) should not be null."); "X@GRAD", "NormOpGrad");
ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X")); ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
} }
}; };
......
...@@ -112,32 +112,37 @@ class SampleLogitsOp : public framework::OperatorWithKernel { ...@@ -112,32 +112,37 @@ class SampleLogitsOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("Logits"), OP_INOUT_CHECK(ctx->HasInput("Labels"), "Input", "Logits",
"Input(Logits) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasInput("Labels"), OP_INOUT_CHECK(ctx->HasInput("Labels"), "Input", "Logits",
"Input(Labels) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasOutput("Samples"), OP_INOUT_CHECK(ctx->HasOutput("Samples"), "Output", "Samples",
"Output(Samples) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasOutput("Probabilities"), OP_INOUT_CHECK(ctx->HasOutput("Probabilities"), "Output", "Probabilities",
"Output(Probabilities) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasOutput("SampledLogits"), OP_INOUT_CHECK(ctx->HasOutput("SampledLogits"), "Output", "SampledLogits",
"Output(SampledLogits) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasOutput("SampledLabels"), OP_INOUT_CHECK(ctx->HasOutput("SampledLabels"), "Output", "SampledLabels",
"Output(SampledLabels) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasOutput("LogitsDim"), OP_INOUT_CHECK(ctx->HasOutput("LogitsDim"), "Output", "LogitsDim",
"Output(LogitsDim) should be not null."); "SampleLogitsOp");
PADDLE_ENFORCE(ctx->HasOutput("LabelsDim"), OP_INOUT_CHECK(ctx->HasOutput("LabelsDim"), "Output", "LabelsDim",
"Output(LabelsDim) should be not null."); "SampleLogitsOp");
auto logits_dims = ctx->GetInputDim("Logits"); auto logits_dims = ctx->GetInputDim("Logits");
auto labels_dims = ctx->GetInputDim("Labels"); auto labels_dims = ctx->GetInputDim("Labels");
PADDLE_ENFORCE_EQ( PADDLE_ENFORCE_EQ(logits_dims.size(), 2UL,
logits_dims.size(), 2UL, platform::errors::InvalidArgument(
"The logits of softmax_with_cross_entropy should be a 2-D tensor."); "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, 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"); const int num_samples = ctx->Attrs().Get<int>("num_samples");
int num_sampled_classes = labels_dims[1] + num_samples; int num_sampled_classes = labels_dims[1] + num_samples;
...@@ -175,25 +180,33 @@ class SampleLogitsOpGrad : public framework::OperatorWithKernel { ...@@ -175,25 +180,33 @@ class SampleLogitsOpGrad : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("LogitsDim"), OP_INOUT_CHECK(ctx->HasInput("LogitsDim"), "Input", "LogitsDim",
"Input(LogitsDim) should not be null."); "SampleLogitsOpGrad");
PADDLE_ENFORCE(ctx->HasInput("LabelsDim"), OP_INOUT_CHECK(ctx->HasInput("LabelsDim"), "Input", "LabelsDim",
"Input(LabelsDim) should be not null."); "SampleLogitsOpGrad");
PADDLE_ENFORCE(ctx->HasInput("Samples"), OP_INOUT_CHECK(ctx->HasInput("Samples"), "Input", "SamplesabelsDim",
"Input(Samples) should be not null."); "SampleLogitsOpGrad");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("SampledLogits")), OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("SampledLogits")),
"Input(SampledLogits@Grad) should not be null."); "Input", "SampledLogits@GRAD", "SampleLogitsOpGrad");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("Logits")), OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("Logits")), "Output",
"Output(Logits@Grad) should be not null."); "Logits@GRAD", "SampleLogitsOpGrad");
auto logits_dims = ctx->GetInputDim("LogitsDim"); auto logits_dims = ctx->GetInputDim("LogitsDim");
logits_dims = framework::DDim(logits_dims.Get(), logits_dims.size() - 1); logits_dims = framework::DDim(logits_dims.Get(), logits_dims.size() - 1);
auto labels_dims = ctx->GetInputDim("LabelsDim"); auto labels_dims = ctx->GetInputDim("LabelsDim");
labels_dims = framework::DDim(labels_dims.Get(), labels_dims.size() - 1); labels_dims = framework::DDim(labels_dims.Get(), labels_dims.size() - 1);
PADDLE_ENFORCE_EQ(labels_dims.size(), 2UL, PADDLE_ENFORCE_EQ(
"The label should be a 2-D tensor."); logits_dims.size(), 2UL,
PADDLE_ENFORCE_EQ(logits_dims.size(), 2UL, platform::errors::InvalidArgument(
"The logits should be a 2-D tensor."); "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); ctx->SetOutputDim(framework::GradVarName("Logits"), logits_dims);
} }
......
...@@ -49,17 +49,37 @@ static void CPUTakeAlongD1(const platform::DeviceContext& ctx, ...@@ -49,17 +49,37 @@ static void CPUTakeAlongD1(const platform::DeviceContext& ctx,
const framework::Tensor& array, const framework::Tensor& array,
const framework::Tensor& index, const framework::Tensor& index,
framework::Tensor* value) { 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) // 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 batch_size = index.dims()[0];
const auto num_take = index.dims()[1]; const auto num_take = index.dims()[1];
const auto array_dims = array.dims(); const auto array_dims = array.dims();
const auto idx_dims = index.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 // UNDERSTAND: no allocations here
const T* p_array = array.data<T>(); const T* p_array = array.data<T>();
...@@ -89,16 +109,37 @@ static void CPUPutAlongD1(const platform::DeviceContext& ctx, ...@@ -89,16 +109,37 @@ static void CPUPutAlongD1(const platform::DeviceContext& ctx,
framework::Tensor* array, framework::Tensor* array,
const framework::Tensor& index, const framework::Tensor& index,
const framework::Tensor& value) { 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) // 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 batch_size = index.dims()[0];
const auto num_put = index.dims()[1]; const auto num_put = index.dims()[1];
auto array_dims = array->dims(); auto array_dims = array->dims();
auto idx_dims = index.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 // UNDERSTAND: no allocations here
T* p_array = array->data<T>(); T* p_array = array->data<T>();
...@@ -149,8 +190,9 @@ class SampleLogitsKernel : public framework::OpKernel<T> { ...@@ -149,8 +190,9 @@ class SampleLogitsKernel : public framework::OpKernel<T> {
public: public:
using Tensor = framework::Tensor; using Tensor = framework::Tensor;
void Compute(const framework::ExecutionContext& context) const override { void Compute(const framework::ExecutionContext& context) const override {
PADDLE_ENFORCE_EQ(platform::is_cpu_place(context.GetPlace()), true, PADDLE_ENFORCE_EQ(
"This kernel only runs on CPU."); platform::is_cpu_place(context.GetPlace()), true,
platform::errors::InvalidArgument("this kernel only runs on cpu."));
VLOG(3) << "Enter SampleLogitsKernel"; VLOG(3) << "Enter SampleLogitsKernel";
// get necessary inputs // get necessary inputs
const Tensor* logits = context.Input<Tensor>("Logits"); const Tensor* logits = context.Input<Tensor>("Logits");
......
...@@ -26,44 +26,61 @@ class SquaredL2DistanceOp : public framework::OperatorWithKernel { ...@@ -26,44 +26,61 @@ class SquaredL2DistanceOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SquaredL2DistanceOp");
"Input(X) of SquaredL2DistanceOp should not be null."); OP_INOUT_CHECK(ctx->HasInput("Y"), "Input", "Y", "SquaredL2DistanceOp");
PADDLE_ENFORCE(ctx->HasInput("Y"), OP_INOUT_CHECK(ctx->HasOutput("sub_result"), "Output", "sub_result",
"Input(Y) of SquaredL2DistanceOp should not be null."); "SquaredL2DistanceOp");
PADDLE_ENFORCE( OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out",
ctx->HasOutput("sub_result"), "SquaredL2DistanceOp");
"Output(sub_result) of SquaredL2DistanceOp should not be null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of SquaredL2DistanceOp should not be null.");
auto x_dims = ctx->GetInputDim("X"); auto x_dims = ctx->GetInputDim("X");
auto y_dims = ctx->GetInputDim("Y"); auto y_dims = ctx->GetInputDim("Y");
PADDLE_ENFORCE_EQ(framework::arity(x_dims), framework::arity(y_dims), PADDLE_ENFORCE_EQ(framework::arity(x_dims), framework::arity(y_dims),
"Tensor rank of both SquaredL2DistanceOp's " platform::errors::InvalidArgument(
"inputs must be same."); "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); 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; bool check = true;
if ((!ctx->IsRuntime()) && if ((!ctx->IsRuntime()) &&
(framework::product(x_dims) <= 0 || framework::product(y_dims) <= 0)) { (framework::product(x_dims) <= 0 || framework::product(y_dims) <= 0)) {
check = false; check = false;
} }
if (check) { if (check) {
PADDLE_ENFORCE_EQ(product(x_dims) / x_dims[0], PADDLE_ENFORCE_EQ(
product(y_dims) / y_dims[0], product(x_dims) / x_dims[0], product(y_dims) / y_dims[0],
"Product of dimensions expcet the first dimension of " platform::errors::InvalidArgument(
"input and target must be equal."); "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; check = true;
if ((!ctx->IsRuntime()) && (y_dims[0] <= 0 || x_dims[0] <= 0)) { if ((!ctx->IsRuntime()) && (y_dims[0] <= 0 || x_dims[0] <= 0)) {
check = false; check = false;
} }
if (check) { if (check) {
PADDLE_ENFORCE(y_dims[0] == 1 || y_dims[0] == x_dims[0], PADDLE_ENFORCE_EQ(
"First dimension of target must be equal to input " y_dims[0] == 1 || y_dims[0] == x_dims[0], true,
"or to 1."); 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("sub_result", {x_dims[0], product(x_dims) / x_dims[0]});
ctx->SetOutputDim("Out", {x_dims[0], 1}); ctx->SetOutputDim("Out", {x_dims[0], 1});
...@@ -126,19 +143,29 @@ class SquaredL2DistanceGradOp : public framework::OperatorWithKernel { ...@@ -126,19 +143,29 @@ class SquaredL2DistanceGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")), OP_INOUT_CHECK(ctx->HasInput("sub_result"), "Input", "sub_result",
"Gradient of Out should not be null"); "SquaredL2DistanceGradOp");
PADDLE_ENFORCE(ctx->HasInput("sub_result"), "SubResult should not be null"); OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Out@GRAD", "SquaredL2DistanceGradOp");
auto out_dims = ctx->GetInputDim(framework::GradVarName("Out")); auto out_dims = ctx->GetInputDim(framework::GradVarName("Out"));
auto x_dims = ctx->GetInputDim("X"); auto x_dims = ctx->GetInputDim("X");
auto y_dims = ctx->GetInputDim("Y"); auto y_dims = ctx->GetInputDim("Y");
if (ctx->IsRuntime()) { if (ctx->IsRuntime()) {
PADDLE_ENFORCE_EQ(out_dims[0], x_dims[0], PADDLE_ENFORCE_EQ(
"First dimension of output gradient and " out_dims[0], x_dims[0],
"input value must be equal."); 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, PADDLE_ENFORCE_EQ(out_dims[1], 1,
"Second dimension of output gradient " platform::errors::InvalidArgument(
"must be 1."); "Second dimension of output gradient of "
"SquaredL2DistanceGradOp must be 1. "
"But received grad's shape = [%s], "
"with second dimension %d",
out_dims, out_dims[1]));
} }
auto x_grad_name = framework::GradVarName("X"); auto x_grad_name = framework::GradVarName("X");
auto y_grad_name = framework::GradVarName("Y"); auto y_grad_name = framework::GradVarName("Y");
......
...@@ -26,8 +26,8 @@ class SquaredL2NormOp : public framework::OperatorWithKernel { ...@@ -26,8 +26,8 @@ class SquaredL2NormOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SquaredL2NormOp");
PADDLE_ENFORCE(ctx->HasOutput("Out"), "Output(Out) should be not null."); OP_INOUT_CHECK(ctx->HasOutput("Out"), "Output", "Out", "SquaredL2NormOp");
ctx->SetOutputDim("Out", {1}); ctx->SetOutputDim("Out", {1});
} }
...@@ -56,11 +56,11 @@ class SquaredL2NormGradOp : public framework::OperatorWithKernel { ...@@ -56,11 +56,11 @@ class SquaredL2NormGradOp : public framework::OperatorWithKernel {
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
void InferShape(framework::InferShapeContext* ctx) const override { void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null."); OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SquaredL2NormGradOp");
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Out")), OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Input(Out@GRAD) should be not null."); "Out@GRAD", "SquaredL2NormGradOp");
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")), OP_INOUT_CHECK(ctx->HasOutput(framework::GradVarName("X")), "Output",
"Output(X@GRAD) should be not null."); "X@GRAD", "SquaredL2NormGradOp");
ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X")); ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
} }
......
...@@ -45,8 +45,10 @@ class SquaredL2NormGradKernel : public framework::OpKernel<T> { ...@@ -45,8 +45,10 @@ class SquaredL2NormGradKernel : public framework::OpKernel<T> {
const framework::Tensor *X = context.Input<framework::Tensor>("X"); const framework::Tensor *X = context.Input<framework::Tensor>("X");
const framework::Tensor *dOut = const framework::Tensor *dOut =
context.Input<framework::Tensor>(framework::GradVarName("Out")); context.Input<framework::Tensor>(framework::GradVarName("Out"));
PADDLE_ENFORCE(dOut->numel() == 1, PADDLE_ENFORCE_EQ(
"Squared L2 Norm Gradient should be scalar"); dOut->numel(), 1,
platform::errors::InvalidArgument(
"Input(GRAD@Out) of SquaredL2NormGradOP should be a scalar."));
framework::Tensor *dX = framework::Tensor *dX =
context.Output<framework::Tensor>(framework::GradVarName("X")); context.Output<framework::Tensor>(framework::GradVarName("X"));
dX->mutable_data<T>(context.GetPlace()); 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.
先完成此消息的编辑!
想要评论请 注册