diff --git a/binarycpython/utils/cache.py b/binarycpython/utils/cache.py index 958cfbc048e5399bd5e2625230d85bd317486a33..021f1bcc341fbb3bcdb4ab52a02af6e79ff9a1fe 100644 --- a/binarycpython/utils/cache.py +++ b/binarycpython/utils/cache.py @@ -6,12 +6,15 @@ cache of the appropriate size for the task in the grid_options dict. Please see the LRU_* options in there. """ + import cachetools -import curses +import contextlib import functools import importlib -import inspect +import os +import sys import time +import tempfile class cache(): class NullCache(cachetools.Cache): @@ -154,70 +157,62 @@ class cache(): Args: dt (default 5) in seconds the length of each test. Long is more accurate, but takes longer (obviously). """ - cachetypes = ("NullCache","FIFOCache","LRUCache","TTLCache","NoCache") + # loop lists + cachetypes = ("NoCache","NullCache","FIFOCache","LRUCache","TTLCache") functions = self.grid_options['function_cache_functions'].keys() maxsizes = (0,1,2,4,8,16,32,64,128,256) - stdscr = curses.initscr() - #curses.noecho() - stdscr.clear() - width = len(maxsizes) * 9 - height = (len(cachetypes) + 2) * len(functions) - - def _coord(n,x,y,xoffset,yoffset): - # map n,x,y,xoffset,yoffset to screen coords - _x = (x + xoffset) * 9 - _y = (len(cachetypes) + 4) * n + (y + yoffset) - return (_x,_y) - - def _print(n,x,y,xoffset,yoffset,str): - # print str at n,x,y,offset - _c = _coord(n,x,y,xoffset,yoffset) - stdscr.addstr(_c[1],_c[0],str) - stdscr.refresh() - self.grid_options['function_cache'] = True for n,func in enumerate(functions): - _print(n,0,0,0,0, - "Cache speed test of function {func}".format(func=func)) + print("Cache speed test of function {func}".format(func=func)) + print("{:18s}".format(""),end='') for x,maxsize in enumerate(maxsizes): - _print(n,x,0,2,1,str(maxsize)) + print("{:>9s}".format(str(maxsize)),end='') + print('') best = 0 best_type = None best_maxsize = None for y,type in enumerate(cachetypes): - _print(n,0,y,0,2,type) + print("{:18s}".format(type),end='') self.grid_options['function_cache_default_type'] = type self.setup_function_cache() (maxsize,cachetype,testargs) = self.grid_options['function_cache_functions'].get(func) + x = func.split('.') modulename = 'binarycpython.utils.' + x[0] module = importlib.import_module(modulename) _method = eval('module.{}.{}'.format(x[0],x[1])) if testargs: + def _func_wrap(*args,**kwargs): + return (args,kwargs) + args,kwargs = eval("_func_wrap({})".format(testargs)) for x,maxsize in enumerate(maxsizes): if type == 'NoCache' and maxsize > 0: continue - t0 = time.time() - count = 0 - while time.time() - t0 < dt: - _method(self,*testargs) - count += 1 + + # redirect stdout to prevent lots of output + with contextlib.redirect_stdout(None): + + # loop for dt seconds + tfin = dt + time.time() + count = 0 + try: + while time.time() < tfin: + _method(self,*args,**kwargs) + count += 1 + except Exception as e: + print("Cache call failed:",e) + self.exit(1) if count < 99999: - _print(n,x,y,2,2,"{:d}".format(count)) + print("{:9d}".format(count),end='') else: - _print(n,x,y,2,2,"{:.2e}".format(float(count))) + print("{:9.2e}".format(float(count)),end='') if count > best: best = count best_type = type best_maxsize = maxsize - _print(n,0,len(cachetypes)+2,0,0,"Best cache type {type} with maxsize {maxsize}".format(type=best_type,maxsize=best_maxsize)) - - stdscr.refresh() - stdscr.getkey() - stdscr.keypad(0) - curses.echo() - print("\npress any key to exit\n") - curses.endwin() + print('') + print("Best cache type {type} with maxsize {maxsize}\n".format(type=best_type,maxsize=best_maxsize)) + return diff --git a/binarycpython/utils/distribution_functions.py b/binarycpython/utils/distribution_functions.py index 88d93b1bd6552d98608d54dc339f259ba6477134..08f0178a470689c30ba3731ea4af9b2c84153999 100644 --- a/binarycpython/utils/distribution_functions.py +++ b/binarycpython/utils/distribution_functions.py @@ -99,9 +99,9 @@ class distribution_functions(): def powerlaw_constant_nocache(self, - min_val: Union[int, float], - max_val: Union[int, float], - k: Union[int, float] + min_val: Union[int, float], + max_val: Union[int, float], + k: Union[int, float] ) -> Union[int, float]: """ Function that returns the constant to normalise a power law diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py index 8e0e0ddccf71a2aa9b2c1d63312358d43a4bcd40..b9b0b9c4777bfeb6cf5607b3ce492a5b407f5c5b 100644 --- a/binarycpython/utils/grid.py +++ b/binarycpython/utils/grid.py @@ -775,8 +775,8 @@ class Population(analytics, # restore from existing HPC files self.HPC_restore() - # set up LRU cache - self.setup_LRU_cache() + # set up function cache + self.setup_function_cache() return @@ -1928,7 +1928,7 @@ class Population(analytics, # Grid run ############################################################ # Set up LRU cache - self.setup_LRU_cache() + self.setup_function_cache() ############################################################ # Dry run and getting starcount diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index c15280a179aa3f5cd243fa4b37804c6895cf8a42..8f6d66d681e5d1389ae2dcd234ddac032bae94cc 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -173,7 +173,7 @@ class grid_options_defaults(): "function_cache_default_type" : "NullCache", # one of LRUCache, LFUCache, FIFOCache, MRUCache, RRCache, TTLCache, NullCache, NoCache "function_cache_TTL" : 30, "function_cache_functions" : { - # key=function_name : value=(cache_size, cache_type, test_args) + # key=function_name : value=(cache_size, cache_type, test_args (string)) # # if cache_size is 0, use function_cache_default_maxsize # set above @@ -182,16 +182,14 @@ class grid_options_defaults(): # set above # # if n is None, no cache is set up - "distribution_functions.powerlaw_constant" : (0, None, (1,100,-2)), - "distribution_functions.calculate_constants_three_part_powerlaw" : (4, None, (0.1,0.5,1,100,-1.3,-2.3,-2.3)), - "distribution_functions.gaussian_normalizing_const" : (0, None, (1.0,1.0,-10.0,+10.0)), - #"spacing_functions.const_linear" : (0, None, None), - #"spacing_functions.const_int" : (0, None, None), - #"spacing_functions.const_ranges" : (0, None, None), - #"spacing_functions.gaussian_zoom" : (0, None, None), - #"spacing_functions.const_dt" : (0, None, None), - #"spacing_functions.peak_normalized_gaussian_func" : (0, None, None), - }, + "distribution_functions.powerlaw_constant" : (0, "NoCache", "1,100,-2"), + "distribution_functions.calculate_constants_three_part_powerlaw" : (4, None, "0.1,0.5,1,100,-1.3,-2.3,-2.3"), + "distribution_functions.gaussian_normalizing_const" : (0, None, "1.0,1.0,-10.0,+10.0"), + "spacing_functions.const_linear" : (0, None, "1,10,9"), + "spacing_functions.const_int" : (0, None, "1,10,9"), + "spacing_functions.const_ranges" : (0, None, "((0.1,0.65,10),(0.65,0.85,20),(0.85,10.0,10))"), + "spacing_functions.gaussian_zoom" : (0, None, "1.0,10.0,5.0,2.0,0.9,100"), + }, ######################################## # HPC variables diff --git a/binarycpython/utils/spacing_functions.py b/binarycpython/utils/spacing_functions.py index 2f7708accd74e7c0ac882cb7468ddfcef29a9eb0..a16be46c6dc0799fbe47c31e0804c0819e4c4d6e 100644 --- a/binarycpython/utils/spacing_functions.py +++ b/binarycpython/utils/spacing_functions.py @@ -27,7 +27,9 @@ class spacing_functions(): ) def const_linear( self, - min_bound: Union[int, float], max_bound: Union[int, float], steps: int + min_bound: Union[int, float], + max_bound: Union[int, float], + steps: int ) -> list: """ Samples a range linearly. Uses numpy linspace, and returns an array of floats. Do NOT use this for integers. @@ -47,7 +49,9 @@ class spacing_functions(): ) def const_int( self, - min_bound: Union[int, float], max_bound: Union[int, float], steps: int + min_bound: Union[int, float], + max_bound: Union[int, float], + steps: int ) -> list: """ Samples an integer range linearly. Returns a list of ints. @@ -103,12 +107,11 @@ class spacing_functions(): ############################################################ - @cachetools.cachedmethod( - lambda self: self.caches["spacing_functions.peak_normalized_gaussian_func"] - ) def peak_normalized_gaussian_func( self, - x: Union[int, float], mean: Union[int, float], sigma: Union[int, float] + x: Union[int, float], + mean: Union[int, float], + sigma: Union[int, float] ) -> Union[int, float]: """ Function to evaluate a Gaussian at a given point, note @@ -168,7 +171,7 @@ class spacing_functions(): array = np.array([]) while x <= max_bound: array = np.append(array, x) - g = peak_normalized_gaussian_func(x, zoom_mean, zoom_dispersion) + g = self.peak_normalized_gaussian_func(x, zoom_mean, zoom_dispersion) f = 1.0 - zoom_magnitude * g dx = linear_spacing * f x = x + dx