I have a program in Python and I use numba
to compile the code to native and run faster.
I want to accelerate the run even further, and implement a cache for function results - if the function is called twice with the same parameters, the first time the calculation will run and return the result and the same time the function will return the result from the cache.
I tried to implement this with a dict
, where the keys are tuple
s containing the function parameters, and the values are the function return values.
However, numba
doesn't support dictionaries and the support for global variables is limited, so my solution didn't work.
I can't use a numpy.ndarray
and use the indices as the parameters, since some of my parameters are float
s.
The problem i that both the function with cached results and and the calling function are compiled with numba
(if the calling function was a regular python function, I could cache using just Python and not numba
)
How can I implement this result cache with numba
?
============================================
The following code gives an error, saying the Memoize
class is not recognized
from __future__ import annotations
from numba import njit
class Memoize:
def __init__(self, f):
self.f = f
self.memo = {}
def __call__(self, *args):
if args not in self.memo:
self.memo[args] = self.f(*args)
#Warning: You may wish to do a deepcopy here if returning objects
return self.memo[args]
@Memoize
@njit
def bla(a: int, b: float):
for i in range(1_000_000_000):
a *= b
return a
@njit
def caller(x: int):
s = 0
for j in range(x):
s += bla(j % 5, (j + 1) % 5)
return s
if __name__ == "__main__":
print(caller(30))
The error:
Untyped global name 'bla': Cannot determine Numba type of <class '__main__.Memoize'>
File "try_numba2.py", line 30:
def caller(x: int):
<source elided>
for j in range(x):
s += bla(j % 5, (j + 1) % 5)
^
Changing the order of the decorators for bla
gives the following error:
TypeError: The decorated object is not a function (got type <class '__main__.Memoize'>).