Files
simpeg/SimPEG/Utils/DataWrappers.py
T
Brendan Smithyman 29195e6608 Incorporating the first parts of my parallel distributed tools.
DataWrappers.py contains the CommonReducer class, which enables pass-through math operations and function calls on dictionaries.
Parallel.py contains the job scheduler, remote interface (w/ MPI support) and several helper functions.
2015-05-01 17:04:59 -04:00

91 lines
2.6 KiB
Python

class CommonReducer(dict):
'''
Object based on 'dict' that implements the binary addition (obj1 + obj1) and
accumulation (obj += obj2). These operations pass through to the entries in
the commonReducer.
Instances of commonReducer are also callable, with the syntax:
cr(key, value)
this is equivalent to cr += {key: value}.
'''
DISALLOWED = ['__getinitargs__', '__getnewargs__', '__getstate__', '__setstate__']
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
def __add__(self, other):
result = CommonReducer(self)
for key in other.keys():
if key in result:
result[key] = self[key] + other[key]
else:
result[key] = other[key]
return result
def __iadd__(self, other):
for key in other.keys():
if key in self:
self[key] += other[key]
else:
self[key] = other[key]
return self
def __mul__(self, other):
result = CommonReducer()
for key in other.keys():
if key in self:
result[key] = self[key] * other[key]
return result
def __sub__(self, other):
result = CommonReducer()
for key in other.keys():
if key in self:
result[key] = self[key] - other[key]
return result
def __div__(self, other):
result = CommonReducer()
for key in other.keys():
if key in self:
result[key] = self[key] / other[key]
return result
def __getattr__(self, attr):
if not attr in self.DISALLOWED and all((getattr(self[key], attr, None) is not None for key in self)):
if any((callable(getattr(self[key], attr)) for key in self)):
def wrapperFunction(*args, **kwargs):
innerresult = CommonReducer({key: getattr(self[key], attr, None)(*args, **kwargs) for key in self})
if not all((innerresult[key] is None for key in innerresult)):
return innerresult
result = wrapperFunction
else:
return CommonReducer({key: getattr(self[key], attr) for key in self})
else:
raise AttributeError('\'CommonReducer\' object has no attribute \'%s\', and it could not be satisfied through cascade lookup'%attr)
return result
def copy(self):
return CommonReducer(self)
def __call__(self, key, result):
if key in self:
self[key] += result
else:
self[key] = result