Skip to content

Commit b7c179a

Browse files
committed
fix lodtensor.py
1 parent 6b95a8a commit b7c179a

File tree

2 files changed

+73
-57
lines changed

2 files changed

+73
-57
lines changed

python/paddle/fluid/lod_tensor.py

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@
1818
__all__ = ['create_lod_tensor', 'create_random_int_lodtensor']
1919

2020

21-
def create_lod_tensor(data, lod, place):
21+
def create_lod_tensor(data, recursive_seq_lens, place):
2222
"""
2323
Create a lod tensor from a numpy array, a list, or an existing lod tensor.
2424
2525
Create a lod tensor by doing the following:
2626
27-
1. Check that the length-based input lod is valid.
27+
1. Check that the length-based level of detail (LoD) also known as
28+
recursive_sequence_lengths of the input is valid.
2829
29-
2. Convert the length-based lod to a offset-based LoD.
30+
2. Convert recursive_sequence_lengths to a offset-based LoD.
3031
3132
3. Copy the data from a numpy array, a list or a existing lod tensor to
3233
CPU or GPU device (based on input place).
@@ -37,45 +38,47 @@ def create_lod_tensor(data, lod, place):
3738
3839
Suppose we want LoDTensor to hold data for sequences of word, where each
3940
word is represented by an integer. If we want to create a LoDTensor to
40-
represent two sentences, one of 2 words, and one of 3 words.
41+
represent two sentences, one of 2 words, and one of 3 words.
4142
4243
Then :code:`data` can be a numpy array of integers with shape (5, 1).
43-
:code:`lod` will be [[2, 3]], indicating the length(# of words) in each
44-
sentence. This length-based input lod [[2, 3]] will be converted to
45-
offset-based lod [[0, 2, 5]] inside the function call.
44+
:code:`recursive_seq_lens` will be [[2, 3]], indicating the length(# of words) in each
45+
sentence. This length-based :code:`recursive_seq_lens` [[2, 3]] will be converted to
46+
offset-based LoD [[0, 2, 5]] inside the function call.
4647
4748
Please reference :ref:`api_guide_low_level_lod_tensor` for more details
4849
regarding LoD.
4950
5051
Args:
5152
data(numpy.ndarray|list|LoDTensor): a numpy array or a LoDTensor or a
52-
list holding the data to be copied.
53-
lod(list): a list of lists indicating the length-based LoD info
54-
specified by the user.
53+
list holding the data to be copied.
54+
recursive_seq_lens(list): a list of lists indicating the length-based level of detail
55+
info specified by the user.
5556
place(Place): CPU or GPU place indicating where the data in the new
5657
LoDTensor will be stored.
5758
5859
Returns:
59-
A fluid LoDTensor object with tensor data and lod info.
60+
A fluid LoDTensor object with tensor data and recursive_seq_lens info.
6061
"""
6162
if isinstance(data, core.LoDTensor):
62-
return create_lod_tensor(np.array(data), lod, place)
63+
return create_lod_tensor(np.array(data), recursive_seq_lens, place)
6364
elif isinstance(data, list):
6465
# When input data is a list, it only deal with the case where the base element
6566
# is an index of shape [1] and dtype int64 (e.g., word id). Hence, the generated
6667
# LoDTensor will be of shape [n, 1] and dtype int64, where `n` is the total number
6768
# of words or other indexes in the sequence.
68-
new_lod = []
69+
new_recursive_seq_lens = []
6970
for seq in data:
70-
new_lod.append(len(seq))
71-
assert [new_lod] == lod, "data and lod do not match"
71+
new_recursive_seq_lens.append(len(seq))
72+
assert [
73+
new_recursive_seq_lens
74+
] == recursive_seq_lens, "data and recursive_seq_lens do not match"
7275
flattened_data = np.concatenate(data, axis=0).astype("int64")
7376
flattened_data = flattened_data.reshape([len(flattened_data), 1])
74-
return create_lod_tensor(flattened_data, lod, place)
77+
return create_lod_tensor(flattened_data, recursive_seq_lens, place)
7578
elif isinstance(data, np.ndarray):
7679
tensor = core.LoDTensor()
7780
tensor.set(data, place)
78-
tensor.set_recursive_sequence_lengths(lod)
81+
tensor.set_recursive_sequence_lengths(recursive_seq_lens)
7982
assert tensor.has_valid_recursive_sequence_lengths(
8083
), "the provided lod info is invalid"
8184
return tensor
@@ -84,7 +87,8 @@ def create_lod_tensor(data, lod, place):
8487
"data should be either a LoDTensor, a Numpy array or a list")
8588

8689

