Package paramz :: Package core :: Module pickleable
[hide private]
[frames] | no frames]

Source Code for Module paramz.core.pickleable

  1  #=============================================================================== 
  2  # Copyright (c) 2015, Max Zwiessele 
  3  # All rights reserved. 
  4  # 
  5  # Redistribution and use in source and binary forms, with or without 
  6  # modification, are permitted provided that the following conditions are met: 
  7  # 
  8  # * Redistributions of source code must retain the above copyright notice, this 
  9  #   list of conditions and the following disclaimer. 
 10  # 
 11  # * Redistributions in binary form must reproduce the above copyright notice, 
 12  #   this list of conditions and the following disclaimer in the documentation 
 13  #   and/or other materials provided with the distribution. 
 14  # 
 15  # * Neither the name of paramz.core.pickleable nor the names of its 
 16  #   contributors may be used to endorse or promote products derived from 
 17  #   this software without specific prior written permission. 
 18  # 
 19  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 20  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 21  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 22  # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
 23  # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 24  # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 25  # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 26  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 27  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 28  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29  #=============================================================================== 
 30   
31 -class Pickleable(object):
32 """ 33 Make an object pickleable (See python doc 'pickling'). 34 35 This class allows for pickling support by Memento pattern. 36 _getstate returns a memento of the class, which gets pickled. 37 _setstate(<memento>) (re-)sets the state of the class to the memento 38 """
39 - def __init__(self, *a, **kw):
40 super(Pickleable, self).__init__()
41 42 #=========================================================================== 43 # Pickling operations 44 #===========================================================================
45 - def pickle(self, f, protocol=-1):
46 """ 47 :param f: either filename or open file object to write to. 48 if it is an open buffer, you have to make sure to close 49 it properly. 50 :param protocol: pickling protocol to use, python-pickle for details. 51 """ 52 try: #Py2 53 import cPickle as pickle 54 if isinstance(f, basestring): 55 with open(f, 'wb') as f: 56 pickle.dump(self, f, protocol) 57 else: 58 pickle.dump(self, f, protocol) 59 except ImportError: #python3 60 import pickle 61 if isinstance(f, str): 62 with open(f, 'wb') as f: 63 pickle.dump(self, f, protocol) 64 else: 65 pickle.dump(self, f, protocol)
66 67 #=========================================================================== 68 # copy and pickling 69 #===========================================================================
70 - def copy(self, memo=None, which=None):
71 """ 72 Returns a (deep) copy of the current parameter handle. 73 74 All connections to parents of the copy will be cut. 75 76 :param dict memo: memo for deepcopy 77 :param Parameterized which: parameterized object which started the copy process [default: self] 78 """ 79 #raise NotImplementedError, "Copy is not yet implemented, TODO: Observable hierarchy" 80 if memo is None: 81 memo = {} 82 import copy 83 # the next part makes sure that we do not include parents in any form: 84 parents = [] 85 if which is None: 86 which = self 87 which.traverse_parents(parents.append) # collect parents 88 for p in parents: 89 if not id(p) in memo :memo[id(p)] = None # set all parents to be None, so they will not be copied 90 if not id(self.gradient) in memo:memo[id(self.gradient)] = None # reset the gradient 91 if not id(self._fixes_) in memo :memo[id(self._fixes_)] = None # fixes have to be reset, as this is now highest parent 92 copy = copy.deepcopy(self, memo) # and start the copy 93 copy._parent_index_ = None 94 copy._trigger_params_changed() 95 return copy
96
97 - def __deepcopy__(self, memo):
98 s = self.__new__(self.__class__) # fresh instance 99 memo[id(self)] = s # be sure to break all cycles --> self is already done 100 import copy 101 s.__setstate__(copy.deepcopy(self.__getstate__(), memo)) # standard copy 102 return s
103
104 - def __getstate__(self):
105 ignore_list = ['_param_array_', # parameters get set from bottom to top 106 '_gradient_array_', # as well as gradients 107 '_optimizer_copy_', 108 'logger', 109 'observers', 110 '_fixes_', # and fixes 111 'cache', # never pickle the cache 112 ] 113 dc = dict() 114 #py3 fix 115 #for k,v in self.__dict__.iteritems(): 116 for k,v in self.__dict__.items(): 117 if k not in ignore_list: 118 dc[k] = v 119 return dc
120
121 - def __setstate__(self, state):
122 self.__dict__.update(state) 123 from .lists_and_dicts import ObserverList 124 from ..caching import FunctionCache 125 self.observers = ObserverList() 126 self.cache = FunctionCache() 127 self._setup_observers() 128 self._optimizer_copy_transformed = False
129