diff --git a/paddle/fluid/operators/linear_chain_crf_op.cc b/paddle/fluid/operators/linear_chain_crf_op.cc index fa09cb61e64aacd2aebf1ecf9826a15f9dcef877..d5e29eb1792f850ac9bf5bb533e66dcbca567dca 100644 --- a/paddle/fluid/operators/linear_chain_crf_op.cc +++ b/paddle/fluid/operators/linear_chain_crf_op.cc @@ -152,12 +152,19 @@ class LinearChainCRFOp : public framework::OperatorWithKernel { auto transition_dims = ctx->GetInputDim("Transition"); PADDLE_ENFORCE_EQ(transition_dims.size(), 2, "The Input(Transition) should be a 2-D tensor."); - PADDLE_ENFORCE_EQ( - transition_dims[0] - 2, transition_dims[1], - "An invalid dimension for the Input(Transition), which should " - "be a 2-D tensor with shape [(D + 2) x D]."); - PADDLE_ENFORCE_EQ( - emission_dims[1], transition_dims[1], + bool check = true; + if ((!ctx->IsRuntime()) && + (transition_dims[0] <= 0 || transition_dims[1] <= 0)) { + check = false; + } + if (check) { + PADDLE_ENFORCE_EQ( + transition_dims[0] - 2, transition_dims[1], + "An invalid dimension for the Input(Transition), which should " + "be a 2-D tensor with shape [(D + 2) x D]."); + } + PADDLE_INFERSHAPE_ENFORCE_EQ( + ctx, emission_dims[1], transition_dims[1], "The 2nd dimension of the Input(Emission) and the Input(Transition) " "should be equal to the tag number."); @@ -165,8 +172,8 @@ class LinearChainCRFOp : public framework::OperatorWithKernel { PADDLE_ENFORCE(label_dims.size() == 2UL && label_dims[1] == 1UL, "The Input(Label) should be a 2-D tensor with the 2nd " "dimensions fixed to 1."); - PADDLE_ENFORCE_EQ( - emission_dims[0], label_dims[0], + PADDLE_INFERSHAPE_ENFORCE_EQ( + ctx, emission_dims[0], label_dims[0], "The height of Input(Emission) and the height of Input(Label) " "should be the same."); @@ -211,12 +218,19 @@ class LinearChainCRFGradOp : public framework::OperatorWithKernel { auto transition_exps_dims = ctx->GetInputDim("TransitionExps"); PADDLE_ENFORCE_EQ(transition_exps_dims.size(), 2, "The Input(TransitionExps) should be a 2-D tensor."); - PADDLE_ENFORCE_EQ( - transition_exps_dims[0] - 2, transition_exps_dims[1], - "An invalid dimension for the Input(TransitionExps), which should " - "be a 2-D tensor with shape [(D + 2) x D]."); - PADDLE_ENFORCE_EQ( - emission_exps_dims[1], transition_exps_dims[1], + bool check = true; + if ((!ctx->IsRuntime()) && + (transition_exps_dims[0] <= 0 || transition_exps_dims[1] <= 0)) { + check = false; + } + if (check) { + PADDLE_ENFORCE_EQ( + transition_exps_dims[0] - 2, transition_exps_dims[1], + "An invalid dimension for the Input(TransitionExps), which should " + "be a 2-D tensor with shape [(D + 2) x D]."); + } + PADDLE_INFERSHAPE_ENFORCE_EQ( + ctx, emission_exps_dims[1], transition_exps_dims[1], "The 2nd dimension of the Input(EmissionExps) and the " "Input(TransitionExps) should be equal to the tag number."); @@ -224,8 +238,8 @@ class LinearChainCRFGradOp : public framework::OperatorWithKernel { PADDLE_ENFORCE(label_dims.size() == 2UL && label_dims[1] == 1UL, "The Input(Label) should be a 2-D tensor with the 2nd " "dimensions fixed to 1."); - PADDLE_ENFORCE_EQ( - emission_exps_dims[0], label_dims[0], + PADDLE_INFERSHAPE_ENFORCE_EQ( + ctx, emission_exps_dims[0], label_dims[0], "The height of Input(EmissionExps) and the height of Input(Label) " "should be the same."); diff --git a/paddle/fluid/operators/metrics/accuracy_op.cc b/paddle/fluid/operators/metrics/accuracy_op.cc index 7db6dff2971ab7eab9d38d7b32e8a5cff1aacb3c..26e6ab1568d15362c7793fe1eb1e970e4a8946d7 100644 --- a/paddle/fluid/operators/metrics/accuracy_op.cc +++ b/paddle/fluid/operators/metrics/accuracy_op.cc @@ -41,10 +41,11 @@ class AccuracyOp : public framework::OperatorWithKernel { // it's the output of topk. PADDLE_ENFORCE_EQ(label_dim.size(), 2, "label's rank must be 2."); - PADDLE_ENFORCE_EQ(label_dim[1], 1, "label's second dimension must be 1"); - PADDLE_ENFORCE_EQ(inference_dim[0], label_dim[0], - "the inference tensor's num_rows must be" - " the same as label."); + PADDLE_INFERSHAPE_ENFORCE_EQ(ctx, label_dim[1], 1, + "label's second dimension must be 1"); + PADDLE_INFERSHAPE_ENFORCE_EQ(ctx, inference_dim[0], label_dim[0], + "the inference tensor's num_rows must be" + " the same as label."); ctx->SetOutputDim("Accuracy", {1}); ctx->SetOutputDim("Correct", {1}); diff --git a/paddle/fluid/operators/metrics/auc_op.cc b/paddle/fluid/operators/metrics/auc_op.cc index 5e33dd96064dffb2b7e8dd748163bac18d5e5eb3..4670eb23b3db9ee91333c39d9bfcdab9fc2e5ff8 100644 --- a/paddle/fluid/operators/metrics/auc_op.cc +++ b/paddle/fluid/operators/metrics/auc_op.cc @@ -32,8 +32,8 @@ class AucOp : public framework::OperatorWithKernel { auto predict_height = ctx->GetInputDim("Predict")[0]; auto label_height = ctx->GetInputDim("Label")[0]; - PADDLE_ENFORCE_EQ(predict_height, label_height, - "Out and Label should have same height."); + PADDLE_INFERSHAPE_ENFORCE_EQ(ctx, predict_height, label_height, + "Out and Label should have same height."); int num_pred_buckets = ctx->Attrs().Get("num_thresholds") + 1; int slide_steps = ctx->Attrs().Get("slide_steps"); diff --git a/paddle/fluid/operators/sample_logits_op.cc b/paddle/fluid/operators/sample_logits_op.cc index a7f7fb26b17c77e6fe87646d3cac20c02c49b52c..8019fceb27ba588b3bb95bcef13b2f3e251058c4 100644 --- a/paddle/fluid/operators/sample_logits_op.cc +++ b/paddle/fluid/operators/sample_logits_op.cc @@ -11,10 +11,11 @@ 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. */ - #include "paddle/fluid/operators/sample_logits_op.h" #include "paddle/fluid/operators/math/sample_prob.h" +#include + namespace paddle { namespace operators { @@ -132,7 +133,10 @@ class SampleLogitsOp : public framework::OperatorWithKernel { "The labels should be a 2-D tensor."); const int num_samples = ctx->Attrs().Get("num_samples"); - const int num_sampled_classes = labels_dims[1] + num_samples; + int num_sampled_classes = labels_dims[1] + num_samples; + if ((!ctx->IsRuntime()) && labels_dims[1] <= 0) { + num_sampled_classes = -1; + } ctx->SetOutputDim("Samples", {logits_dims[0], num_sampled_classes}); ctx->SetOutputDim("Probabilities", {logits_dims[0], num_sampled_classes}); ctx->SetOutputDim("SampledLogits", {logits_dims[0], num_sampled_classes}); diff --git a/paddle/fluid/operators/smooth_l1_loss_op.cc b/paddle/fluid/operators/smooth_l1_loss_op.cc index 622420c1c33a62994c81ad9534c4fa37a4a1fa1a..5282bcbc693b4980616e12b57c19dee44ba645e9 100644 --- a/paddle/fluid/operators/smooth_l1_loss_op.cc +++ b/paddle/fluid/operators/smooth_l1_loss_op.cc @@ -14,6 +14,8 @@ limitations under the License. */ #include "paddle/fluid/operators/smooth_l1_loss_op.h" +#include + namespace paddle { namespace operators { @@ -27,7 +29,14 @@ class SmoothL1LossOp : public framework::OperatorWithKernel { auto x_dims = ctx->GetInputDim("X"); auto y_dims = ctx->GetInputDim("Y"); - PADDLE_ENFORCE_EQ(x_dims, y_dims); + bool check = true; + if ((!ctx->IsRuntime()) && + (framework::product(x_dims) <= 0 || framework::product(y_dims) <= 0)) { + check = false; + } + if (check) { + PADDLE_ENFORCE_EQ(x_dims, y_dims); + } PADDLE_ENFORCE_GE(x_dims.size(), 2, "The tensor rank of Input(X) should not be less than 2."); if (ctx->HasInput("InsideWeight")) { @@ -110,11 +119,11 @@ class SmoothL1LossGradOp : public framework::OperatorWithKernel { PADDLE_ENFORCE_GE(out_dims.size(), 2, "The tensor rank of Input(Out@Grad) should be 2."); - PADDLE_ENFORCE_EQ(out_dims[0], in_dims[0], - "The 1st dimension of Input(Out@Grad) must be " - "same as input."); - PADDLE_ENFORCE_EQ(out_dims[1], 1, - "The 2nd dimension of Input(Out@Grad) must be 1."); + PADDLE_INFERSHAPE_ENFORCE_EQ(ctx, out_dims[0], in_dims[0], + "The 1st dimension of Input(Out@Grad) must be " + "same as input."); + PADDLE_INFERSHAPE_ENFORCE_EQ( + ctx, out_dims[1], 1, "The 2nd dimension of Input(Out@Grad) must be 1."); auto x_grad_name = framework::GradVarName("X"); auto y_grad_name = framework::GradVarName("Y"); diff --git a/paddle/fluid/operators/squared_l2_distance_op.cc b/paddle/fluid/operators/squared_l2_distance_op.cc index 0652c163f71709c66b2b9c1cedcbfd3ce9061bea..6e82bf407496ab2d37d3fe81aacccfc128d57aec 100644 --- a/paddle/fluid/operators/squared_l2_distance_op.cc +++ b/paddle/fluid/operators/squared_l2_distance_op.cc @@ -45,13 +45,26 @@ class SquaredL2DistanceOp : public framework::OperatorWithKernel { int rank = framework::arity(x_dims); PADDLE_ENFORCE_GE(rank, 2, "Tensor rank should be at least equal to 2."); - 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(y_dims[0] == 1 || y_dims[0] == x_dims[0], - "First dimension of target must be equal to input " - "or to 1."); - + 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."); + } + 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."); + } ctx->SetOutputDim("sub_result", {x_dims[0], product(x_dims) / x_dims[0]}); ctx->SetOutputDim("Out", {x_dims[0], 1}); ctx->ShareLoD("X", /*->*/ "Out"); @@ -124,12 +137,12 @@ class SquaredL2DistanceGradOp : public framework::OperatorWithKernel { auto out_dims = ctx->GetInputDim(framework::GradVarName("Out")); auto x_dims = ctx->GetInputDim("X"); auto y_dims = ctx->GetInputDim("Y"); - 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[1], 1, - "Second dimension of output gradient " - "must be 1."); + PADDLE_INFERSHAPE_ENFORCE_EQ(ctx, out_dims[0], x_dims[0], + "First dimension of output gradient and " + "input value must be equal."); + PADDLE_INFERSHAPE_ENFORCE_EQ(ctx, out_dims[1], 1, + "Second dimension of output gradient " + "must be 1."); auto x_grad_name = framework::GradVarName("X"); auto y_grad_name = framework::GradVarName("Y"); if (ctx->HasOutput(x_grad_name)) ctx->SetOutputDim(x_grad_name, x_dims); diff --git a/paddle/fluid/platform/enforce.h b/paddle/fluid/platform/enforce.h index bdb1d1bd3bf47ea89984587ae84d2aa84be232a4..127be44525beca0e2273e591cf2ea5fb332782b4 100644 --- a/paddle/fluid/platform/enforce.h +++ b/paddle/fluid/platform/enforce.h @@ -356,5 +356,46 @@ using CommonType2 = typename std::add_lvalue_reference< #define PADDLE_ENFORCE_LE(__VAL0, __VAL1, ...) \ __PADDLE_BINARY_COMPARE(__VAL0, __VAL1, <=, >, __VA_ARGS__) +#define __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL1, __VAL2, __CMP, \ + __INV_CMP, ...) \ + do { \ + auto __val1 = (__VAL1); \ + auto __val2 = (__VAL2); \ + if (!__CTX->IsRuntime()) { \ + if (__val1 == -1 || __val2 == -1) { \ + break; \ + } \ + } \ + using __TYPE1__ = decltype(__val1); \ + using __TYPE2__ = decltype(__val2); \ + using __COMMON_TYPE1__ = \ + ::paddle::platform::details::CommonType1<__TYPE1__, __TYPE2__>; \ + using __COMMON_TYPE2__ = \ + ::paddle::platform::details::CommonType2<__TYPE1__, __TYPE2__>; \ + bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1))__CMP( \ + static_cast<__COMMON_TYPE2__>(__val2)); \ + if (UNLIKELY(!__is_not_error)) { \ + PADDLE_THROW("Enforce failed. Expected %s " #__CMP \ + " %s, but received %s:%s " #__INV_CMP " %s:%s.\n%s", \ + #__VAL1, #__VAL2, #__VAL1, \ + ::paddle::string::to_string(__val1), #__VAL2, \ + ::paddle::string::to_string(__val2), \ + ::paddle::string::Sprintf(__VA_ARGS__)); \ + } \ + } while (0) + +#define PADDLE_INFERSHAPE_ENFORCE_EQ(__CTX, __VAL0, __VAL1, ...) \ + __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL0, __VAL1, ==, !=, __VA_ARGS__) +#define PADDLE_INFERSHAPE_ENFORCE_NE(__CTX, __VAL0, __VAL1, ...) \ + __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL0, __VAL1, !=, ==, __VA_ARGS__) +#define PADDLE_INFERSHAPE_ENFORCE_GT(__CTX, __VAL0, __VAL1, ...) \ + __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL0, __VAL1, >, <=, __VA_ARGS__) +#define PADDLE_INFERSHAPE_ENFORCE_GE(__CTX, __VAL0, __VAL1, ...) \ + __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL0, __VAL1, >=, <, __VA_ARGS__) +#define PADDLE_INFERSHAPE_ENFORCE_LT(__CTX, __VAL0, __VAL1, ...) \ + __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL0, __VAL1, <, >=, __VA_ARGS__) +#define PADDLE_INFERSHAPE_ENFORCE_LE(__CTX, __VAL0, __VAL1, ...) \ + __PADDLE_INFERSHAPE_BINARY_COMPARE(__CTX, __VAL0, __VAL1, <=, >, __VA_ARGS__) + } // namespace platform } // namespace paddle