From 900ff5f70493f3997446c590f81dfddb807e5669 Mon Sep 17 00:00:00 2001
From: Robert Izzard <r.izzard@surrey.ac.uk>
Date: Sat, 20 Nov 2021 17:28:29 +0000
Subject: [PATCH] remove curses from cache tests, just output to stdout few
 other cleanups

---
 binarycpython/utils/cache.py                  | 75 +++++++++----------
 binarycpython/utils/distribution_functions.py |  6 +-
 binarycpython/utils/grid.py                   |  6 +-
 binarycpython/utils/grid_options_defaults.py  | 20 +++--
 binarycpython/utils/spacing_functions.py      | 17 +++--
 5 files changed, 60 insertions(+), 64 deletions(-)

diff --git a/binarycpython/utils/cache.py b/binarycpython/utils/cache.py
index 958cfbc04..021f1bcc3 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 88d93b1bd..08f0178a4 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 8e0e0ddcc..b9b0b9c47 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 c15280a17..8f6d66d68 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 2f7708acc..a16be46c6 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
-- 
GitLab