chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,353 @@
|
||||
# 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()
|
||||
Reference in New Issue
Block a user