added algos/utils folder and npmemo
This commit is contained in:
4
dap/algos/utils/__init__.py
Normal file
4
dap/algos/utils/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
from .npmemo import npmemo
|
||||||
|
|
||||||
|
|
77
dap/algos/utils/npmemo.py
Normal file
77
dap/algos/utils/npmemo.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import functools
|
||||||
|
#import hashlib
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def npmemo(func):
|
||||||
|
"""
|
||||||
|
numpy array aware memoizer
|
||||||
|
"""
|
||||||
|
cache = {}
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(*args):
|
||||||
|
key = make_key(args)
|
||||||
|
try:
|
||||||
|
return cache[key]
|
||||||
|
except KeyError:
|
||||||
|
cache[key] = res = func(*args)
|
||||||
|
return res
|
||||||
|
|
||||||
|
# wrapper.cache = cache
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def make_key(args):
|
||||||
|
return tuple(make_key_entry(i) for i in args)
|
||||||
|
|
||||||
|
def make_key_entry(x):
|
||||||
|
if isinstance(x, np.ndarray):
|
||||||
|
return np_array_hash(x)
|
||||||
|
return x
|
||||||
|
|
||||||
|
def np_array_hash(arr):
|
||||||
|
# return id(arr) # this has been used so far
|
||||||
|
res = arr.tobytes()
|
||||||
|
# res = hashlib.sha256(res).hexdigest() # if tobytes was too large, we could hash it
|
||||||
|
# res = (arr.shape, res) # tobytes does not take shape into account
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
@npmemo
|
||||||
|
def expensive(arr, offset):
|
||||||
|
print("recalc", arr, offset)
|
||||||
|
return np.dot(arr, arr) + offset
|
||||||
|
|
||||||
|
def test(arr, offset):
|
||||||
|
print("first")
|
||||||
|
res1 = expensive(arr, offset)
|
||||||
|
print("second")
|
||||||
|
res2 = expensive(arr, offset)
|
||||||
|
print()
|
||||||
|
assert np.array_equal(res1, res2)
|
||||||
|
|
||||||
|
arrays = (
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3, 4],
|
||||||
|
[1, 2, 3, 4]
|
||||||
|
)
|
||||||
|
|
||||||
|
offsets = (
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
5
|
||||||
|
)
|
||||||
|
|
||||||
|
for a, o in zip(arrays, offsets):
|
||||||
|
a = np.array(a)
|
||||||
|
test(a, o)
|
||||||
|
|
||||||
|
# print(expensive.cache)
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user