Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【SCU】【Paddle Tensor No.28-29】新增 paddle.from_dlpack , paddle.to_dlpack,复用已有同名函数 paddle.utils.dlpack #69361

Merged
merged 5 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions python/paddle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,10 @@
var,
)
from .tensor.to_string import set_printoptions
from .utils.dlpack import (
from_dlpack,
to_dlpack,
)

# CINN has to set a flag to include a lib
if is_compiled_with_cinn():
Expand Down Expand Up @@ -1186,4 +1190,6 @@
'combinations',
'signbit',
'positive',
'from_dlpack',
'to_dlpack',
]
215 changes: 153 additions & 62 deletions test/legacy_test/test_dlpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,37 @@ class TestDLPack(unittest.TestCase):
def test_dlpack_dygraph(self):
with dygraph_guard():
tensor = paddle.to_tensor(np.array([1, 2, 3, 4]).astype("int"))
dlpack = paddle.utils.dlpack.to_dlpack(tensor)
out_from_dlpack = paddle.utils.dlpack.from_dlpack(dlpack)
dlpack_v1 = paddle.utils.dlpack.to_dlpack(tensor)
out_from_dlpack_v1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
dlpack_v2 = paddle.to_dlpack(tensor)
out_from_dlpack_v2 = paddle.from_dlpack(dlpack_v2)
self.assertTrue(
isinstance(out_from_dlpack, paddle.base.core.eager.Tensor)
isinstance(out_from_dlpack_v1, paddle.base.core.eager.Tensor)
)
self.assertEqual(str(tensor.place), str(out_from_dlpack.place))
self.assertTrue(
isinstance(out_from_dlpack_v2, paddle.base.core.eager.Tensor)
)
self.assertEqual(str(tensor.place), str(out_from_dlpack_v1.place))
self.assertEqual(str(tensor.place), str(out_from_dlpack_v2.place))
np.testing.assert_array_equal(
out_from_dlpack.numpy(), np.array([1, 2, 3, 4]).astype("int")
out_from_dlpack_v1.numpy(), np.array([1, 2, 3, 4]).astype("int")
)
np.testing.assert_array_equal(
out_from_dlpack_v2.numpy(), np.array([1, 2, 3, 4]).astype("int")
)
HydrogenSulfate marked this conversation as resolved.
Show resolved Hide resolved

def test_dlpack_tensor_larger_than_2dim(self):
with dygraph_guard():
numpy_data = np.random.randn(4, 5, 6)
t = paddle.to_tensor(numpy_data)
dlpack = paddle.utils.dlpack.to_dlpack(t)
out = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertEqual(str(t.place), str(out.place))
np.testing.assert_allclose(numpy_data, out.numpy(), rtol=1e-05)
dlpack_v1 = paddle.utils.dlpack.to_dlpack(t)
dlpack_v2 = paddle.to_dlpack(t)
out_v1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
out_v2 = paddle.from_dlpack(dlpack_v2)
self.assertEqual(str(t.place), str(out_v1.place))
self.assertEqual(str(t.place), str(out_v2.place))
np.testing.assert_allclose(numpy_data, out_v1.numpy(), rtol=1e-05)
np.testing.assert_allclose(numpy_data, out_v2.numpy(), rtol=1e-05)

HydrogenSulfate marked this conversation as resolved.
Show resolved Hide resolved
def test_dlpack_static(self):
with static_guard():
Expand All @@ -52,11 +65,18 @@ def test_dlpack_static(self):
[[1, 3]],
base.CPUPlace(),
)
dlpack = paddle.utils.dlpack.to_dlpack(tensor)
out_from_dlpack = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertTrue(isinstance(out_from_dlpack, base.core.Tensor))
dlpack_v1 = paddle.utils.dlpack.to_dlpack(tensor)
out_from_dlpack_v1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
dlpack_v2 = paddle.to_dlpack(tensor)
out_from_dlpack_v2 = paddle.from_dlpack(dlpack_v2)
self.assertTrue(isinstance(out_from_dlpack_v1, base.core.Tensor))
self.assertTrue(isinstance(out_from_dlpack_v2, base.core.Tensor))
np.testing.assert_array_equal(
np.array(out_from_dlpack_v1),
np.array([[1], [2], [3], [4]]).astype("int"),
)
np.testing.assert_array_equal(
np.array(out_from_dlpack),
np.array(out_from_dlpack_v2),
np.array([[1], [2], [3], [4]]).astype("int"),
)

