theano/compile/builders.py
def _recompute_lop_op(self):
        '''
        converts self._lop_op from user supplied form to type(self) instance

        '''
        local_inputs = self.local_inputs
        local_outputs = self.local_outputs
        inp_len = len(local_inputs)
        lop_op = self._lop_op

        if isinstance(lop_op, OpFromGraph):
            if self._lop_op_is_cached:
                return
            assert self._lop_type in ['lop', 'grad'],\
                self.LOP_TYPE_ERR_MSG % self._lop_type
            if self._lop_type == 'grad':
                needed_ninps = inp_len + len(local_outputs)
                ninps = len(lop_op.local_inputs)
                if needed_ninps != ninps:
                    raise ValueError(
                        self.OV_INP_LEN_ERR_MSG % (needed_ninps, ninps))
                # make a wrapper callable

                def lop_op(inps, grads):
                    return self._lop_op(*(inps + grads))
            elif self._lop_type == 'lop':
                # OfG can be directly used in L_op format
                needed_ninps = inp_len + 2 * len(local_outputs)
                ninps = len(lop_op.local_inputs)
                if needed_ninps != ninps:
                    raise ValueError(
                        self.OV_INP_LEN_ERR_MSG % (needed_ninps, ninps))
                self._lop_op_is_cached = True
                self._lop_op_stypes_l = [None] * inp_len
                self._lop_op.kwargs['on_unused_input'] = 'ignore'
                return

        output_grads = [out_t() for out_t in self.output_types]
        fn_grad = partial(
            theano.gradient.grad,
            cost=None,
            disconnected_inputs='ignore',
            return_disconnected='Disconnected',
            null_gradients='return',
            known_grads=OrderedDict(izip(local_outputs, output_grads)))

        assert self._lop_type in ['lop', 'grad'],\
            self.LOP_TYPE_ERR_MSG % self._lop_type
        if self._lop_type == 'lop':
            callable_args = (local_inputs, local_outputs, output_grads)
        elif self._lop_type == 'grad':
            callable_args = (local_inputs, output_grads)

        # we need to convert _lop_op into an OfG instance
        if lop_op == 'default':
            gdefaults_l = fn_grad(wrt=local_inputs)
            all_grads_l, all_grads_ov_l = izip(
                *[OpFromGraph._filter_grad_var(grad, inp) for grad, inp in izip(gdefaults_l, local_inputs)])
            all_grads_l = list(all_grads_l)
            all_grads_ov_l = list(all_grads_ov_l)
        elif isinstance(lop_op, Variable):
            if isinstance(lop_op.type, (DisconnectedType, NullType)):
                all_grads_l = [inp.zeros_like() for inp in local_inputs]
                all_grads_ov_l = [lop_op.type() for _ in range(inp_len)]
            else:
                raise ValueError(self.STYPE_ERR_MSG % lop_op.type)
        elif isinstance(lop_op, list):
            goverrides_l = lop_op
            if len(goverrides_l) != inp_len:
                raise ValueError(
                    'Need to override %d gradients, got %d' % (
                        inp_len, len(goverrides_l)), goverrides_l)
            # compute non-overriding downsteam grads from upstreams grads
            # it's normal some input may be disconnected, thus the 'ignore'
            wrt_l = [lin for lin, gov in izip(
                local_inputs, goverrides_l) if gov == 'default']
            gdefaults = iter(fn_grad(wrt=wrt_l) if wrt_l else [])
            # combine overriding gradients
            all_grads_l = []
            all_grads_ov_l = []
            for inp, fn_gov in izip(local_inputs, goverrides_l):
                if fn_gov == 'default':
                    gnext, gnext_ov = OpFromGraph._filter_grad_var(
                        next(gdefaults), inp)
                    all_grads_l.append(gnext)
                    all_grads_ov_l.append(gnext_ov)
                elif isinstance(fn_gov, Variable):
                    if isinstance(fn_gov.type, (DisconnectedType, NullType)):
                        all_grads_l.append(inp.zeros_like())
                        all_grads_ov_l.append(fn_gov.type())
                    else:
                        raise ValueError(self.STYPE_ERR_MSG % fn_gov.type)
                else:
                    if not callable(fn_gov):
                        raise TypeError(self.TYPE_ERR_MSG % fn_gov)
                    gov, gov_ov = OpFromGraph._filter_grad_var(
                        fn_gov(*callable_args), inp)
                    all_grads_l.append(gov)
                    all_grads_ov_l.append(gov_ov)
        else:
            # callable case
            if not callable(lop_op):
                raise TypeError(self.TYPE_ERR_MSG % lop_op)
            goverrides_l = lop_op(*callable_args)
            if not isinstance(goverrides_l, list):
                raise TypeError(
                    'Gradient/L_op overriding function should return a list, '
                    'got "%s"' % type(goverrides_l))
            all_grads_l, all_grads_ov_l = izip(
                *[OpFromGraph._filter_grad_var(grad, inp)
                  for grad, inp in izip(goverrides_l, local_inputs)])
            if len(all_grads_l) != len(local_inputs):
                raise ValueError(
                    'Gradient/L_op overriding function should return list of '
                    '%d outputs, got %d' % (inp_len, len(all_grads_l)))
        all_grads_l = list(all_grads_l)
        all_grads_ov_l = list(all_grads_ov_l)
        self._lop_op = type(self)(
            inputs=local_inputs + local_outputs + output_grads,
            outputs=all_grads_l,
            inline=self.is_inline,
            name=(None if self.name is None else self.name + '_' + self._lop_type),
            on_unused_input='ignore')
        self._lop_op_stypes_l = all_grads_ov_l
        self._lop_op_is_cached = True
        self._lop_type = 'lop'

        converts self._lop_op from user supplied form to type(self) instance

        
