diff --git a/paddle/fluid/operators/fill_constant_batch_size_like_op_npu.cc b/paddle/fluid/operators/fill_constant_batch_size_like_op_npu.cc index 7edddce65cc6f567b7df89bc9713f49792298445..c05ec87004ce215f858d579f59f359e1d98b7b26 100644 --- a/paddle/fluid/operators/fill_constant_batch_size_like_op_npu.cc +++ b/paddle/fluid/operators/fill_constant_batch_size_like_op_npu.cc @@ -32,13 +32,12 @@ class FillConstantBatchSizeLikeOpNPUKernel : public framework::OpKernel { auto force_cpu = ctx.Attr("force_cpu"); auto *out = ctx.Output("Out"); - auto *input = ctx.Input("Input"); - if (&ctx.Attr("input_dim_idx") == 0) { - // set the correct batch size. + auto *in = ctx.Input("Input"); + if (in->lod().size() && ctx.Attr("input_dim_idx") == 0) { + // set the correct batch size for the LoDTensor. auto odims = out->dims(); - int input_dim_idx = ctx.Attr("input_dim_idx"); int output_dim_idx = ctx.Attr("output_dim_idx"); - odims[output_dim_idx] = input->dims()[input_dim_idx]; + odims[output_dim_idx] = static_cast(in->lod().back().size()) - 1; out->mutable_data(odims, ctx.GetPlace()); } @@ -46,15 +45,24 @@ class FillConstantBatchSizeLikeOpNPUKernel : public framework::OpKernel { if (str_value.empty()) { value = static_cast(float_value); } else { - std::stringstream convert_stream(str_value); - if (std::is_same::value) { - int64_t tmp_value; - convert_stream >> tmp_value; - value = static_cast(tmp_value); + // handle NaN/Inf first, which cannot be read from stream. + if (str_value == "inf") { + value = static_cast(std::numeric_limits::infinity()); + } else if (str_value == "-inf") { + value = static_cast(-std::numeric_limits::infinity()); + } else if (str_value == "nan") { + value = static_cast(std::numeric_limits::quiet_NaN()); } else { - double tmp_value; - convert_stream >> tmp_value; - value = static_cast(tmp_value); + std::stringstream convert_stream(str_value); + if (std::is_same::value) { + int64_t tmp_value; + convert_stream >> tmp_value; + value = static_cast(tmp_value); + } else { + double tmp_value; + convert_stream >> tmp_value; + value = static_cast(tmp_value); + } } } diff --git a/python/paddle/fluid/tests/unittests/npu/test_fill_constant_batch_size_like_op_npu.py b/python/paddle/fluid/tests/unittests/npu/test_fill_constant_batch_size_like_op_npu.py index 7736c85c87aa2975a459d7e1f4e6298542432f5c..615fe6f7645f993c1e87de3122d1636cb9edc2e3 100644 --- a/python/paddle/fluid/tests/unittests/npu/test_fill_constant_batch_size_like_op_npu.py +++ b/python/paddle/fluid/tests/unittests/npu/test_fill_constant_batch_size_like_op_npu.py @@ -99,6 +99,22 @@ class TestFillConstantBatchSizeLike3(TestFillConstantBatchSizeLike): self.output_value = 4.5 +class TestFillConstantBatchSizeLike4(TestFillConstantBatchSizeLike): + def init_value(self): + # str_value = 'inf' + self.value = 3.8 + self.str_value = 'inf' + self.output_value = float('inf') + + +class TestFillConstantBatchSizeLike5(TestFillConstantBatchSizeLike): + def init_value(self): + # str_value = '-inf' + self.value = 3.8 + self.str_value = '-inf' + self.output_value = -float('inf') + + class TestFillConstantBatchSizeLike6(TestFillConstantBatchSizeLike): def init_dtype(self): self.dtype = core.VarDesc.VarType.FP16 @@ -130,5 +146,54 @@ class TestFillConstantBatchSizeLike9(TestFillConstantBatchSizeLike): self.output_dim_idx = 1 +class TestFillConstantBatchSizeLikeLodTensor(TestFillConstantBatchSizeLike): + # test LodTensor + def setUp(self): + self.set_npu() + self.place = paddle.NPUPlace(0) + self.op_type = "fill_constant_batch_size_like" + self.init_shape() + self.init_value() + self.init_dtype() + self.init_force_cpu() + self.init_dim_idx() + + lod = [[3, 2, 5]] + self.inputs = { + 'Input': (np.random.random(self.input_shape).astype("float32"), lod) + } + self.attrs = { + 'shape': self.shape, + 'value': self.value, + 'str_value': self.str_value, + 'dtype': self.dtype, + 'force_cpu': self.force_cpu, + 'input_dim_idx': self.input_dim_idx, + 'output_dim_idx': self.output_dim_idx + } + self.outputs = { + 'Out': np.full(self.output_shape, self.output_value, + self.output_dtype) + } + + def init_shape(self): + self.input_shape = [10, 20] + self.shape = [123, 92] + self.output_shape = (3, 92) + + +class TestFillConstantBatchSizeLikeLodTensor2( + TestFillConstantBatchSizeLikeLodTensor): + # test LodTensor with 'input_dim_idx' != 0 + def init_shape(self): + self.input_shape = [10, 20] + self.shape = [123, 92] + self.output_shape = (20, 92) + + def init_dim_idx(self): + self.input_dim_idx = 1 + self.output_dim_idx = 0 + + if __name__ == '__main__': unittest.main()