HydrogenSulfate marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -67,11 +87,24 @@ def test_dlpack_static(self):
[[1, 3]],
base.CUDAPlace(0),
)
gdlpack = paddle.utils.dlpack.to_dlpack(gtensor)
gout_from_dlpack = paddle.utils.dlpack.from_dlpack(gdlpack)
self.assertTrue(isinstance(gout_from_dlpack, base.core.Tensor))
gdlpack_v1 = paddle.utils.dlpack.to_dlpack(gtensor)
gdlpack_v2 = paddle.to_dlpack(gtensor)
gout_from_dlpack_v1 = paddle.utils.dlpack.from_dlpack(
gdlpack_v1
)
gout_from_dlpack_v2 = paddle.from_dlpack(gdlpack_v2)
self.assertTrue(
isinstance(gout_from_dlpack_v1, base.core.Tensor)
)
self.assertTrue(
isinstance(gout_from_dlpack_v2, base.core.Tensor)
)
np.testing.assert_array_equal(
np.array(gout_from_dlpack),
np.array(gout_from_dlpack_v1),
np.array([[1], [2], [3], [4]]).astype("int"),
)
np.testing.assert_array_equal(
np.array(gout_from_dlpack_v2),
np.array([[1], [2], [3], [4]]).astype("int"),
)

HydrogenSulfate marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -98,11 +131,20 @@ def test_dlpack_dtype_and_place_consistency(self):
for place in places:
for dtype in dtypes:
x = paddle.to_tensor(data, dtype=dtype, place=place)
dlpack = paddle.utils.dlpack.to_dlpack(x)
o = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertEqual(x.dtype, o.dtype)
np.testing.assert_allclose(x.numpy(), o.numpy(), rtol=1e-05)
self.assertEqual(str(x.place), str(o.place))
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
o_v1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
dlpack_v2 = paddle.to_dlpack(x)
o_v2 = paddle.from_dlpack(dlpack_v2)
self.assertEqual(x.dtype, o_v1.dtype)
self.assertEqual(x.dtype, o_v2.dtype)
np.testing.assert_allclose(
x.numpy(), o_v1.numpy(), rtol=1e-05
)
np.testing.assert_allclose(
x.numpy(), o_v2.numpy(), rtol=1e-05
)
self.assertEqual(str(x.place), str(o_v1.place))
self.assertEqual(str(x.place), str(o_v2.place))

complex_dtypes = ["complex64", "complex128"]
for place in places:
Expand All @@ -112,11 +154,20 @@ def test_dlpack_dtype_and_place_consistency(self):
dtype=dtype,
place=place,
)
dlpack = paddle.utils.dlpack.to_dlpack(x)
o = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertEqual(x.dtype, o.dtype)
np.testing.assert_allclose(x.numpy(), o.numpy(), rtol=1e-05)
self.assertEqual(str(x.place), str(o.place))
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
o_v1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
dlpack_v2 = paddle.to_dlpack(x)
o_v2 = paddle.from_dlpack(dlpack_v2)
self.assertEqual(x.dtype, o_v1.dtype)
self.assertEqual(x.dtype, o_v2.dtype)
np.testing.assert_allclose(
x.numpy(), o_v1.numpy(), rtol=1e-05
)
np.testing.assert_allclose(
x.numpy(), o_v2.numpy(), rtol=1e-05
)
self.assertEqual(str(x.place), str(o_v1.place))
self.assertEqual(str(x.place), str(o_v2.place))

