Improve performance of getting and putting MJX device data with large numpy arrays.
ndarray.tobytes() is faster than converting arrays to tuples by orders of magnitude. PiperOrigin-RevId: 605437697 Change-Id: I7d42c10e178b1aec80ff38a82e863e0701c15e62
This commit is contained in:
committed by
Copybara-Service
parent
1fe258fb60
commit
3e2d62c248
@@ -2,6 +2,14 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
Upcoming version (not yet released)
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
MJX
|
||||||
|
^^^
|
||||||
|
|
||||||
|
1. Improved performance of getting and putting device data by using a faster numpy array serialization method.
|
||||||
|
|
||||||
Version 3.1.2 (February 05, 2024)
|
Version 3.1.2 (February 05, 2024)
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -58,12 +58,13 @@ def dataclass(clz: _T) -> _T:
|
|||||||
data_clz.replace = replace
|
data_clz.replace = replace
|
||||||
|
|
||||||
def iterate_clz_with_keys(x):
|
def iterate_clz_with_keys(x):
|
||||||
# numpy arrays are not hashable, so convert them to tuples for jit cache
|
|
||||||
to_tup = lambda x: tuple(x) if len(x.shape) == 1 else tuple(map(to_tup, x))
|
|
||||||
|
|
||||||
def to_meta(field, obj):
|
def to_meta(field, obj):
|
||||||
val = getattr(obj, field.name)
|
val = getattr(obj, field.name)
|
||||||
return (to_tup(val), val.dtype) if isinstance(val, np.ndarray) else val
|
# numpy arrays are not hashable so return raw bytes instead
|
||||||
|
if isinstance(val, np.ndarray):
|
||||||
|
return (val.tobytes(), val.dtype, val.shape)
|
||||||
|
else:
|
||||||
|
return val
|
||||||
|
|
||||||
def to_data(field, obj):
|
def to_data(field, obj):
|
||||||
return (jax.tree_util.GetAttrKey(field.name), getattr(obj, field.name))
|
return (jax.tree_util.GetAttrKey(field.name), getattr(obj, field.name))
|
||||||
@@ -76,7 +77,8 @@ def dataclass(clz: _T) -> _T:
|
|||||||
|
|
||||||
def from_meta(field, meta):
|
def from_meta(field, meta):
|
||||||
if field.type is np.ndarray:
|
if field.type is np.ndarray:
|
||||||
return (field.name, np.array(meta[0], dtype=meta[1]))
|
arr = np.frombuffer(meta[0], dtype=meta[1]).reshape(meta[2])
|
||||||
|
return (field.name, arr)
|
||||||
else:
|
else:
|
||||||
return (field.name, meta)
|
return (field.name, meta)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user