converts self._lop_op from user supplied form to type(self) instance
converts self . _lop_op from user supplied form to type ( self ) instance
def _recompute_lop_op(self):
        local_inputs = self.local_inputs
        local_outputs = self.local_outputs
        inp_len = len(local_inputs)
        lop_op = self._lop_op
        if isinstance(lop_op, OpFromGraph):
            if self._lop_op_is_cached:
                return
            assert self._lop_type in ['lop', 'grad'],\
                self.LOP_TYPE_ERR_MSG % self._lop_type
            if self._lop_type == 'grad':
                needed_ninps = inp_len + len(local_outputs)
                ninps = len(lop_op.local_inputs)
                if needed_ninps != ninps:
                    raise ValueError(
                        self.OV_INP_LEN_ERR_MSG % (needed_ninps, ninps))
                def lop_op(inps, grads):
                    return self._lop_op(*(inps + grads))
            elif self._lop_type == 'lop':
                needed_ninps = inp_len + 2 * len(local_outputs)
                ninps = len(lop_op.local_inputs)
                if needed_ninps != ninps:
                    raise ValueError(
                        self.OV_INP_LEN_ERR_MSG % (needed_ninps, ninps))
                self._lop_op_is_cached = True
                self._lop_op_stypes_l = [None] * inp_len
                self._lop_op.kwargs['on_unused_input'] = 'ignore'
                return
        output_grads = [out_t() for out_t in self.output_types]
        fn_grad = partial(
            theano.gradient.grad,
            cost=None,
            disconnected_inputs='ignore',
            return_disconnected='Disconnected',
            null_gradients='return',
            known_grads=OrderedDict(izip(local_outputs, output_grads)))
        assert self._lop_type in ['lop', 'grad'],\
            self.LOP_TYPE_ERR_MSG % self._lop_type
        if self._lop_type == 'lop':
            callable_args = (local_inputs, local_outputs, output_grads)
        elif self._lop_type == 'grad':
            callable_args = (local_inputs, output_grads)
        if lop_op == 'default':
            gdefaults_l = fn_grad(wrt=local_inputs)
            all_grads_l, all_grads_ov_l = izip(
                *[OpFromGraph._filter_grad_var(grad, inp) for grad, inp in izip(gdefaults_l, local_inputs)])
            all_grads_l = list(all_grads_l)
            all_grads_ov_l = list(all_grads_ov_l)
        elif isinstance(lop_op, Variable):
            if isinstance(lop_op.type, (DisconnectedType, NullType)):
                all_grads_l = [inp.zeros_like() for inp in local_inputs]
                all_grads_ov_l = [lop_op.type() for _ in range(inp_len)]
            else:
                raise ValueError(self.STYPE_ERR_MSG % lop_op.type)
        elif isinstance(lop_op, list):
            goverrides_l = lop_op
            if len(goverrides_l) != inp_len:
                raise ValueError(
                    'Need to override %d gradients, got %d' % (
                        inp_len, len(goverrides_l)), goverrides_l)
            wrt_l = [lin for lin, gov in izip(
                local_inputs, goverrides_l) if gov == 'default']
            gdefaults = iter(fn_grad(wrt=wrt_l) if wrt_l else [])
            all_grads_l = []
            all_grads_ov_l = []
            for inp, fn_gov in izip(local_inputs, goverrides_l):
                if fn_gov == 'default':
                    gnext, gnext_ov = OpFromGraph._filter_grad_var(
                        next(gdefaults), inp)
                    all_grads_l.append(gnext)
                    all_grads_ov_l.append(gnext_ov)
                elif isinstance(fn_gov, Variable):
                    if isinstance(fn_gov.type, (DisconnectedType, NullType)):
                        all_grads_l.append(inp.zeros_like())
                        all_grads_ov_l.append(fn_gov.type())
                    else:
                        raise ValueError(self.STYPE_ERR_MSG % fn_gov.type)
                else:
                    if not callable(fn_gov):
                        raise TypeError(self.TYPE_ERR_MSG % fn_gov)
                    gov, gov_ov = OpFromGraph._filter_grad_var(
                        fn_gov(*callable_args), inp)
                    all_grads_l.append(gov)
                    all_grads_ov_l.append(gov_ov)
        else:
            if not callable(lop_op):
                raise TypeError(self.TYPE_ERR_MSG % lop_op)
            goverrides_l = lop_op(*callable_args)
            if not isinstance(goverrides_l, list):
                raise TypeError(
                    'Gradient/L_op overriding function should return a list, '
                    'got "%s"' % type(goverrides_l))
            all_grads_l, all_grads_ov_l = izip(
                *[OpFromGraph._filter_grad_var(grad, inp)
                  for grad, inp in izip(goverrides_l, local_inputs)])
            if len(all_grads_l) != len(local_inputs):
                raise ValueError(
                    'Gradient/L_op overriding function should return list of '
                    '%d outputs, got %d' % (inp_len, len(all_grads_l)))
        all_grads_l = list(all_grads_l)
        all_grads_ov_l = list(all_grads_ov_l)
        self._lop_op = type(self)(
            inputs=local_inputs + local_outputs + output_grads,
            outputs=all_grads_l,
            inline=self.is_inline,
            name=(None if self.name is None else self.name + '_' + self._lop_type),
            on_unused_input='ignore')
        self._lop_op_stypes_l = all_grads_ov_l
        self._lop_op_is_cached = True
        self._lop_type = 'lop'