def test_dlpack_deletion(self):
# See Paddle issue 47171
Expand All @@ -129,9 +180,12 @@ def test_dlpack_deletion(self):
a = paddle.rand(shape=[3, 5], dtype="float32").to(
device=place
)
dlpack = paddle.utils.dlpack.to_dlpack(a)
b = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertEqual(str(a.place), str(b.place))
dlpack_v1 = paddle.utils.dlpack.to_dlpack(a)
dlpack_v2 = paddle.to_dlpack(a)
b1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
b2 = paddle.from_dlpack(dlpack_v2)
self.assertEqual(str(a.place), str(b1.place))
self.assertEqual(str(a.place), str(b2.place))

def test_to_dlpack_for_loop(self):
# See Paddle issue 50120
Expand All @@ -142,7 +196,8 @@ def test_to_dlpack_for_loop(self):
for place in places:
for _ in range(4):
x = paddle.rand([3, 5]).to(device=place)
dlpack = paddle.utils.dlpack.to_dlpack(x)
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
dlpack_v2 = paddle.to_dlpack(x)

def test_to_dlpack_modification(self):
# See Paddle issue 50120
Expand All @@ -153,11 +208,16 @@ def test_to_dlpack_modification(self):
for place in places:
for _ in range(4):
x = paddle.rand([3, 5]).to(device=place)
dlpack = paddle.utils.dlpack.to_dlpack(x)
y = paddle.utils.dlpack.from_dlpack(dlpack)
y[1:2, 2:5] = 2.0
np.testing.assert_allclose(x.numpy(), y.numpy())
self.assertEqual(str(x.place), str(y.place))
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
dlpack_v2 = paddle.to_dlpack(x)
y1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
y2 = paddle.from_dlpack(dlpack_v2)
y1[1:2, 2:5] = 2.0
y2[1:2, 2:5] = 2.0
np.testing.assert_allclose(x.numpy(), y1.numpy())
np.testing.assert_allclose(x.numpy(), y2.numpy())
self.assertEqual(str(x.place), str(y1.place))
self.assertEqual(str(x.place), str(y2.place))

def test_to_dlpack_data_ptr_consistency(self):
# See Paddle issue 50120
Expand All @@ -168,11 +228,15 @@ def test_to_dlpack_data_ptr_consistency(self):
for place in places:
for _ in range(4):
x = paddle.rand([3, 5]).to(device=place)
dlpack = paddle.utils.dlpack.to_dlpack(x)
y = paddle.utils.dlpack.from_dlpack(dlpack)
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
dlpack_v2 = paddle.to_dlpack(x)
y1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
y2 = paddle.from_dlpack(dlpack_v2)

self.assertEqual(x.data_ptr(), y.data_ptr())
self.assertEqual(str(x.place), str(y.place))
self.assertEqual(x.data_ptr(), y1.data_ptr())
self.assertEqual(x.data_ptr(), y2.data_ptr())
self.assertEqual(str(x.place), str(y1.place))
self.assertEqual(str(x.place), str(y2.place))

def test_to_dlpack_strides_consistency(self):
with dygraph_guard():
Expand All @@ -183,21 +247,33 @@ def test_to_dlpack_strides_consistency(self):
for _ in range(4):
x = paddle.rand([10, 10]).to(device=place)
x_strided = x[::2, ::2]
dlpack = paddle.utils.dlpack.to_dlpack(x_strided)
y = paddle.utils.dlpack.from_dlpack(dlpack)
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x_strided)
dlpack_v2 = paddle.to_dlpack(x_strided)
y1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
y2 = paddle.from_dlpack(dlpack_v2)

self.assertEqual(x_strided.strides, y.strides)
self.assertEqual(str(x_strided.place), str(y.place))
np.testing.assert_equal(x_strided.numpy(), y.numpy())
self.assertEqual(x_strided.strides, y1.strides)
self.assertEqual(x_strided.strides, y2.strides)
self.assertEqual(str(x_strided.place), str(y1.place))
self.assertEqual(str(x_strided.place), str(y2.place))
np.testing.assert_equal(x_strided.numpy(), y1.numpy())
np.testing.assert_equal(x_strided.numpy(), y2.numpy())

