diff --git a/paddle/fluid/operators/sequence_ops/sequence_mask_op.h b/paddle/fluid/operators/sequence_ops/sequence_mask_op.h index d541f712a5d670c289179c4807b5c6c8965503ef..d69ebafb017ec290b66f55d45b9a96691fd9b76d 100644 --- a/paddle/fluid/operators/sequence_ops/sequence_mask_op.h +++ b/paddle/fluid/operators/sequence_ops/sequence_mask_op.h @@ -106,18 +106,23 @@ class SequenceMaskKernel : public framework::OpKernel { auto *x_data = x->data(); auto x_numel = x->numel(); + if (maxlen < 0) { + if (x_numel == 0) { + maxlen = 0; + } else { #if defined(__NVCC__) || defined(__HIPCC__) - VLOG(10) - << "SequenceMaskOp on GPU may be slow when maxlen is not provided."; - maxlen = static_cast( - thrust::reduce(thrust::device_pointer_cast(x_data), - thrust::device_pointer_cast(x_data) + x_numel, - static_cast(0), - thrust::maximum())); + VLOG(10) + << "SequenceMaskOp on GPU may be slow when maxlen is not provided."; + maxlen = static_cast( + thrust::reduce(thrust::device_pointer_cast(x_data), + thrust::device_pointer_cast(x_data) + x_numel, + static_cast(0), + thrust::maximum())); #else - maxlen = static_cast(*std::max_element(x_data, x_data + x_numel)); + maxlen = static_cast(*std::max_element(x_data, x_data + x_numel)); #endif + } auto y_dim = phi::vectorize(x->dims()); y_dim.push_back(maxlen); y->Resize(phi::make_ddim(y_dim)); diff --git a/paddle/fluid/operators/sequence_ops/sequence_mask_op_npu.cc b/paddle/fluid/operators/sequence_ops/sequence_mask_op_npu.cc index f3b18676abe56440b67afb124172cafb7f40e74c..200ec54ac200edc97d653abee329d2a330dd88f8 100644 --- a/paddle/fluid/operators/sequence_ops/sequence_mask_op_npu.cc +++ b/paddle/fluid/operators/sequence_ops/sequence_mask_op_npu.cc @@ -48,10 +48,14 @@ class SequenceMaskNPUKernel : public framework::OpKernel { if (maxlen < 0) { auto x_numel = x->numel(); - std::vector x_vec; - framework::TensorToVector(*x, dev_ctx, &x_vec); - auto x_data = x_vec.data(); - maxlen = static_cast(*std::max_element(x_data, x_data + x_numel)); + if (x_numel == 0) { + maxlen = 0; + } else { + std::vector x_vec; + framework::TensorToVector(*x, dev_ctx, &x_vec); + auto x_data = x_vec.data(); + maxlen = static_cast(*std::max_element(x_data, x_data + x_numel)); + } } auto y_dim = phi::vectorize(x->dims()); y_dim.push_back(maxlen); diff --git a/python/paddle/fluid/tests/unittests/sequence/test_sequence_mask.py b/python/paddle/fluid/tests/unittests/sequence/test_sequence_mask.py index b7c3cc0e4dd3aafa1d26ec053eb2df41af2fa3c0..c8b210625571961da053a2ef3bd7bca4b702211d 100644 --- a/python/paddle/fluid/tests/unittests/sequence/test_sequence_mask.py +++ b/python/paddle/fluid/tests/unittests/sequence/test_sequence_mask.py @@ -17,6 +17,7 @@ import unittest import numpy as np +import paddle import paddle.fluid as fluid from paddle.fluid.framework import ( Program, @@ -171,5 +172,14 @@ class TestSequenceMaskOpError(unittest.TestCase): self.assertRaises(TypeError, test_Variable) +class TestSequenceMaskWithEmptyTensor(unittest.TestCase): + def test_empty(self): + paddle.disable_static() + lengths = paddle.to_tensor(np.array([], dtype=np.int64)) + mask = paddle.nn.functional.sequence_mask(lengths) + self.assertEqual(list(mask.shape), [0, 0]) + paddle.enable_static() + + if __name__ == '__main__': unittest.main()