87-
def create_random_int_lodtensor(lod, base_shape, place, low, high):
90+
def create_random_int_lodtensor(recursive_seq_lens, base_shape, place, low,
91+
high):
8892
"""
8993
Create a LoDTensor containing random integers.
9094
@@ -95,7 +99,7 @@ def create_random_int_lodtensor(lod, base_shape, place, low, high):
9599
The function does the following:
96100
97101
1. Calculate the overall shape of the LoDTensor based on the length-based
98-
:code:`lod` input and the shape of the basic element in
102+
:code:`recursive_seq_lens` input and the shape of the basic element in
99103
:code:`base_shape`.
100104
101105
2. Create a numpy array of this shape.
@@ -105,12 +109,13 @@ def create_random_int_lodtensor(lod, base_shape, place, low, high):
105109
Suppose we want LoDTensor to hold data for sequences of word, where each
106110
word is represented by an integer. If we want to create a LoDTensor to
107111
represent two sentences, one of 2 words, and one of 3 words. Then
108-
'base_shape' is [1], input length-based 'lod' is [[2, 3]]. Then the overall
109-
shape of the LoDTensor would be [5, 1], holding 5 words for two sentences.
112+
'base_shape' is [1], input length-based 'recursive_seq_lens' is [[2, 3]].
113+
Then the overall shape of the LoDTensor would be [5, 1], holding 5 words
114+
for two sentences.
110115
111116
Args:
112-
lod(list): a list of lists indicating the length-based LoD info
113-
specified by the user.
117+
recursive_seq_lens(list): a list of lists indicating the length-based
118+
level of detail info specified by the user.
114119
base_shape(list): the shape of the basic element to be held by the
115120
LoDTensor.
116121
place(Place): CPU or GPU place indicating where the data in the new
@@ -119,11 +124,11 @@ def create_random_int_lodtensor(lod, base_shape, place, low, high):
119124
high(int): the upper bound of the random integers.
120125
121126
Returns:
122-
A fluid LoDTensor object with tensor data and lod info.
127+
A fluid LoDTensor object with tensor data and recursive_seq_lens info.
123128
"""
124129
assert isinstance(base_shape, list), "base_shape should be a list"
125130
# append the total number of basic elements to the front of its shape
126-
overall_shape = [sum(lod[-1])] + base_shape
131+
overall_shape = [sum(recursive_seq_lens[-1])] + base_shape
127132
# the range of integer data elements is [low, high]
128133
data = np.random.random_integers(low, high, overall_shape).astype("int64")
129-
return create_lod_tensor(data, lod, place)
134+
return create_lod_tensor(data, recursive_seq_lens, place)

python/paddle/fluid/tests/test_lod_tensor.py

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,68 +19,79 @@
1919

2020

2121
class TestLoDTensor(unittest.TestCase):
22-
def test_pybind_lod(self):
22+
def test_pybind_recursive_seq_lens(self):
2323
tensor = fluid.LoDTensor()
24-
lod = []
25-
tensor.set_recursive_sequence_lengths(lod)
26-
lod = [[], [1], [3]]
27-
self.assertRaises(Exception, tensor.set_recursive_sequence_lengths, lod)
28-
lod = [[0], [2], [3]]
29-
self.assertRaises(Exception, tensor.set_recursive_sequence_lengths, lod)
24+
recursive_seq_lens = []
25+
tensor.set_recursive_sequence_lengths(recursive_seq_lens)
26+
recursive_seq_lens = [[], [1], [3]]
27+
self.assertRaises(Exception, tensor.set_recursive_sequence_lengths,
28+
recursive_seq_lens)
29+
recursive_seq_lens = [[0], [2], [3]]
30+
self.assertRaises(Exception, tensor.set_recursive_sequence_lengths,
31+
recursive_seq_lens)
3032

31-
lod = [[1, 2, 3]]
32-
tensor.set_recursive_sequence_lengths(lod)
33-
self.assertEqual(tensor.recursive_sequence_lengths(), lod)
33+
recursive_seq_lens = [[1, 2, 3]]
34+
tensor.set_recursive_sequence_lengths(recursive_seq_lens)
35+
self.assertEqual(tensor.recursive_sequence_lengths(),
36+
recursive_seq_lens)
3437
tensor.set(np.random.random([6, 1]), fluid.CPUPlace())
3538
self.assertTrue(tensor.has_valid_recursive_sequence_lengths())
3639
tensor.set(np.random.random([9, 1]), fluid.CPUPlace())
3740
self.assertFalse(tensor.has_valid_recursive_sequence_lengths())
3841

