metaopt / optree

OpTree: Optimized PyTree Utilities
https://optree.readthedocs.io
Apache License 2.0
136 stars 6 forks source link

[Feature Request] Comparison with treevalue #10

Closed Benjamin-eecs closed 1 year ago

Benjamin-eecs commented 1 year ago

Motivation

Another tree structure computing solutions: treevalue

Resource

Checklist

XuehaiPan commented 1 year ago

treevalue only support trees that are nested dictionaries with str key paths. It has several limitations and may not be considered a general tree utility library compares to optree.

  1. It will raise an error when the dict keys are not strs, while optree accepts dicts with any key type. As defined in the .pyx source file:

https://github.com/opendilab/treevalue/blob/47142049602c21834941d784c76f1ed1b68c02de/treevalue/tree/tree/tree.pyx#L33-L46

In [1]: from treevalue import TreeValue, raw, flatten

In [2]: t = TreeValue({
   ...:     'a': 1,
   ...:     2: 2.3,
   ...:     'x': {
   ...:         'c': 'str',
   ...:         'd': [1, 2, None],
   ...:         'e': b'bytes',
   ...:     }
   ...: })
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-390fae3ac2be> in <module>
----> 1 t = TreeValue({
      2     'a': 1,
      3     2: 2.3,
      4     'x': {
      5         'c': 'str',

~/Projects/treevalue/treevalue/tree/tree/tree.pyx in treevalue.tree.tree.tree.TreeValue.__init__()
     95             self._st = data._detach()
     96         elif isinstance(data, dict):
---> 97             self._st = _dict_unpack(data)
     98         else:
     99             raise TypeError(

~/Projects/treevalue/treevalue/tree/tree/tree.pyx in treevalue.tree.tree.tree._dict_unpack()
     36     cdef dict result = {}
     37 
---> 38     for k, v in d.items():
     39         if isinstance(v, dict):
     40             result[k] = _dict_unpack(v)

TypeError: Expected unicode, got int
  1. Only dicts are considered as trees, while optree accepts arbitrarily nested Python objects.
In [3]: t = TreeValue([1, 2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-f31962bd91b4> in <module>
----> 1 t = TreeValue([1, 2])

~/Projects/treevalue/treevalue/tree/tree/tree.pyx in treevalue.tree.tree.tree.TreeValue.__init__()
     97             self._st = _dict_unpack(data)
     98         else:
---> 99             raise TypeError(
    100                 "Unknown initialization type for tree value - {type}.".format(
    101                     type=repr(type(data).__name__)))

TypeError: Unknown initialization type for tree value - 'list'.
  1. while it only flattens up to the str-key dictionary structures, nested list/tuple and list/tuple in dict values are leaves:
In [4]: t = TreeValue({
   ...:     'a': 1,
   ...:     'b': 2.3,
   ...:     'x': {
   ...:         'c': 'str',
   ...:         'd': [1, 2, None, {'f': 3}],
   ...:         'e': b'bytes',
   ...:     }
   ...: })

In [5]: flatten(t)
Out[5]: 
[(('a',), 1),
 (('b',), 2.3),
 (('x', 'c'), 'str'),
 (('x', 'd'), [1, 2, None, {'f': 3}]),
 (('x', 'e'), b'bytes')]

The path ('x', 'd') has a leaf value [1, 2, None, {'f': 3}]) (a list with a nested dict) which can be furtherly flattened.

  1. Equal inputs do not imply equal output:
In [6]: t1 = {'a': 1, 'b': 2}
   ...: t2 = {'b': 2, 'a': 1}

In [7]: t1 == t2
True

In [7]: flatten(TreeValue(t1)) == flatten(TreeValue(t2))
False