view utils/ComputationCache.py @ 18:b4bf37f94e92

prepared to add another annotation
author mitian
date Wed, 09 Dec 2015 16:27:10 +0000
parents 26838b1f560f
children
line wrap: on
line source
#!/usr/bin/env python
# encoding: utf-8
"""
ComputationCache.py

Created by George Fazekas on 2014-09-21.
Copyright (c) 2014 . All rights reserved.

These methods can be used to decorate any function with a caching mechanism to avoid repeating long computations during experimentation.

Example:

m = Meta()
m.cache = True
m.cache_file_base = "filname-with-unique-parameters.txt"

@with_cache(meta)
def some_heavy_function():
	... lots of computation here...
	return numpy_array


Once decorated, some_heavy_function() will only execute once, then the results will be loaded from a file as long as the parametrs 
encoded in cache_file_base don't change. The parameters and function name are appended to the cache file name so the decorator
is safe to use for multiple computationally intense functions. 

The decorator assumes the heavy function returns a singke numpy array or matrix.

"""

import cPickle
import numpy as np
from os.path import join, isdir, dirname

class Meta(object):
	__slots__ = ["cache","cache_file_base","cache_location"]

	
def makedir(output_folder) :
	'''Create a directory tree and set privileges to allow acces to multiple users.'''
	if output_folder and not isdir(output_folder) :
		try:
			from os import makedirs
			makedirs(output_folder,0o777)
		except :
			print "Failed to create directory: %s" %output_folder
			import sys
			sys.exit(-1)
	pass


'''Generic decorator that caches function execution results.'''
def with_cache(meta):
	def wrap(func):
		def file_cache(*args, **kwargs):
			if meta.cache :
				file = "Cache-" + meta.cache_file_base + "-f_%s.txt" %func.__name__
				file = join(getattr(meta,"cache_location",""),file)
				# print func, meta.cache, file			
				try :
					print "Loading data from file <%s>" %file
					return np.loadtxt(file)
				except :
					print "Loading from <%s> failed. Computing new results." %file
					makedir(dirname(file))
					result = func(*args, **kwargs)
					np.savetxt(file,result)
					return result
			else :
				return func(*args, **kwargs)
		return file_cache
	return wrap

def with_pickle_dump(meta):
	def wrap(func):
		def file_cache(*args, **kwargs):
			if meta.cache :
				file = "Cache-" + meta.cache_file_base + "-f_%s-pickle.txt" %func.__name__
				file = join(getattr(meta,"cache_location",""),file)
				file = file.replace(" ","-")
				# print func, meta.cache, file			
				try :
					print "Loading data from file <%s>" %file
					with open(file, 'r') as fh:
						return cPickle.load(fh)
				except :
					print "Loading from <%s> failed. Computing new results." %file
					makedir(dirname(file))
					result = func(*args, **kwargs)
					with open(file, 'w') as f:
						f.write(cPickle.dumps(result))
					return result
			else :
				return func(*args, **kwargs)
		return file_cache
	return wrap