Files
paddlepaddle--paddle/test/legacy_test/test_size.py
T
2026-07-13 12:40:42 +08:00

286 lines
9.0 KiB
Python

# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# 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.
import unittest
import numpy as np
import paddle
class TestPaddleSize(unittest.TestCase):
def test_tensor_size(self):
x = paddle.empty(3, 4, 5)
size = x.size()
self.assertEqual(size, (3, 4, 5))
self.assertIsInstance(size, paddle.Size)
int_size = x.size(dim=1)
self.assertEqual(int_size, 4)
self.assertIsInstance(int_size, int)
def test_creation_size(self):
size = paddle.Size()
self.assertEqual(size, ())
self.assertIsInstance(size, list)
self.assertIsInstance(size, paddle.Size)
size = paddle.Size([2, 3, 4])
self.assertEqual(size, (2, 3, 4))
self.assertIsInstance(size, paddle.Size)
size = paddle.Size((2, 3, 4))
self.assertEqual(size, (2, 3, 4))
self.assertIsInstance(size, paddle.Size)
tensor1 = paddle.to_tensor(2)
tensor2 = paddle.to_tensor(3)
size = paddle.Size([tensor1, tensor2])
self.assertEqual(size, (2, 3))
self.assertIsInstance(size, paddle.Size)
tensor3 = paddle.to_tensor([2, 3])
size = paddle.Size(tensor3)
self.assertEqual(size, (2, 3))
self.assertIsInstance(size, paddle.Size)
size = paddle.Size([True, False])
self.assertEqual(size, (1, 0))
self.assertIsInstance(size, paddle.Size)
size = paddle.Size([np.int64(8), np.int64(8)])
self.assertEqual(size, (8, 8))
self.assertIsInstance(size, paddle.Size)
def test_creation_invalid_type(self):
with self.assertRaises(TypeError):
paddle.Size([1.5, 2.5]) # float not allowed
with self.assertRaises(TypeError):
paddle.Size(["a", "b"]) # string not allowed
def test_creation_from_mixed_types(self):
size = paddle.Size([1, paddle.to_tensor(2), 3])
self.assertEqual(size, (1, 2, 3))
self.assertIsInstance(size, paddle.Size)
def test_getitem_int(self):
size = paddle.Size([2, 3, 4])
self.assertEqual(size[0], 2)
self.assertEqual(size[1], 3)
self.assertEqual(size[2], 4)
self.assertIsInstance(size[0], int)
def test_getitem_slice(self):
size = paddle.Size([2, 3, 4, 5])
sliced = size[1:3]
self.assertEqual(sliced, (3, 4))
self.assertIsInstance(sliced, paddle.Size)
def test_addition(self):
size1 = paddle.Size([2, 3])
size2 = (4, 5)
result = size1 + size2
self.assertEqual(result, (2, 3, 4, 5))
self.assertIsInstance(result, paddle.Size)
def test_raddition(self):
size1 = paddle.Size([2, 3])
size2 = (4, 5)
result = size2 + size1
self.assertEqual(result, (4, 5, 2, 3))
self.assertIsInstance(result, paddle.Size)
def test_addition_invalid_type(self):
size = paddle.Size([2, 3])
with self.assertRaises(TypeError):
size + "abc" # string not allowed
def test_multiplication(self):
size = paddle.Size([2, 3])
result = size * 2
self.assertEqual(result, (2, 3, 2, 3))
self.assertIsInstance(result, paddle.Size)
def test_rmultiplication(self):
size = paddle.Size([2, 3])
result = 2 * size
self.assertEqual(result, (2, 3, 2, 3))
self.assertIsInstance(result, paddle.Size)
def test_multiplication_invalid_type(self):
size = paddle.Size([2, 3])
with self.assertRaises(TypeError):
size * 2.5 # float not allowed
with self.assertRaises(TypeError):
size * "a" # string not allowed
def test_repr(self):
size = paddle.Size([2, 3, 4])
size1 = paddle.Size()
self.assertEqual(repr(size), "paddle.Size([2, 3, 4])")
self.assertEqual(str(size), "paddle.Size([2, 3, 4])")
self.assertEqual(str(size1), "paddle.Size([])")
def test_numel(self):
size = paddle.Size([2, 3, 4])
self.assertEqual(size.numel(), 24) # 2*3*4=24
def test_empty_size_numel(self):
size = paddle.Size([])
self.assertEqual(size.numel(), 1) # Empty size has numel=1
def test_reduce(self):
size = paddle.Size([2, 3])
reduced = size.__reduce__()
self.assertEqual(reduced, (paddle.Size, ((2, 3),)))
# Test reconstruction
new_size = reduced[0](*reduced[1])
self.assertEqual(new_size, size)
self.assertIsInstance(new_size, paddle.Size)
def test_count_index(self):
x = paddle.Size([2, 3]).count(2)
y = paddle.Size([2, 3]).index(3, 0)
self.assertEqual(x, 1)
self.assertEqual(y, 1)
class TestTensorShapeBehavior(unittest.TestCase):
def setUp(self):
self.tensor = paddle.randn([10, 20, 30])
def test_01_type_and_value(self):
s = self.tensor.shape
self.assertIsInstance(
s, paddle.Size, "Tensor.shape should be instance of paddle.Size"
)
self.assertEqual(
type(s),
paddle.Size,
"The exact type of Tensor.shape should be paddle.Size",
)
self.assertIsInstance(s, list, "paddle.Size should inherit from list")
self.assertEqual(s, [10, 20, 30])
self.assertEqual(len(s), 3)
def test_02_edge_cases_0d_and_1d(self):
scalar = paddle.to_tensor(100)
s_scalar = scalar.shape
self.assertEqual(type(s_scalar), paddle.Size)
self.assertEqual(s_scalar, [])
self.assertEqual(len(s_scalar), 0)
vector = paddle.to_tensor([1, 2, 3])
s_vector = vector.shape
self.assertEqual(type(s_vector), paddle.Size)
self.assertEqual(s_vector, [3])
self.assertEqual(len(s_vector), 1)
def test_03_indexing_and_slicing(self):
s = self.tensor.shape
self.assertEqual(s[0], 10)
self.assertEqual(s[-1], 30)
self.assertIsInstance(s[0], int)
s_slice = s[1:3]
self.assertEqual(s_slice, [20, 30])
self.assertIsInstance(s_slice, paddle.Size)
s_full_slice = s[:]
self.assertEqual(s_full_slice, [10, 20, 30])
self.assertIsInstance(s_full_slice, paddle.Size)
self.assertIsNot(s, s_full_slice)
def test_04_concatenation_add(self):
s = paddle.Size([1, 2])
result_ss = s + paddle.Size([3, 4])
self.assertEqual(result_ss, [1, 2, 3, 4])
self.assertEqual(type(result_ss), paddle.Size)
result_sl = s + [3, 4] # noqa: RUF005
self.assertEqual(result_sl, [1, 2, 3, 4])
self.assertEqual(type(result_sl), paddle.Size)
result_ls = [0, 0] + s # noqa: RUF005
self.assertEqual(result_ls, [0, 0, 1, 2])
self.assertEqual(type(result_ls), paddle.Size)
result_st = s + (3, 4) # noqa: RUF005
self.assertEqual(result_st, [1, 2, 3, 4])
self.assertEqual(type(result_st), paddle.Size)
result_ts = (0, 0) + s # noqa: RUF005
self.assertEqual(result_ts, [0, 0, 1, 2])
self.assertEqual(type(result_ts), paddle.Size)
def test_05_repetition_mul(self):
s = paddle.Size([1, 2])
result_sm = s * 3
self.assertEqual(result_sm, [1, 2, 1, 2, 1, 2])
self.assertEqual(type(result_sm), paddle.Size)
result_ms = 3 * s
self.assertEqual(result_ms, [1, 2, 1, 2, 1, 2])
self.assertEqual(type(result_ms), paddle.Size)
def test_06_custom_methods(self):
s = self.tensor.shape
self.assertTrue(hasattr(s, "numel"))
self.assertEqual(s.numel(), 10 * 20 * 30)
s_scalar = paddle.to_tensor(100).shape
self.assertEqual(s_scalar.numel(), 1)
def test_07_mutability_and_independence(self):
s = self.tensor.shape
original_shape_copy = list(s) # [10, 20, 30]
try:
s.append(40)
s[0] = 99
except Exception as e:
self.fail(f"paddle.Size should support methods like list: {e}")
self.assertEqual(
s, [99, 20, 30, 40], "paddle.Size should support methods like list"
)
self.assertEqual(
self.tensor.shape,
original_shape_copy,
"Modifying a Size object should not modify the original tensor shape",
)
s_new = self.tensor.shape
self.assertEqual(
s_new,
original_shape_copy,
"Calling tensor.shape again should return the unmodified shape",
)
self.assertIsNot(
s, s_new, "Calling tensor.shape should return a new object"
)
if __name__ == "__main__":
unittest.main()