def __init__(self, valid=None, invalid=None, valid_equivalent=None): ''' Check if variables can be expressed without using variables in invalid. init_valid_equivalent provides a dictionary mapping some invalid variables to valid ones that can be used instead. ''' if valid is None: valid = [] if invalid is None: invalid = [] if valid_equivalent is None: valid_equivalent = OrderedDict() # Nodes that are valid to have in the graph computing outputs self.valid = set(valid) # Nodes that are NOT valid to have in the graph computing outputs self.invalid = set(invalid) # Mapping from invalid variables to equivalent valid ones. self.valid_equivalent = valid_equivalent.copy() self.valid.update(valid_equivalent.values()) self.invalid.update(valid_equivalent.keys())
def __init__(self, valid=None, invalid=None, valid_equivalent=None): ''' Check if variables can be expressed without using variables in invalid. init_valid_equivalent provides a dictionary mapping some invalid variables to valid ones that can be used instead. ''' if valid is None: valid = [] if invalid is None: invalid = [] if valid_equivalent is None: valid_equivalent = OrderedDict() # Nodes that are valid to have in the graph computing outputs self.valid = set(valid) # Nodes that are NOT valid to have in the graph computing outputs self.invalid = set(invalid) # Mapping from invalid variables to equivalent valid ones. self.valid_equivalent = valid_equivalent.copy() self.valid.update(valid_equivalent.values()) self.invalid.update(valid_equivalent.keys())
def __init__(self, valid=None, invalid=None, valid_equivalent=None): if valid is None: valid = [] if invalid is None: invalid = [] if valid_equivalent is None: valid_equivalent = OrderedDict() # Nodes that are valid to have in the graph computing outputs self.valid = set(valid) # Nodes that are NOT valid to have in the graph computing outputs self.invalid = set(invalid) # Mapping from invalid variables to equivalent valid ones. self.valid_equivalent = valid_equivalent.copy() self.valid.update(list(valid_equivalent.values())) self.invalid.update(list(valid_equivalent.keys()))
def __init__(self, valid=None, invalid=None, valid_equivalent=None): if valid is None: valid = [] if invalid is None: invalid = [] if valid_equivalent is None: valid_equivalent = OrderedDict() # Nodes that are valid to have in the graph computing outputs self.valid = set(valid) # Nodes that are NOT valid to have in the graph computing outputs self.invalid = set(invalid) # Mapping from invalid variables to equivalent valid ones. self.valid_equivalent = valid_equivalent.copy() self.valid.update(list(valid_equivalent.values())) self.invalid.update(list(valid_equivalent.keys()))
class Rebroadcast(gof.Op): """ Change the input's broadcastable fields in some predetermined way. See Also -------- unbroadcast <theano.tensor.unbroadcast> addbroadcast <theano.tensor.addbroadcast> patternbroadcast <theano.tensor.patternbroadcast> Notes ----- Works inplace and works for CudaNdarrayType. Example ------- `Rebroadcast((0, True), (1, False))(x)` would make `x` broadcastable in axis 0 and not broadcastable in axis 1. """ view_map = {0: [0]} _f16_ok = True # Mapping from Type to C code (and version) to use. # In the C code, the name of the input variable is %(iname)s, # the output variable is %(oname)s. c_code_and_version = {} check_input = False __props__ = ("axis", ) def __init__(self, *axis): # Sort them to make sure we merge all possible case. items = sorted(axis) self.axis = OrderedDict(items) for axis, broad in iteritems(self.axis): assert isinstance( axis, (numpy.integer, int)), ("Rebroadcast needs integer axes. Got ", axis) assert isinstance(broad, bool), ( "Rebroadcast needs bool for new broadcast pattern. Got ", broad) def __hash__(self): # Need special __hash__ as dict aren't hashable. # no ambiguity because each item key is unique items = sorted(iteritems(self.axis)) return hash((type(self), tuple(items))) def __str__(self): if len(self.axis) == 0: broadcast_pattern = [] else: broadcast_pattern = [ '?' for i in xrange(1 + max(self.axis.keys())) ] for k, v in iteritems(self.axis): broadcast_pattern[k] = str(int(v)) return '%s{%s}' % (self.__class__.__name__, ','.join(broadcast_pattern)) def make_node(self, x): if self.axis.keys() and (x.ndim <= max(self.axis.keys())): raise ValueError('Trying to rebroadcast non-existent dimension') t = x.type.clone(broadcastable=[ self.axis.get(i, b) for i, b in enumerate(x.type.broadcastable) ]) return gof.Apply(self, [x], [t()]) def perform(self, node, inp, out_): x, = inp out, = out_ for axis, value in iteritems(self.axis): if value and x.shape[axis] != 1: raise ValueError('Dimension %s in Rebroadcast\'s input was' ' supposed to be 1 (got %s instead)' % (axis, x.shape[axis])) out[0] = x def grad(self, inp, grads): x, = inp gz, = grads # restore the broadcasting pattern of the input return Rebroadcast(*[(axis, x.type.broadcastable[axis]) for axis, value in iteritems(self.axis)])(gz), def infer_shape(self, node, ishapes): assert len(ishapes) == 1 l = [] one = theano.tensor.basic.constant(1) for ax in xrange(len(ishapes[0])): if self.axis.get(ax, False): l.append(one) else: l.append(ishapes[0][ax]) return [tuple(l)] def R_op(self, inputs, eval_points): if eval_points[0] is None: return [None] return self(*eval_points, **dict(return_list=True)) def c_code(self, node, nodename, inp, out, sub): iname, = inp oname, = out fail = sub['fail'] itype = node.inputs[0].type.__class__ if itype in self.c_code_and_version: code, version = self.c_code_and_version[itype] final_code = "" for axis, value in iteritems(self.axis): if value: final_code += code % locals() return final_code + """ Py_XDECREF(%(oname)s); %(oname)s = %(iname)s; Py_XINCREF(%(oname)s); """ % locals() return super(Rebroadcast, self).c_code(node, nodename, inp, out, sub) def c_code_cache_version(self): version = [] # If any of the c code is unversionned, we have to return () # Else, we will return a list of (type name, version) pairs. for t, (c, v) in sorted(iteritems(self.c_code_and_version), key=lambda pair: str(pair[0])): if not v: warnings.warn("Type %s has C code for Rebroadcast, but it " "has no version. You should add a 'version' " "keyword arg when calling " "register_rebroadcast_c_code." % t, stacklevel=2) return () version.append((str(t), v)) if version: version.append(1) return tuple(version)
class Rebroadcast(gof.Op): """ Change the input's broadcastable fields in some predetermined way. See Also -------- unbroadcast <theano.tensor.unbroadcast> addbroadcast <theano.tensor.addbroadcast> patternbroadcast <theano.tensor.patternbroadcast> Notes ----- Works inplace and works for CudaNdarrayType. Example ------- `Rebroadcast((0, True), (1, False))(x)` would make `x` broadcastable in axis 0 and not broadcastable in axis 1. """ view_map = {0: [0]} _f16_ok = True # Mapping from Type to C code (and version) to use. # In the C code, the name of the input variable is %(iname)s, # the output variable is %(oname)s. c_code_and_version = {} check_input = False __props__ = ("axis",) def __init__(self, *axis): # Sort them to make sure we merge all possible case. items = sorted(axis) self.axis = OrderedDict(items) for axis, broad in iteritems(self.axis): if not isinstance(axis, (numpy.integer, integer_types)): raise TypeError("Rebroadcast needs integer axes. " "Got {}".format(axis)) if not isinstance(broad, (numpy.bool_, bool)): raise TypeError("Rebroadcast needs bool for new broadcast " "pattern. Got {}".format(broad)) def __hash__(self): # Need special __hash__ as dict aren't hashable. # no ambiguity because each item key is unique items = sorted(iteritems(self.axis)) return hash((type(self), tuple(items))) def __str__(self): if len(self.axis) == 0: broadcast_pattern = [] else: broadcast_pattern = ['?' for i in xrange(1 + max(self.axis.keys()))] for k, v in iteritems(self.axis): broadcast_pattern[k] = str(int(v)) return '%s{%s}' % (self.__class__.__name__, ','.join(broadcast_pattern)) def make_node(self, x): if self.axis.keys() and (x.ndim <= max(self.axis.keys())): raise ValueError('Trying to rebroadcast non-existent dimension') t = x.type.clone( broadcastable=[self.axis.get(i, b) for i, b in enumerate(x.type.broadcastable)]) return gof.Apply(self, [x], [t()]) def perform(self, node, inp, out_): x, = inp out, = out_ for axis, value in iteritems(self.axis): if value and x.shape[axis] != 1: raise ValueError('Dimension %s in Rebroadcast\'s input was' ' supposed to be 1 (got %s instead)' % (axis, x.shape[axis])) out[0] = x def grad(self, inp, grads): x, = inp gz, = grads # restore the broadcasting pattern of the input return Rebroadcast(*[(axis, x.type.broadcastable[axis]) for axis, value in iteritems(self.axis)])(gz), def infer_shape(self, node, ishapes): assert len(ishapes) == 1 l = [] one = theano.tensor.basic.constant(1) for ax in xrange(len(ishapes[0])): if self.axis.get(ax, False): l.append(one) else: l.append(ishapes[0][ax]) return [tuple(l)] def R_op(self, inputs, eval_points): if eval_points[0] is None: return [None] return self(*eval_points, **dict(return_list=True)) def c_code(self, node, nodename, inp, out, sub): iname, = inp oname, = out fail = sub['fail'] itype = node.inputs[0].type.__class__ if itype in self.c_code_and_version: code, version = self.c_code_and_version[itype] final_code = "" for axis, value in iteritems(self.axis): if value: final_code += code % locals() return final_code + """ Py_XDECREF(%(oname)s); %(oname)s = %(iname)s; Py_XINCREF(%(oname)s); """ % locals() return super(Rebroadcast, self).c_code(node, nodename, inp, out, sub) def c_code_cache_version(self): version = [] # If any of the c code is unversionned, we have to return () # Else, we will return a list of (type name, version) pairs. for t, (c, v) in sorted(iteritems(self.c_code_and_version), key=lambda pair: str(pair[0])): if not v: warnings.warn("Type %s has C code for Rebroadcast, but it " "has no version. You should add a 'version' " "keyword arg when calling " "register_rebroadcast_c_code." % t, stacklevel=2) return () version.append((str(t), v)) if version: version.append(1) return tuple(version)