3942
# Each level's sum should be equal to the number of items in the next level
4043
# Moreover, last level's sum should be equal to the tensor height
41-
lod = [[2, 3], [1, 3, 1, 2, 2]]
42-
tensor.set_recursive_sequence_lengths(lod)
43-
self.assertEqual(tensor.recursive_sequence_lengths(), lod)
44+
recursive_seq_lens = [[2, 3], [1, 3, 1, 2, 2]]
45+
tensor.set_recursive_sequence_lengths(recursive_seq_lens)
46+
self.assertEqual(tensor.recursive_sequence_lengths(),
47+
recursive_seq_lens)
4448
tensor.set(np.random.random([8, 1]), fluid.CPUPlace())
4549
self.assertFalse(tensor.has_valid_recursive_sequence_lengths())
46-
lod = [[2, 3], [1, 3, 1, 2, 1]]
47-
tensor.set_recursive_sequence_lengths(lod)
50+
recursive_seq_lens = [[2, 3], [1, 3, 1, 2, 1]]
51+
tensor.set_recursive_sequence_lengths(recursive_seq_lens)
4852
self.assertTrue(tensor.has_valid_recursive_sequence_lengths())
4953
tensor.set(np.random.random([9, 1]), fluid.CPUPlace())
5054
self.assertFalse(tensor.has_valid_recursive_sequence_lengths())
5155

5256
def test_create_lod_tensor(self):
5357
# Create LoDTensor from a list
5458
data = [[1, 2, 3], [3, 4]]
55-
wrong_lod = [[2, 2]]
56-
correct_lod = [[3, 2]]
57-
self.assertRaises(AssertionError, create_lod_tensor, data, wrong_lod,
58-
fluid.CPUPlace())
59-
tensor = create_lod_tensor(data, correct_lod, fluid.CPUPlace())
60-
self.assertEqual(tensor.recursive_sequence_lengths(), correct_lod)
59+
wrong_recursive_seq_lens = [[2, 2]]
60+
correct_recursive_seq_lens = [[3, 2]]
61+
self.assertRaises(AssertionError, create_lod_tensor, data,
62+
wrong_recursive_seq_lens, fluid.CPUPlace())
63+
tensor = create_lod_tensor(data, correct_recursive_seq_lens,
64+
fluid.CPUPlace())
65+
self.assertEqual(tensor.recursive_sequence_lengths(),
66+
correct_recursive_seq_lens)
6167

6268
# Create LoDTensor from numpy array
6369
data = np.random.random([10, 1])
64-
lod = [[2, 1], [3, 3, 4]]
65-
tensor = create_lod_tensor(data, lod, fluid.CPUPlace())
66-
self.assertEqual(tensor.recursive_sequence_lengths(), lod)
70+
recursive_seq_lens = [[2, 1], [3, 3, 4]]
71+
tensor = create_lod_tensor(data, recursive_seq_lens, fluid.CPUPlace())
72+
self.assertEqual(tensor.recursive_sequence_lengths(),
73+
recursive_seq_lens)
6774

6875
# Create LoDTensor from another LoDTensor, they are differnt instances
69-
new_lod = [[2, 2, 1], [1, 2, 2, 3, 2]]
70-
new_tensor = create_lod_tensor(tensor, new_lod, fluid.CPUPlace())
71-
self.assertEqual(tensor.recursive_sequence_lengths(), lod)
72-
self.assertEqual(new_tensor.recursive_sequence_lengths(), new_lod)
76+
new_recursive_seq_lens = [[2, 2, 1], [1, 2, 2, 3, 2]]
77+
new_tensor = create_lod_tensor(tensor, new_recursive_seq_lens,
78+
fluid.CPUPlace())
79+
self.assertEqual(tensor.recursive_sequence_lengths(),
80+
recursive_seq_lens)
81+
self.assertEqual(new_tensor.recursive_sequence_lengths(),
82+
new_recursive_seq_lens)
7383

7484
def test_create_random_int_lodtensor(self):
7585
# The shape of a word, commonly used in speech and NLP problem, is [1]
7686
shape = [1]
77-
lod = [[2, 3, 5]]
87+
recursive_seq_lens = [[2, 3, 5]]
7888
dict_size = 10000
7989
low = 0
8090
high = dict_size - 1
81-
tensor = create_random_int_lodtensor(lod, shape,
91+
tensor = create_random_int_lodtensor(recursive_seq_lens, shape,
8292
fluid.CPUPlace(), low, high)
83-
self.assertEqual(tensor.recursive_sequence_lengths(), lod)
93+
self.assertEqual(tensor.recursive_sequence_lengths(),
94+
recursive_seq_lens)
8495
self.assertEqual(tensor.shape(), [10, 1])
8596

8697

0 commit comments

Comments
 (0)