ATLAS Offline Software
Classes | Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
python.AccumulatorCache.AccumulatorDecorator Class Reference
Collaboration diagram for python.AccumulatorCache.AccumulatorDecorator:

Classes

class  CacheStats
 

Public Member Functions

def __init__ (self, func, size, verify, deepCopy)
 
def getInfo (self)
 
def printStats (cls)
 
def suspendCaching (cls)
 
def resumeCaching (cls)
 
def clearCache (cls)
 
def __get__ (self, obj, objtype)
 
def __call__ (self, *args, **kwargs)
 
def __del__ (self)
 

Static Public Attributes

int VERIFY_NOTHING = 0
 
int VERIFY_HASH = 1
 

Private Member Functions

def _getHash (x)
 
def _evict (x)
 
def _evictAll (self)
 
def _callImpl (self, *args, **kwargs)
 

Private Attributes

 _maxSize
 
 _func
 
 _cache
 
 _resultCache
 
 _verify
 
 _deepcopy
 
 _memoize
 

Static Private Attributes

bool _memoize = True
 
 _stats
 

Detailed Description

Class for use in function decorators, implements memoization.

Instances are callable objects that use the
hash value calculated from positional and keyword arguments
to implement memoization. Methods for suspending and 
resuming memoization are provided.

Definition at line 38 of file AccumulatorCache.py.

Constructor & Destructor Documentation

◆ __init__()

def python.AccumulatorCache.AccumulatorDecorator.__init__ (   self,
  func,
  size,
  verify,
  deepCopy 
)
See AccumulatorCache decorator for documentation of arguments.

Definition at line 61 of file AccumulatorCache.py.

61  def __init__(self, func, size, verify, deepCopy):
62  """See AccumulatorCache decorator for documentation of arguments."""
63 
64  functools.update_wrapper(self , func)
65  self._maxSize = size
66  self._func = func
67  self._cache = {}
68  self._resultCache = {}
69  self._verify = verify
70  self._deepcopy = deepCopy
71 
72  if self._verify not in [self.VERIFY_NOTHING, self.VERIFY_HASH]:
73  raise RuntimeError(f"Invalid value for verify ({verify}) in AccumulatorCache for {func}")
74 

◆ __del__()

def python.AccumulatorCache.AccumulatorDecorator.__del__ (   self)

Definition at line 224 of file AccumulatorCache.py.

224  def __del__(self):
225  self._evictAll()
226 
227 

Member Function Documentation

◆ __call__()

def python.AccumulatorCache.AccumulatorDecorator.__call__ (   self,
args,
**  kwargs 
)

Definition at line 144 of file AccumulatorCache.py.

144  def __call__(self, *args, **kwargs):
145  cacheHit = None
146  try:
147  t0 = time.perf_counter()
148  res, cacheHit = self._callImpl(*args, **kwargs)
149  return res
150  except NotHashable as e:
151  _msg.warning(f"Argument value '{repr(e.value)}' in {self._func} is not hashable. "
152  "No caching is performed!")
153  cacheHit = False
154  return self._func(*args, **kwargs) # perform regular function call
155  finally:
156  t1 = time.perf_counter()
157  if cacheHit is True:
158  self._stats[self].hits += 1
159  self._stats[self].t_hits += (t1-t0)
160  elif cacheHit is False:
161  self._stats[self].misses += 1
162  self._stats[self].t_misses += (t1-t0)
163 

◆ __get__()

def python.AccumulatorCache.AccumulatorDecorator.__get__ (   self,
  obj,
  objtype 
)
Support instance methods.

Definition at line 140 of file AccumulatorCache.py.

140  def __get__(self, obj, objtype):
141  """Support instance methods."""
142  return functools.partial(self.__call__, obj)
143 

◆ _callImpl()

def python.AccumulatorCache.AccumulatorDecorator._callImpl (   self,
args,
**  kwargs 
)
private
Implementation of __call__.

Returns: (result, cacheHit)

Definition at line 164 of file AccumulatorCache.py.

