未验证 提交 1b9a3bfc 编写于 作者: H Huihuang Zheng 提交者: GitHub

[Dy2stat] Support paddle.to_tensor with int, float, bool. (#32420)

paddle.to_tensor will be translated to paddle.assign in Dy2stat, however paddle.assign doesn't support int, float, bool. This PR added the supports.
上级 d0751d09
...@@ -547,8 +547,10 @@ def assign(input, output=None): ...@@ -547,8 +547,10 @@ def assign(input, output=None):
The OP copies the :attr:`input` to the :attr:`output`. The OP copies the :attr:`input` to the :attr:`output`.
Parameters: Parameters:
input (Tensor|numpy.ndarray): A tensor or numpy ndarray, its data type supports input (Tensor|numpy.ndarray|list|tuple|scalar): A tensor, numpy ndarray, tuple/list of scalar,
float16, float32, float64, int32 and int64. or scalar. Its data type supports float16, float32, float64, int32, int64, and bool.
Note: the float64 data will be converted to float32 because of current platform protobuf
data limitation.
output (Tensor, optional): A tensor. If :attr:`output` is None, a new tensor will output (Tensor, optional): A tensor. If :attr:`output` is None, a new tensor will
be created as :attr:`output`. Default: None. be created as :attr:`output`. Default: None.
...@@ -570,9 +572,15 @@ def assign(input, output=None): ...@@ -570,9 +572,15 @@ def assign(input, output=None):
result3 = paddle.assign(np.array([[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]], dtype='float32')) # result3 = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]] result3 = paddle.assign(np.array([[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]], dtype='float32')) # result3 = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]]
""" """
helper = LayerHelper('assign', **locals()) helper = LayerHelper('assign', **locals())
check_type(input, 'input', (Variable, numpy.ndarray), 'assign') check_type(input, 'input', (Variable, numpy.ndarray, list, tuple, float,
int, bool), 'assign')
is_inplace = True if output is not None else False is_inplace = True if output is not None else False
if numpy.isscalar(input) and not isinstance(input, str):
input = numpy.array([input])
elif isinstance(input, (list, tuple)):
input = numpy.array(input)
if isinstance(input, Variable): if isinstance(input, Variable):
check_dtype( check_dtype(
input.dtype, 'input', input.dtype, 'input',
...@@ -585,6 +593,14 @@ def assign(input, output=None): ...@@ -585,6 +593,14 @@ def assign(input, output=None):
type='assign', inputs={'X': [input]}, outputs={'Out': [output]}) type='assign', inputs={'X': [input]}, outputs={'Out': [output]})
elif isinstance(input, numpy.ndarray): elif isinstance(input, numpy.ndarray):
dtype = convert_np_dtype_to_dtype_(input.dtype) dtype = convert_np_dtype_to_dtype_(input.dtype)
if dtype == VarDesc.VarType.FP64:
# Setting FP64 numpy data is not supported in Paddle, so we
# use FP32 here
warnings.warn(
"paddle.assign doesn't support float64 input now due "
"to current platform protobuf data limitation, we convert "
"it to float32")
dtype = VarDesc.VarType.FP32
if dtype == VarDesc.VarType.BOOL: if dtype == VarDesc.VarType.BOOL:
value_name = "bool_values" value_name = "bool_values"
values = [bool(v) for v in input.flat] values = [bool(v) for v in input.flat]
......
...@@ -31,6 +31,10 @@ from paddle.fluid.dygraph.dygraph_to_static.utils import is_dygraph_api ...@@ -31,6 +31,10 @@ from paddle.fluid.dygraph.dygraph_to_static.utils import is_dygraph_api
SEED = 2020 SEED = 2020
np.random.seed(SEED) np.random.seed(SEED)
# TODO(zhhsplendid): This test is old so that use a static graph style
# mark it as TODO, to refactoring the code of this file.
paddle.enable_static()
def dyfunc_to_variable(x): def dyfunc_to_variable(x):
res = fluid.dygraph.to_variable(x, name=None, zero_copy=None) res = fluid.dygraph.to_variable(x, name=None, zero_copy=None)
...@@ -54,11 +58,27 @@ def dyfunc_to_tensor(x): ...@@ -54,11 +58,27 @@ def dyfunc_to_tensor(x):
return res3 return res3
def dyfunc_int_to_tensor(x):
res = paddle.to_tensor(3)
return res
def dyfunc_float_to_tensor(x):
res = paddle.to_tensor(2.0)
return res
def dyfunc_bool_to_tensor(x):
res = paddle.to_tensor(True)
return res
class TestDygraphBasicApi_ToVariable(unittest.TestCase): class TestDygraphBasicApi_ToVariable(unittest.TestCase):
def setUp(self): def setUp(self):
self.input = np.ones(5).astype("int32") self.input = np.ones(5).astype("int32")
self.test_funcs = [ self.test_funcs = [
dyfunc_to_tensor, dyfunc_to_variable, dyfunc_to_variable_2, dyfunc_to_tensor, dyfunc_bool_to_tensor, dyfunc_int_to_tensor,
dyfunc_float_to_tensor, dyfunc_to_variable, dyfunc_to_variable_2,
dyfunc_to_variable_3 dyfunc_to_variable_3
] ]
self.place = fluid.CUDAPlace(0) if fluid.is_compiled_with_cuda( self.place = fluid.CUDAPlace(0) if fluid.is_compiled_with_cuda(
......
...@@ -94,10 +94,8 @@ class TestAssignOpError(unittest.TestCase): ...@@ -94,10 +94,8 @@ class TestAssignOpError(unittest.TestCase):
x3 = fluid.layers.data(name='x3', shape=[4], dtype="uint8") x3 = fluid.layers.data(name='x3', shape=[4], dtype="uint8")
self.assertRaises(TypeError, fluid.layers.assign, x3) self.assertRaises(TypeError, fluid.layers.assign, x3)
# When the type of input is numpy.ndarray, the dtype of input must be float32, int32. # When the type of input is numpy.ndarray, the dtype of input must be float32, int32.
x4 = np.array([[2.5, 2.5]], dtype='float64') x4 = np.array([[2.5, 2.5]], dtype='uint8')
self.assertRaises(TypeError, fluid.layers.assign, x4) self.assertRaises(TypeError, fluid.layers.assign, x4)
x5 = np.array([[2.5, 2.5]], dtype='uint8')
self.assertRaises(TypeError, fluid.layers.assign, x5)
class TestAssignOApi(unittest.TestCase): class TestAssignOApi(unittest.TestCase):
...@@ -157,6 +155,23 @@ class TestAssignOApi(unittest.TestCase): ...@@ -157,6 +155,23 @@ class TestAssignOApi(unittest.TestCase):
paddle.assign(array, result1) paddle.assign(array, result1)
self.assertTrue(np.allclose(result1.numpy(), array)) self.assertTrue(np.allclose(result1.numpy(), array))
def test_assign_List(self):
paddle.disable_static()
l = [1, 2, 3]
result = paddle.assign(l)
self.assertTrue(np.allclose(result.numpy(), np.array(l)))
paddle.enable_static()
def test_assign_BasicTypes(self):
paddle.disable_static()
result1 = paddle.assign(2)
result2 = paddle.assign(3.0)
result3 = paddle.assign(True)
self.assertTrue(np.allclose(result1.numpy(), np.array([2])))
self.assertTrue(np.allclose(result2.numpy(), np.array([3.0])))
self.assertTrue(np.allclose(result3.numpy(), np.array([1])))
paddle.enable_static()
class TestAssignOpErrorApi(unittest.TestCase): class TestAssignOpErrorApi(unittest.TestCase):
def test_errors(self): def test_errors(self):
...@@ -169,10 +184,8 @@ class TestAssignOpErrorApi(unittest.TestCase): ...@@ -169,10 +184,8 @@ class TestAssignOpErrorApi(unittest.TestCase):
x3 = fluid.layers.data(name='x3', shape=[4], dtype="uint8") x3 = fluid.layers.data(name='x3', shape=[4], dtype="uint8")
self.assertRaises(TypeError, paddle.assign, x3) self.assertRaises(TypeError, paddle.assign, x3)
# When the type of input is numpy.ndarray, the dtype of input must be float32, int32. # When the type of input is numpy.ndarray, the dtype of input must be float32, int32.
x4 = np.array([[2.5, 2.5]], dtype='float64') x4 = np.array([[2.5, 2.5]], dtype='uint8')
self.assertRaises(TypeError, paddle.assign, x4) self.assertRaises(TypeError, paddle.assign, x4)
x5 = np.array([[2.5, 2.5]], dtype='uint8')
self.assertRaises(TypeError, paddle.assign, x5)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -85,11 +85,8 @@ class TestAssignOpError(unittest.TestCase): ...@@ -85,11 +85,8 @@ class TestAssignOpError(unittest.TestCase):
# When the type of input is Variable, the dtype of input must be float16, float32, float64, int32, int64, bool. # When the type of input is Variable, the dtype of input must be float16, float32, float64, int32, int64, bool.
x3 = fluid.layers.data(name='x3', shape=[4], dtype="uint8") x3 = fluid.layers.data(name='x3', shape=[4], dtype="uint8")
self.assertRaises(TypeError, fluid.layers.assign, x3) self.assertRaises(TypeError, fluid.layers.assign, x3)
# When the type of input is numpy.ndarray, the dtype of input must be float32, int32. x4 = np.array([[2.5, 2.5]], dtype='uint8')
x4 = np.array([[2.5, 2.5]], dtype='float64')
self.assertRaises(TypeError, fluid.layers.assign, x4) self.assertRaises(TypeError, fluid.layers.assign, x4)
x5 = np.array([[2.5, 2.5]], dtype='uint8')
self.assertRaises(TypeError, fluid.layers.assign, x5)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -1036,8 +1036,8 @@ def assign(x, output=None): ...@@ -1036,8 +1036,8 @@ def assign(x, output=None):
The OP copies the :attr:`x` to the :attr:`output`. The OP copies the :attr:`x` to the :attr:`output`.
Parameters: Parameters:
x (Tensor|numpy.ndarray): A tensor or numpy ndarray, its data type supports x (Tensor|numpy.ndarray|list|tuple|scalar): A tensor, numpy ndarray, tuple, list or scalar,
float16, float32, float64, int32 and int64. its data type supports float16, float32, float64, int32, int64, and bool.
output (Tensor, optional): A tensor. If :attr:`output` is None, a new tensor will output (Tensor, optional): A tensor. If :attr:`output` is None, a new tensor will
be created as :attr:`output`. Default: None. be created as :attr:`output`. Default: None.
...@@ -1058,5 +1058,6 @@ def assign(x, output=None): ...@@ -1058,5 +1058,6 @@ def assign(x, output=None):
result2 = paddle.assign(data) # result2 = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]] result2 = paddle.assign(data) # result2 = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]]
result3 = paddle.assign(np.array([[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]], dtype='float32')) # result3 = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]] result3 = paddle.assign(np.array([[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]], dtype='float32')) # result3 = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]]
""" """
check_type(x, 'x', (Variable, numpy.ndarray), 'assign') check_type(x, 'x', (Variable, numpy.ndarray, list, tuple, float, int, bool),
'assign')
return tensor.assign(x, output) return tensor.assign(x, output)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册