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

354 lines
11 KiB
Python

# Copyright (c) 2023 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
from paddle.jit.sot.opcode_translator.executor.mutable_data import (
MutableData,
MutableDictLikeData,
MutableListLikeData,
)
class VariableBase:
def __init__(self): ...
class ConstVariable(VariableBase):
def __init__(self, value):
self.value = value
def __repr__(self):
return f"ConstVariable({self.value})"
def __eq__(self, other):
if not isinstance(other, ConstVariable):
return False
return self.value == other.value
class DictVariable(VariableBase):
def __init__(self, data):
self.data = data
self.proxy = MutableDictLikeData(data, DictVariable.proxy_getter)
@staticmethod
def proxy_getter(proxy, key):
if key not in proxy.original_data:
return MutableData.Empty()
return ConstVariable(proxy.original_data[key])
def getitem(self, key):
res = self.proxy.get(key)
if isinstance(res, MutableData.Empty):
raise KeyError(f"Key {key} not found")
return res
def setitem(self, key, value):
self.proxy.set(key, value)
def delitem(self, key):
self.proxy.delete(key)
class ListVariable(VariableBase):
def __init__(self, data):
self.data = data
self.proxy = MutableListLikeData(data, ListVariable.proxy_getter)
@staticmethod
def proxy_getter(proxy, key):
if key < 0 or key >= len(proxy.original_data):
return MutableData.Empty()
return ConstVariable(proxy.original_data[key])
def getitem(self, key):
if isinstance(key, int):
res = self.proxy.get(key)
if isinstance(res, MutableData.Empty):
raise IndexError(f"Index {key} out of range")
return res
elif isinstance(key, slice):
return self.proxy.get_all()[key]
else:
raise TypeError(f"Invalid key type {type(key)}")
def __getitem__(self, key):
return self.getitem(key)
def setitem(self, key, value):
if isinstance(key, int):
self.proxy.set(key, value)
elif isinstance(key, slice):
start, end, step = key.indices(self.proxy.length)
indices = list(range(start, end, step))
if step == 1:
# replace a continuous range
for i, idx in enumerate(indices):
self.proxy.delete(idx - i)
for i, item in enumerate(value):
self.proxy.insert(start + i, item)
else:
# replace some elements
if len(indices) != len(value):
raise ValueError(
f"Attempt to replace {len(indices)} items with {len(value)}"
)
for i, idx in enumerate(indices):
self.proxy.set(idx, value[i])
def delitem(self, key):
self.proxy.delete(key)
def insert(self, index, value):
self.proxy.insert(index, value)
def append(self, value):
self.proxy.insert(self.proxy.length, value)
def extend(self, value):
for item in value:
self.append(item)
def pop(self, index=-1):
res = self.getitem(index)
self.delitem(index)
return res
def clear(self):
for i in range(self.proxy.length):
self.delitem(0)
def remove(self, value):
for i in range(self.proxy.length):
if self.getitem(i) == value:
self.delitem(i)
return
raise ValueError(f"Value {value} not found")
def sort(self, key=None, reverse=False):
if key is None:
key = lambda x: x
permutation = list(range(self.proxy.length))
permutation.sort(
key=lambda x: key(self.getitem(x).value), reverse=reverse
)
self.proxy.permutate(permutation)
def reverse(self):
permutation = list(range(self.proxy.length))
permutation.reverse()
self.proxy.permutate(permutation)
class TestMutableDictLikeVariable(unittest.TestCase):
def test_getitem(self):
data = {"a": 1, "b": 2}
var = DictVariable(data)
self.assertEqual(var.getitem("a"), ConstVariable(1))
self.assertEqual(var.getitem("b"), ConstVariable(2))
def test_setitem(self):
data = {"a": 1, "b": 2}
var = DictVariable(data)
var.setitem("a", ConstVariable(3))
self.assertEqual(var.getitem("a"), ConstVariable(3))
var.setitem("c", ConstVariable(4))
self.assertEqual(var.getitem("c"), ConstVariable(4))
def test_delitem(self):
data = {"a": 1, "b": 2}
var = DictVariable(data)
var.delitem("a")
with self.assertRaises(KeyError):
var.getitem("a")
def test_keys(self):
data = {"a": 1, "b": 2}
var = DictVariable(data)
self.assertEqual(list(var.proxy.get_all().keys()), ["a", "b"])
class TestMutableListLikeVariable(unittest.TestCase):
def test_getitem(self):
data = [1, 2, 3]
var = ListVariable(data)
self.assertEqual(var.getitem(0), ConstVariable(1))
self.assertEqual(var.getitem(1), ConstVariable(2))
self.assertEqual(var.getitem(2), ConstVariable(3))
def test_getitem_slice_1(self):
data = [1, 2, 3, 4, 5, 6, 7]
var = ListVariable(data)
self.assertEqual(
var.getitem(slice(0, 3)),
[ConstVariable(1), ConstVariable(2), ConstVariable(3)],
)
self.assertEqual(
var.getitem(slice(4, 1, -1)),
[ConstVariable(5), ConstVariable(4), ConstVariable(3)],
)
self.assertEqual(
var.getitem(slice(1, 5, 2)),
[ConstVariable(2), ConstVariable(4)],
)
def test_getitem_slice_2(self):
data = [1, 2, 3, 4, 5, 6, 7]
var = ListVariable(data)
self.assertEqual(
var[0:3],
[ConstVariable(1), ConstVariable(2), ConstVariable(3)],
)
self.assertEqual(
var[4:1:-1],
[ConstVariable(5), ConstVariable(4), ConstVariable(3)],
)
self.assertEqual(
var[1:5:2],
[ConstVariable(2), ConstVariable(4)],
)
def test_setitem(self):
data = [1, 2, 3]
var = ListVariable(data)
var.setitem(0, ConstVariable(4))
self.assertEqual(var.getitem(0), ConstVariable(4))
var.append(ConstVariable(5))
self.assertEqual(var.getitem(3), ConstVariable(5))
def test_setitem_slice_1(self):
data = [1, 2, 3, 4, 5, 6, 7]
var = ListVariable(data)
var.setitem(slice(0, 3), [ConstVariable(4), ConstVariable(5)])
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [4, 5, 4, 5, 6, 7]],
)
var.setitem(
slice(4, 1, -1),
[ConstVariable(8), ConstVariable(9), ConstVariable(10)],
)
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [4, 5, 10, 9, 8, 7]],
)
def test_setitem_slice_2(self):
data = [1, 2, 3, 4, 5, 6, 7]
var = ListVariable(data)
var.setitem(slice(2, 5, 2), [ConstVariable(8), ConstVariable(9)])
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [1, 2, 8, 4, 9, 6, 7]],
)
def test_delitem(self):
data = [1, 2, 3]
var = ListVariable(data)
var.delitem(0)
with self.assertRaises(IndexError):
var.getitem(2)
var.pop()
with self.assertRaises(IndexError):
var.getitem(1)
def test_insert(self):
data = [1, 2, 3]
var = ListVariable(data)
var.insert(0, ConstVariable(4))
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [4, 1, 2, 3]],
)
var.insert(2, ConstVariable(5))
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [4, 1, 5, 2, 3]],
)
def test_append(self):
data = [1, 2, 3]
var = ListVariable(data)
var.append(ConstVariable(4))
self.assertEqual(var.getitem(3), ConstVariable(4))
def test_extend(self):
data = [1, 2, 3]
var = ListVariable(data)
var.extend([ConstVariable(4), ConstVariable(5)])
self.assertEqual(var.getitem(3), ConstVariable(4))
self.assertEqual(var.getitem(4), ConstVariable(5))
def test_pop(self):
data = [1, 2, 3]
var = ListVariable(data)
self.assertEqual(var.pop(), ConstVariable(3))
self.assertEqual(var.pop(0), ConstVariable(1))
def test_clear(self):
data = [1, 2, 3]
var = ListVariable(data)
var.clear()
self.assertEqual(var.proxy.length, 0)
def test_remove(self):
data = [1, 2, 3]
var = ListVariable(data)
var.remove(ConstVariable(2))
self.assertEqual(var.getitem(0), ConstVariable(1))
self.assertEqual(var.getitem(1), ConstVariable(3))
with self.assertRaises(ValueError):
var.remove(ConstVariable(2))
def test_sort(self):
data = [2, 3, 0, 4, 1, 5]
var = ListVariable(data)
var.sort()
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [0, 1, 2, 3, 4, 5]],
)
def test_sort_with_key(self):
data = [-1, -4, 2, 0, 5, -3]
var = ListVariable(data)
var.sort(key=lambda x: x**2)
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [0, -1, 2, -3, -4, 5]],
)
def test_sort_reverse(self):
data = [2, 3, 0, 4, 1, 5]
var = ListVariable(data)
var.sort(reverse=True)
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [5, 4, 3, 2, 1, 0]],
)
def test_reverse(self):
data = [2, 3, 0, 4, 1, 5]
var = ListVariable(data)
var.reverse()
self.assertEqual(
[var.getitem(i) for i in range(var.proxy.length)],
[ConstVariable(n) for n in [5, 1, 4, 0, 3, 2]],
)
if __name__ == "__main__":
unittest.main()