def test_to_dlpack_from_ext_tensor(self):
with dygraph_guard():
for _ in range(4):
x = np.random.randn(3, 5)
y = paddle.utils.dlpack.from_dlpack(x)
y1 = paddle.utils.dlpack.from_dlpack(x)
y2 = paddle.from_dlpack(x)

self.assertEqual(x.__array_interface__['data'][0], y.data_ptr())
np.testing.assert_allclose(x, y.numpy())
self.assertEqual(
x.__array_interface__['data'][0], y1.data_ptr()
)
self.assertEqual(
x.__array_interface__['data'][0], y2.data_ptr()
)
np.testing.assert_allclose(x, y1.numpy())
np.testing.assert_allclose(x, y2.numpy())

def test_to_dlpack_from_zero_dim(self):
with dygraph_guard():
Expand All @@ -207,13 +283,20 @@ def test_to_dlpack_from_zero_dim(self):
for place in places:
for _ in range(4):
x = paddle.to_tensor(1.0, place=place)
dlpack = paddle.utils.dlpack.to_dlpack(x)
y = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertEqual(x.data_ptr(), y.data_ptr())
self.assertEqual(str(x.place), str(y.place))
self.assertEqual(y.shape, [])
self.assertEqual(y.numel().item(), 1)
np.testing.assert_array_equal(x.numpy(), y.numpy())
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
dlpack_v2 = paddle.to_dlpack(x)
y1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
y2 = paddle.from_dlpack(dlpack_v2)
self.assertEqual(x.data_ptr(), y1.data_ptr())
self.assertEqual(x.data_ptr(), y2.data_ptr())
self.assertEqual(str(x.place), str(y1.place))
self.assertEqual(str(x.place), str(y2.place))
self.assertEqual(y1.shape, [])
self.assertEqual(y2.shape, [])
self.assertEqual(y1.numel().item(), 1)
self.assertEqual(y2.numel().item(), 1)
np.testing.assert_array_equal(x.numpy(), y1.numpy())
np.testing.assert_array_equal(x.numpy(), y2.numpy())

def test_to_dlpack_from_zero_size(self):
with dygraph_guard():
Expand All @@ -223,18 +306,26 @@ def test_to_dlpack_from_zero_size(self):
for place in places:
for _ in range(4):
x = paddle.zeros([0, 10]).to(device=place)
dlpack = paddle.utils.dlpack.to_dlpack(x)
y = paddle.utils.dlpack.from_dlpack(dlpack)
self.assertEqual(x.data_ptr(), y.data_ptr())
self.assertEqual(str(x.place), str(y.place))
self.assertEqual(y.shape, [0, 10])
self.assertEqual(y.numel().item(), 0)
np.testing.assert_array_equal(x.numpy(), y.numpy())
dlpack_v1 = paddle.utils.dlpack.to_dlpack(x)
dlpack_v2 = paddle.to_dlpack(x)
y1 = paddle.utils.dlpack.from_dlpack(dlpack_v1)
y2 = paddle.from_dlpack(dlpack_v2)
self.assertEqual(x.data_ptr(), y1.data_ptr())
self.assertEqual(x.data_ptr(), y2.data_ptr())
self.assertEqual(str(x.place), str(y1.place))
self.assertEqual(str(x.place), str(y2.place))
self.assertEqual(y1.shape, [0, 10])
self.assertEqual(y2.shape, [0, 10])
self.assertEqual(y1.numel().item(), 0)
self.assertEqual(y2.numel().item(), 0)
np.testing.assert_array_equal(x.numpy(), y1.numpy())
np.testing.assert_array_equal(x.numpy(), y2.numpy())


class TestRaiseError(unittest.TestCase):
def test_to_dlpack_raise_type_error(self):
self.assertRaises(TypeError, paddle.utils.dlpack.to_dlpack, np.zeros(5))
self.assertRaises(TypeError, paddle.to_dlpack, np.zeros(5))


if __name__ == "__main__":
Expand Down