164  def _callImpl(self, *args, **kwargs):
165  """Implementation of __call__.
166 
167  Returns: (result, cacheHit)
168  """
169 
170  # AccumulatorCache enabled?
171  if not AccumulatorDecorator._memoize:
172  return (self._func(*args , **kwargs), None)
173 
174  # frozen set makes the order of keyword arguments irrelevant
175  hsh = hash( (tuple(AccumulatorDecorator._getHash(a) for a in args),
176  frozenset((hash(k), AccumulatorDecorator._getHash(v)) for k,v in kwargs.items())) )
177 
178  res = self._cache.get(hsh, None)
179  if res is not None:
180  cacheHit = None
181  if AccumulatorDecorator.VERIFY_HASH == self._verify:
182  resHsh = self._resultCache[hsh]
183  chkHsh = AccumulatorDecorator._getHash(res)
184  if chkHsh != resHsh:
185  _msg.debug("Hash of function result, cached using AccumulatorDecorator, changed.")
186  cacheHit = False
187  res = self._func(*args , **kwargs)
188  self._cache[hsh] = res
189  self._resultCache[hsh] = AccumulatorDecorator._getHash(res)
190  else:
191  cacheHit = True
192  else:
193  cacheHit = True
194 
195  if self._deepcopy:
196  return deepcopy(res), cacheHit
197  else:
198  # shallow copied CA still needs to undergo merging
199  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
200  if isinstance(res, ComponentAccumulator):
201  res._wasMerged=False
202  return res, cacheHit
203 
204  else:
205  _msg.debug('Hash not found in AccumulatorCache for function %s' , self._func)
206  if len(self._cache) >= self._maxSize:
207  _msg.warning("Cache limit (%d) reached for %s.%s",
208  self._maxSize, self._func.__module__, self._func.__name__)
209  oldest = self._cache.pop(next(iter(self._cache)))
210  AccumulatorDecorator._evict(oldest)
211 
212  res = self._func(*args , **kwargs)
213 
214  if AccumulatorDecorator.VERIFY_HASH == self._verify:
215  if len(self._resultCache) >= self._maxSize:
216  del self._resultCache[next(iter(self._resultCache))]
217  self._resultCache[hsh] = AccumulatorDecorator._getHash(res)
218  self._cache[hsh] = res
219  else:
220  self._cache[hsh] = res
221 
222  return (deepcopy(res) if self._deepcopy else res, False)
223 

◆ _evict()

def python.AccumulatorCache.AccumulatorDecorator._evict (   x)
private
Called when x is removed from the cache

Definition at line 128 of file AccumulatorCache.py.

128  def _evict(x):
129  """Called when x is removed from the cache"""
130  if isinstance(x, AccumulatorCachable):
131  x._cacheEvict()
132  elif isinstance(x, Iterable) and not isinstance(x, str):
133  for el in x:
134  AccumulatorDecorator._evict(el)
135 

◆ _evictAll()

def python.AccumulatorCache.AccumulatorDecorator._evictAll (   self)
private

Definition at line 136 of file AccumulatorCache.py.

136  def _evictAll(self):
137  for v in self._cache.values():
138  AccumulatorDecorator._evict(v)
139 

◆ _getHash()

def python.AccumulatorCache.AccumulatorDecorator._getHash (   x)
private

Definition at line 119 of file AccumulatorCache.py.

119  def _getHash(x):
120  if hasattr(x, "athHash"):
121  return x.athHash()
122  elif isinstance(x, Hashable):
123  return hash(x)
124  elif isinstance(x, DataHandle):
125  return hash(repr(x))
126  raise NotHashable(x)
127 

◆ clearCache()

def python.AccumulatorCache.AccumulatorDecorator.clearCache (   cls)
Clear all accumulator caches

Definition at line 110 of file AccumulatorCache.py.

110  def clearCache(cls):
111  """Clear all accumulator caches"""
112  for decor in cls._stats:
113  decor._evictAll()
114  decor._cache.clear()
115  decor._resultCache.clear()
116 
117  cls._stats.clear()
118 

◆ getInfo()

def python.AccumulatorCache.AccumulatorDecorator.getInfo (   self)
Return a dictionary with information about the cache size and cache usage

Definition at line 75 of file AccumulatorCache.py.