def _recompute_lop_op ( self ) : local_inputs = self . local_inputs local_outputs = self . local_outputs inp_len = len ( local_inputs ) lop_op = self . _lop_op if isinstance ( lop_op , OpFromGraph ) : if self . _lop_op_is_cached : return assert self . _lop_type in [ 'lop' , 'grad' ] , self . LOP_TYPE_ERR_MSG % self . _lop_type if self . _lop_type == 'grad' : needed_ninps = inp_len + len ( local_outputs ) ninps = len ( lop_op . local_inputs ) if needed_ninps != ninps : raise ValueError ( self . OV_INP_LEN_ERR_MSG % ( needed_ninps , ninps ) ) def lop_op ( inps , grads ) : return self . _lop_op ( * ( inps + grads ) ) elif self . _lop_type == 'lop' : needed_ninps = inp_len + 2 * len ( local_outputs ) ninps = len ( lop_op . local_inputs ) if needed_ninps != ninps : raise ValueError ( self . OV_INP_LEN_ERR_MSG % ( needed_ninps , ninps ) ) self . _lop_op_is_cached = True self . _lop_op_stypes_l = [ None ] * inp_len self . _lop_op . kwargs [ 'on_unused_input' ] = 'ignore' return output_grads = [ out_t ( ) for out_t in self . output_types ] fn_grad = partial ( theano . gradient . grad , cost = None , disconnected_inputs = 'ignore' , return_disconnected = 'Disconnected' , null_gradients = 'return' , known_grads = OrderedDict ( izip ( local_outputs , output_grads ) ) ) assert self . _lop_type in [ 'lop' , 'grad' ] , self . LOP_TYPE_ERR_MSG % self . _lop_type if self . _lop_type == 'lop' : callable_args = ( local_inputs , local_outputs , output_grads ) elif self . _lop_type == 'grad' : callable_args = ( local_inputs , output_grads ) if lop_op == 'default' : gdefaults_l = fn_grad ( wrt = local_inputs ) all_grads_l , all_grads_ov_l = izip ( * [ OpFromGraph . _filter_grad_var ( grad , inp ) for grad , inp in izip ( gdefaults_l , local_inputs ) ] ) all_grads_l = list ( all_grads_l ) all_grads_ov_l = list ( all_grads_ov_l ) elif isinstance ( lop_op , Variable ) : if isinstance ( lop_op . type , ( DisconnectedType , NullType ) ) : all_grads_l = [ inp . zeros_like ( ) for inp in local_inputs ] all_grads_ov_l = [ lop_op . type ( ) for _ in range ( inp_len ) ] else : raise ValueError ( self . STYPE_ERR_MSG % lop_op . type ) elif isinstance ( lop_op , list ) : goverrides_l = lop_op if len ( goverrides_l ) != inp_len : raise ValueError ( 'Need to override %d gradients, got %d' % ( inp_len , len ( goverrides_l ) ) , goverrides_l ) wrt_l = [ lin for lin , gov in izip ( local_inputs , goverrides_l ) if gov == 'default' ] gdefaults = iter ( fn_grad ( wrt = wrt_l ) if wrt_l else [ ] ) all_grads_l = [ ] all_grads_ov_l = [ ] for inp , fn_gov in izip ( local_inputs , goverrides_l ) : if fn_gov == 'default' : gnext , gnext_ov = OpFromGraph . _filter_grad_var ( next ( gdefaults ) , inp ) all_grads_l . append ( gnext ) all_grads_ov_l . append ( gnext_ov ) elif isinstance ( fn_gov , Variable ) : if isinstance ( fn_gov . type , ( DisconnectedType , NullType ) ) : all_grads_l . append ( inp . zeros_like ( ) ) all_grads_ov_l . append ( fn_gov . type ( ) ) else : raise ValueError ( self . STYPE_ERR_MSG % fn_gov . type ) else : if not callable ( fn_gov ) : raise TypeError ( self . TYPE_ERR_MSG % fn_gov ) gov , gov_ov = OpFromGraph . _filter_grad_var ( fn_gov ( * callable_args ) , inp ) all_grads_l . append ( gov ) all_grads_ov_l . append ( gov_ov ) else : if not callable ( lop_op ) : raise TypeError ( self . TYPE_ERR_MSG % lop_op ) goverrides_l = lop_op ( * callable_args ) if not isinstance ( goverrides_l , list ) : raise TypeError ( 'Gradient/L_op overriding function should return a list, ' 'got "%s"' % type ( goverrides_l ) ) all_grads_l , all_grads_ov_l = izip ( * [ OpFromGraph . _filter_grad_var ( grad , inp ) for grad , inp in izip ( goverrides_l , local_inputs ) ] ) if len ( all_grads_l ) != len ( local_inputs ) : raise ValueError ( 'Gradient/L_op overriding function should return list of ' '%d outputs, got %d' % ( inp_len , len ( all_grads_l ) ) ) all_grads_l = list ( all_grads_l ) all_grads_ov_l = list ( all_grads_ov_l ) self . _lop_op = type ( self ) ( inputs = local_inputs + local_outputs + output_grads , outputs = all_grads_l , inline = self . is_inline , name = ( None if self . name is None else self . name + '_' + self . _lop_type ) , on_unused_input = 'ignore' ) self . _lop_op_stypes_l = all_grads_ov_l self . _lop_op_is_cached = True self . _lop_type = 'lop'
converts self._lop_op from user supplied form to type(self) instance
converts self . _lop_op from user supplied form to type ( self ) instance
'''
        converts self._lop_op from user supplied form to type(self) instance

        ''' # make a wrapper callable # OfG can be directly used in L_op format # we need to convert _lop_op into an OfG instance # compute non-overriding downsteam grads from upstreams grads # it's normal some input may be disconnected, thus the 'ignore' # combine overriding gradients # callable case
self