annotate utils/ComputationCache.py @ 19:890cfe424f4a tip

added annotations
author mitian
date Fri, 11 Dec 2015 09:47:40 +0000
parents 26838b1f560f
children
rev   line source
mi@0 1 #!/usr/bin/env python
mi@0 2 # encoding: utf-8
mi@0 3 """
mi@0 4 ComputationCache.py
mi@0 5
mi@0 6 Created by George Fazekas on 2014-09-21.
mi@0 7 Copyright (c) 2014 . All rights reserved.
mi@0 8
mi@0 9 These methods can be used to decorate any function with a caching mechanism to avoid repeating long computations during experimentation.
mi@0 10
mi@0 11 Example:
mi@0 12
mi@0 13 m = Meta()
mi@0 14 m.cache = True
mi@0 15 m.cache_file_base = "filname-with-unique-parameters.txt"
mi@0 16
mi@0 17 @with_cache(meta)
mi@0 18 def some_heavy_function():
mi@0 19 ... lots of computation here...
mi@0 20 return numpy_array
mi@0 21
mi@0 22
mi@0 23 Once decorated, some_heavy_function() will only execute once, then the results will be loaded from a file as long as the parametrs
mi@0 24 encoded in cache_file_base don't change. The parameters and function name are appended to the cache file name so the decorator
mi@0 25 is safe to use for multiple computationally intense functions.
mi@0 26
mi@0 27 The decorator assumes the heavy function returns a singke numpy array or matrix.
mi@0 28
mi@0 29 """
mi@0 30
mi@0 31 import cPickle
mi@0 32 import numpy as np
mi@0 33 from os.path import join, isdir, dirname
mi@0 34
mi@0 35 class Meta(object):
mi@0 36 __slots__ = ["cache","cache_file_base","cache_location"]
mi@0 37
mi@0 38
mi@0 39 def makedir(output_folder) :
mi@0 40 '''Create a directory tree and set privileges to allow acces to multiple users.'''
mi@0 41 if output_folder and not isdir(output_folder) :
mi@0 42 try:
mi@0 43 from os import makedirs
mi@0 44 makedirs(output_folder,0o777)
mi@0 45 except :
mi@0 46 print "Failed to create directory: %s" %output_folder
mi@0 47 import sys
mi@0 48 sys.exit(-1)
mi@0 49 pass
mi@0 50
mi@0 51
mi@0 52 '''Generic decorator that caches function execution results.'''
mi@0 53 def with_cache(meta):
mi@0 54 def wrap(func):
mi@0 55 def file_cache(*args, **kwargs):
mi@0 56 if meta.cache :
mi@0 57 file = "Cache-" + meta.cache_file_base + "-f_%s.txt" %func.__name__
mi@0 58 file = join(getattr(meta,"cache_location",""),file)
mi@0 59 # print func, meta.cache, file
mi@0 60 try :
mi@0 61 print "Loading data from file <%s>" %file
mi@0 62 return np.loadtxt(file)
mi@0 63 except :
mi@0 64 print "Loading from <%s> failed. Computing new results." %file
mi@0 65 makedir(dirname(file))
mi@0 66 result = func(*args, **kwargs)
mi@0 67 np.savetxt(file,result)
mi@0 68 return result
mi@0 69 else :
mi@0 70 return func(*args, **kwargs)
mi@0 71 return file_cache
mi@0 72 return wrap
mi@0 73
mi@0 74 def with_pickle_dump(meta):
mi@0 75 def wrap(func):
mi@0 76 def file_cache(*args, **kwargs):
mi@0 77 if meta.cache :
mi@0 78 file = "Cache-" + meta.cache_file_base + "-f_%s-pickle.txt" %func.__name__
mi@0 79 file = join(getattr(meta,"cache_location",""),file)
mi@0 80 file = file.replace(" ","-")
mi@0 81 # print func, meta.cache, file
mi@0 82 try :
mi@0 83 print "Loading data from file <%s>" %file
mi@0 84 with open(file, 'r') as fh:
mi@0 85 return cPickle.load(fh)
mi@0 86 except :
mi@0 87 print "Loading from <%s> failed. Computing new results." %file
mi@0 88 makedir(dirname(file))
mi@0 89 result = func(*args, **kwargs)
mi@0 90 with open(file, 'w') as f:
mi@0 91 f.write(cPickle.dumps(result))
mi@0 92 return result
mi@0 93 else :
mi@0 94 return func(*args, **kwargs)
mi@0 95 return file_cache
mi@0 96 return wrap
mi@0 97
mi@0 98