75  def getInfo(self):
76  """Return a dictionary with information about the cache size and cache usage"""
77  return {"cache_size" : len(self._cache),
78  "misses" : self._stats[self].misses,
79  "hits" : self._stats[self].hits,
80  "function" : self._func,
81  "result_cache_size" : len(self._resultCache)}
82 

◆ printStats()

def python.AccumulatorCache.AccumulatorDecorator.printStats (   cls)
Print cache statistics

Definition at line 84 of file AccumulatorCache.py.

84  def printStats(cls):
85  """Print cache statistics"""
86  header = "%-70s | Hits (time) | Misses (time) |" % "AccumulatorCache"
87  print("-"*len(header))
88  print(header)
89  print("-"*len(header))
90  # Print sorted by hit+miss time:
91  for func, stats in sorted(cls._stats.items(), key=lambda s:s[1].t_hits+s[1].t_misses, reverse=True):
92  name = f"{func.__module__}.{func.__name__}"
93  if len(name) > 70:
94  name = '...' + name[-67:]
95  print(f"{name:70} | {stats.hits:6} ({stats.t_hits:4.1f}s) | "
96  f"{stats.misses:6} ({stats.t_misses:4.1f}s) |")
97  print("-"*len(header))
98 

◆ resumeCaching()

def python.AccumulatorCache.AccumulatorDecorator.resumeCaching (   cls)
Resume memoization for all instances of AccumulatorDecorator.

Definition at line 105 of file AccumulatorCache.py.

105  def resumeCaching(cls):
106  """Resume memoization for all instances of AccumulatorDecorator."""
107  cls._memoize = True
108 

◆ suspendCaching()

def python.AccumulatorCache.AccumulatorDecorator.suspendCaching (   cls)
Suspend memoization for all instances of AccumulatorDecorator.

Definition at line 100 of file AccumulatorCache.py.

100  def suspendCaching(cls):
101  """Suspend memoization for all instances of AccumulatorDecorator."""
102  cls._memoize = False
103 

Member Data Documentation

◆ _cache

python.AccumulatorCache.AccumulatorDecorator._cache
private

Definition at line 67 of file AccumulatorCache.py.

◆ _deepcopy

python.AccumulatorCache.AccumulatorDecorator._deepcopy
private

Definition at line 70 of file AccumulatorCache.py.

◆ _func

python.AccumulatorCache.AccumulatorDecorator._func
private

Definition at line 66 of file AccumulatorCache.py.

◆ _maxSize

python.AccumulatorCache.AccumulatorDecorator._maxSize
private

Definition at line 65 of file AccumulatorCache.py.

◆ _memoize [1/2]

bool python.AccumulatorCache.AccumulatorDecorator._memoize = True
staticprivate

Definition at line 47 of file AccumulatorCache.py.

◆ _memoize [2/2]

python.AccumulatorCache.AccumulatorDecorator._memoize
private

Definition at line 102 of file AccumulatorCache.py.

◆ _resultCache

python.AccumulatorCache.AccumulatorDecorator._resultCache
private

Definition at line 68 of file AccumulatorCache.py.

◆ _stats

python.AccumulatorCache.AccumulatorDecorator._stats
staticprivate

Definition at line 59 of file AccumulatorCache.py.

◆ _verify

python.AccumulatorCache.AccumulatorDecorator._verify
private

Definition at line 69 of file AccumulatorCache.py.

◆ VERIFY_HASH

int python.AccumulatorCache.AccumulatorDecorator.VERIFY_HASH = 1
static

Definition at line 50 of file AccumulatorCache.py.

◆ VERIFY_NOTHING

int python.AccumulatorCache.AccumulatorDecorator.VERIFY_NOTHING = 0
static

Definition at line 49 of file AccumulatorCache.py.


The documentation for this class was generated from the following file:
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:797
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
PyAthena::repr
std::string repr(PyObject *o)
returns the string representation of a python object equivalent of calling repr(o) in python
Definition: PyAthenaUtils.cxx:106
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
python.processes.powheg.ZZ.ZZ.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZ.py:18
dlldep.printStats
def printStats()
Definition: dlldep.py:226
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
python.AthDsoLogger.__del__
def __del__(self)
Definition: AthDsoLogger.py:82
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127