<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import , print_function , division <EOL> from copy import deepcopy <EOL> from theano . compat import izip <EOL> import logging <EOL> import numpy <EOL> import theano . tensor <EOL> from theano . tensor import TensorType <EOL> from theano import gof <EOL> from theano . gof import PureOp , Apply <EOL> from six import iteritems <EOL> from six . moves import xrange <EOL> from theano . compile import optdb <EOL> from theano . tensor import opt <EOL> from theano . scan_module . scan_utils import find_up <EOL> from theano . scan_module . scan_utils import clone <EOL> __docformat__ = '<STR_LIT>' <EOL> __authors__ = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> __copyright__ = "<STR_LIT>" <EOL> __contact__ = "<STR_LIT>" <EOL> _logger = logging . getLogger ( '<STR_LIT>' ) <EOL> class IfElse ( PureOp ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , n_outs , as_view = False , gpu = False , name = None ) : <EOL> if as_view : <EOL> view_map = { } <EOL> for idx in xrange ( n_outs ) : <EOL> view_map [ idx ] = [ idx + <NUM_LIT:1> ] <EOL> self . view_map = view_map <EOL> self . as_view = as_view <EOL> self . gpu = gpu <EOL> self . n_outs = n_outs <EOL> self . name = name <EOL> def __eq__ ( self , other ) : <EOL> if not type ( self ) == type ( other ) : <EOL> return False <EOL> if not self . as_view == other . as_view : <EOL> return False <EOL> if not self . gpu == other . gpu : <EOL> return False <EOL> if not self . n_outs == other . n_outs : <EOL> return False <EOL> return True <EOL> def __hash__ ( self ) : <EOL> rval = ( hash ( type ( self ) ) ^ <EOL> hash ( self . as_view ) ^ <EOL> hash ( self . gpu ) ^ <EOL> hash ( self . n_outs ) ) <EOL> return rval <EOL> def __str__ ( self ) : <EOL> args = [ ] <EOL> if self . name is not None : <EOL> args . append ( self . name ) <EOL> if self . as_view : <EOL> args . append ( '<STR_LIT>' ) <EOL> if self . gpu : <EOL> args . append ( '<STR_LIT>' ) <EOL> return '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( args ) <EOL> def infer_shape ( self , node , inputs_shapes ) : <EOL> ts_shapes = inputs_shapes [ <NUM_LIT:1> : ] [ : self . n_outs ] <EOL> fs_shapes = inputs_shapes [ <NUM_LIT:1> : ] [ self . n_outs : ] <EOL> new_ts_inputs = [ ] <EOL> for ts_shape in ts_shapes : <EOL> if isinstance ( ts_shape , ( list , tuple ) ) : <EOL> new_ts_inputs += list ( ts_shape ) <EOL> else : <EOL> return [ None ] * self . n_outs <EOL> new_fs_inputs = [ ] <EOL> for fs_shape in fs_shapes : <EOL> if isinstance ( fs_shape , ( list , tuple ) ) : <EOL> new_fs_inputs += list ( fs_shape ) <EOL> else : <EOL> return [ None ] * self . n_outs <EOL> assert len ( new_ts_inputs ) == len ( new_fs_inputs ) <EOL> if len ( new_ts_inputs + new_fs_inputs ) > <NUM_LIT:0> : <EOL> name_tokens = [ '<STR_LIT>' ] <EOL> if self . name is not None : <EOL> name_tokens . append ( self . name ) <EOL> new_ifelse = IfElse ( <EOL> n_outs = len ( new_ts_inputs ) , <EOL> as_view = False , <EOL> gpu = False , <EOL> name = '<STR_LIT:_>' . join ( name_tokens ) ) <EOL> new_outs = new_ifelse ( node . inputs [ <NUM_LIT:0> ] , <EOL> * ( new_ts_inputs + new_fs_inputs ) , <EOL> ** dict ( return_list = True ) ) <EOL> else : <EOL> new_outs = [ ] <EOL> out_shapes = [ ] <EOL> for out in node . outputs : <EOL> out_shapes . append ( tuple ( new_outs [ : out . ndim ] ) ) <EOL> new_outs = new_outs [ out . ndim : ] <EOL> assert len ( new_outs ) == <NUM_LIT:0> <EOL> return out_shapes <EOL> def make_node ( self , c , * args ) : <EOL> assert len ( args ) == <NUM_LIT:2> * self . n_outs , ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( <NUM_LIT:2> * self . n_outs , len ( args ) ) <EOL> ) <EOL> if not self . gpu : <EOL> c = theano . tensor . as_tensor_variable ( c ) <EOL> nw_args = [ ] <EOL> for x in args : <EOL> if isinstance ( x , theano . Variable ) : <EOL> nw_args . append ( x ) <EOL> else : <EOL> nw_args . append ( theano . tensor . as_tensor_variable ( x ) ) <EOL> args = nw_args <EOL> ts = args [ : self . n_outs ] <EOL> fs = args [ self . n_outs : ] <EOL> for t , f in izip ( ts , fs ) : <EOL> if t . type != f . type : <EOL> raise TypeError ( ( '<STR_LIT>' <EOL> '<STR_LIT>' ) , t , f , t . type , f . type ) <EOL> if c . ndim > <NUM_LIT:0> : <EOL> raise TypeError ( ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) ) <EOL> return Apply ( self , [ c ] + list ( args ) , [ t . type ( ) for t in ts ] ) <EOL> def R_op ( self , inputs , eval_points ) : <EOL> return self ( inputs [ <NUM_LIT:0> ] , * eval_points [ <NUM_LIT:1> : ] , ** dict ( return_list = True ) ) <EOL> def grad ( self , ins , grads ) : <EOL> ts = ins [ <NUM_LIT:1> : ] [ : self . n_outs ] <EOL> fs = ins [ <NUM_LIT:1> : ] [ self . n_outs : ] <EOL> if self . name is not None : <EOL> nw_name_t = self . name + '<STR_LIT>' <EOL> nw_name_f = self . name + '<STR_LIT>' <EOL> else : <EOL> nw_name_t = None <EOL> nw_name_f = None <EOL> if_true_op = IfElse ( n_outs = self . n_outs , <EOL> as_view = self . as_view , <EOL> gpu = self . gpu , <EOL> name = nw_name_t ) <EOL> if_false_op = IfElse ( n_outs = self . n_outs , <EOL> as_view = self . as_view , <EOL> gpu = self . gpu , <EOL> name = nw_name_f ) <EOL> if_true = ( [ ins [ <NUM_LIT:0> ] ] + grads + [ theano . tensor . zeros_like ( t ) <EOL> for t in ts ] ) <EOL> if_false = ( [ ins [ <NUM_LIT:0> ] ] + [ theano . tensor . zeros_like ( f ) <EOL> for f in fs ] + grads ) <EOL> condition = ins [ <NUM_LIT:0> ] <EOL> condition_grad = condition . zeros_like ( ) . astype ( theano . config . floatX ) <EOL> return ( [ condition_grad ] + <EOL> if_true_op ( * if_true , ** dict ( return_list = True ) ) + <EOL> if_false_op ( * if_false , ** dict ( return_list = True ) ) ) <EOL> def make_thunk ( self , node , storage_map , compute_map , no_recycling ) : <EOL> cond = node . inputs [ <NUM_LIT:0> ] <EOL> ts = node . inputs [ <NUM_LIT:1> : ] [ : self . n_outs ] <EOL> fs = node . inputs [ <NUM_LIT:1> : ] [ self . n_outs : ] <EOL> outputs = node . outputs <EOL> def thunk ( ) : <EOL> if not compute_map [ cond ] [ <NUM_LIT:0> ] : <EOL> return [ <NUM_LIT:0> ] <EOL> else : <EOL> truthval = storage_map [ cond ] [ <NUM_LIT:0> ] <EOL> if truthval != <NUM_LIT:0> : <EOL> ls = [ idx + <NUM_LIT:1> for idx in xrange ( self . n_outs ) <EOL> if not compute_map [ ts [ idx ] ] [ <NUM_LIT:0> ] ] <EOL> if len ( ls ) > <NUM_LIT:0> : <EOL> return ls <EOL> else : <EOL> for out , t in izip ( outputs , ts ) : <EOL> compute_map [ out ] [ <NUM_LIT:0> ] = <NUM_LIT:1> <EOL> val = storage_map [ t ] [ <NUM_LIT:0> ] <EOL> if self . as_view : <EOL> storage_map [ out ] [ <NUM_LIT:0> ] = val <EOL> elif type ( val ) in ( numpy . ndarray , numpy . memmap ) : <EOL> storage_map [ out ] [ <NUM_LIT:0> ] = val . copy ( ) <EOL> else : <EOL> storage_map [ out ] [ <NUM_LIT:0> ] = deepcopy ( val ) <EOL> return [ ] <EOL> else : <EOL> ls = [ <NUM_LIT:1> + idx + self . n_outs for idx in xrange ( self . n_outs ) <EOL> if not compute_map [ fs [ idx ] ] [ <NUM_LIT:0> ] ] <EOL> if len ( ls ) > <NUM_LIT:0> : <EOL> return ls <EOL> else : <EOL> for out , f in izip ( outputs , fs ) : <EOL> compute_map [ out ] [ <NUM_LIT:0> ] = <NUM_LIT:1> <EOL> val = storage_map [ f ] [ <NUM_LIT:0> ] <EOL> if type ( val ) in ( numpy . ndarray , numpy . memmap ) : <EOL> storage_map [ out ] [ <NUM_LIT:0> ] = val . copy ( ) <EOL> else : <EOL> storage_map [ out ] [ <NUM_LIT:0> ] = deepcopy ( val ) <EOL> return [ ] <EOL> thunk . lazy = True <EOL> thunk . inputs = [ storage_map [ v ] for v in node . inputs ] <EOL> thunk . outputs = [ storage_map [ v ] for v in node . outputs ] <EOL> return thunk <EOL> def ifelse ( condition , then_branch , else_branch , name = None ) : <EOL> """<STR_LIT>""" <EOL> rval_type = None <EOL> if type ( then_branch ) is list : <EOL> rval_type = list <EOL> elif type ( then_branch ) is tuple : <EOL> rval_type = tuple <EOL> if type ( then_branch ) not in ( list , tuple ) : <EOL> then_branch = [ then_branch ] <EOL> if type ( else_branch ) not in ( list , tuple ) : <EOL> else_branch = [ else_branch ] <EOL> new_then_branch = [ ] <EOL> new_else_branch = [ ] <EOL> for then_branch_elem , else_branch_elem in izip ( then_branch , else_branch ) : <EOL> if not isinstance ( then_branch_elem , theano . Variable ) : <EOL> then_branch_elem = theano . tensor . as_tensor_variable ( <EOL> then_branch_elem ) <EOL> if not isinstance ( else_branch_elem , theano . Variable ) : <EOL> else_branch_elem = theano . tensor . as_tensor_variable ( <EOL> else_branch_elem ) <EOL> if then_branch_elem . type != else_branch_elem . type : <EOL> if ( isinstance ( then_branch_elem . type , TensorType ) and not <EOL> isinstance ( else_branch_elem . type , TensorType ) ) : <EOL> else_branch_elem = then_branch_elem . type . filter_variable ( <EOL> else_branch_elem ) <EOL> elif ( isinstance ( else_branch_elem . type , TensorType ) and not <EOL> isinstance ( then_branch_elem . type , TensorType ) ) : <EOL> then_branch_elem = else_branch_elem . type . filter_variable ( <EOL> then_branch_elem ) <EOL> if then_branch_elem . type != else_branch_elem . type : <EOL> raise TypeError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> ( then_branch_elem . type , else_branch_elem . type ) ) <EOL> new_then_branch . append ( then_branch_elem ) <EOL> new_else_branch . append ( else_branch_elem ) <EOL> if len ( then_branch ) != len ( else_branch ) : <EOL> raise ValueError ( ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % len ( then_branch ) + '<STR_LIT>' <EOL> '<STR_LIT>' % len ( else_branch ) + '<STR_LIT:)>' ) ) <EOL> new_ifelse = IfElse ( n_outs = len ( then_branch ) , <EOL> as_view = False , <EOL> gpu = False , <EOL> name = name ) <EOL> ins = [ condition ] + list ( new_then_branch ) + list ( new_else_branch ) <EOL> rval = new_ifelse ( * ins , ** dict ( return_list = True ) ) <EOL> if rval_type is None : <EOL> return rval [ <NUM_LIT:0> ] <EOL> elif rval_type is list : <EOL> return list ( rval ) <EOL> else : <EOL> return tuple ( rval ) <EOL> @ gof . local_optimizer ( [ IfElse ] ) <EOL> def cond_make_inplace ( node ) : <EOL> op = node . op <EOL> if ( isinstance ( op , IfElse ) and <EOL> not op . as_view and <EOL> ( len ( node . fgraph . apply_nodes ) < <NUM_LIT> or <EOL> not all ( [ getattr ( o . type , '<STR_LIT>' , - <NUM_LIT:1> ) == <NUM_LIT:0> <EOL> for o in node . outputs ] ) ) ) : <EOL> return IfElse ( n_outs = op . n_outs , <EOL> as_view = True , <EOL> gpu = op . gpu , <EOL> name = op . name ) ( * node . inputs , ** dict ( return_list = True ) ) <EOL> return False <EOL> optdb . register ( '<STR_LIT>' , opt . in2out ( cond_make_inplace , <EOL> ignore_newtrees = True ) , <NUM_LIT> , '<STR_LIT>' , '<STR_LIT>' ) <EOL> '''<STR_LIT>''' <EOL> acceptable_ops = ( theano . tensor . basic . Dot , <EOL> theano . tensor . basic . Reshape , <EOL> theano . tensor . basic . Shape , <EOL> theano . tensor . SpecifyShape , <EOL> theano . tensor . basic . MaxAndArgmax , <EOL> theano . tensor . Subtensor , <EOL> theano . tensor . IncSubtensor , <EOL> theano . tensor . basic . Rebroadcast , <EOL> theano . tensor . basic . Alloc , <EOL> theano . tensor . elemwise . Elemwise , <EOL> theano . tensor . elemwise . DimShuffle ) <EOL> @ gof . local_optimizer ( acceptable_ops ) <EOL> def ifelse_lift_single_if_through_acceptable_ops ( main_node ) : <EOL> """<STR_LIT>""" <EOL> if not ( isinstance ( main_node . op , acceptable_ops ) ) : <EOL> return False <EOL> all_inp_nodes = set ( ) <EOL> for inp in main_node . inputs : <EOL> all_inp_nodes . add ( inp . owner ) <EOL> ifnodes = [ x for x in list ( all_inp_nodes ) <EOL> if x and isinstance ( x . op , IfElse ) ] <EOL> if len ( ifnodes ) != <NUM_LIT:1> : <EOL> return False <EOL> node = ifnodes [ <NUM_LIT:0> ] <EOL> op = node . op <EOL> ts = node . inputs [ <NUM_LIT:1> : ] [ : op . n_outs ] <EOL> fs = node . inputs [ <NUM_LIT:1> : ] [ op . n_outs : ] <EOL> mop = main_node . op <EOL> true_ins = [ ] <EOL> false_ins = [ ] <EOL> for x in main_node . inputs : <EOL> if x in node . outputs : <EOL> idx = node . outputs . index ( x ) <EOL> true_ins . append ( ts [ idx ] ) <EOL> false_ins . append ( fs [ idx ] ) <EOL> else : <EOL> true_ins . append ( x ) <EOL> false_ins . append ( x ) <EOL> true_eval = mop ( * true_ins , ** dict ( return_list = True ) ) <EOL> false_eval = mop ( * false_ins , ** dict ( return_list = True ) ) <EOL> nw_outs = ifelse ( node . inputs [ <NUM_LIT:0> ] , true_eval , false_eval , return_list = True ) <EOL> return nw_outs <EOL> @ gof . local_optimizer ( [ IfElse ] ) <EOL> def cond_merge_ifs_true ( node ) : <EOL> op = node . op <EOL> if not isinstance ( op , IfElse ) : <EOL> return False <EOL> t_ins = node . inputs [ <NUM_LIT:1> : ] [ : op . n_outs ] <EOL> replace = { } <EOL> for idx , tval in enumerate ( t_ins ) : <EOL> if ( tval . owner and isinstance ( tval . owner . op , IfElse ) and <EOL> tval . owner . inputs [ <NUM_LIT:0> ] == node . inputs [ <NUM_LIT:0> ] ) : <EOL> ins_op = tval . owner . op <EOL> ins_t = tval . owner . inputs [ <NUM_LIT:1> : ] [ : ins_op . n_outs ] <EOL> replace [ idx + <NUM_LIT:1> ] = ins_t [ tval . owner . outputs . index ( tval ) ] <EOL> if len ( replace ) == <NUM_LIT:0> : <EOL> return False <EOL> old_ins = list ( node . inputs ) <EOL> for pos , var in iteritems ( replace ) : <EOL> old_ins [ pos ] = var <EOL> return op ( * old_ins , ** dict ( return_list = True ) ) <EOL> @ gof . local_optimizer ( [ IfElse ] ) <EOL> def cond_merge_ifs_false ( node ) : <EOL> op = node . op <EOL> if not isinstance ( op , IfElse ) : <EOL> return False <EOL> f_ins = node . inputs [ <NUM_LIT:1> : ] [ op . n_outs : ] <EOL> replace = { } <EOL> for idx , fval in enumerate ( f_ins ) : <EOL> if ( fval . owner and isinstance ( fval . owner . op , IfElse ) and <EOL> fval . owner . inputs [ <NUM_LIT:0> ] == node . inputs [ <NUM_LIT:0> ] ) : <EOL> ins_op = fval . owner . op <EOL> ins_t = fval . owner . inputs [ <NUM_LIT:1> : ] [ ins_op . n_outs : ] <EOL> replace [ idx + <NUM_LIT:1> + op . n_outs ] = ins_t [ fval . owner . outputs . index ( fval ) ] <EOL> if len ( replace ) == <NUM_LIT:0> : <EOL> return False <EOL> old_ins = list ( node . inputs ) <EOL> for pos , var in iteritems ( replace ) : <EOL> old_ins [ pos ] = var <EOL> return op ( * old_ins , ** dict ( return_list = True ) ) <EOL> class CondMerge ( gof . Optimizer ) : <EOL> """<STR_LIT>""" <EOL> def add_requirements ( self , fgraph ) : <EOL> fgraph . add_feature ( gof . toolbox . ReplaceValidate ( ) ) <EOL> def apply ( self , fgraph ) : <EOL> nodelist = list ( fgraph . toposort ( ) ) <EOL> cond_nodes = [ s for s in nodelist if isinstance ( s . op , IfElse ) ] <EOL> if len ( cond_nodes ) < <NUM_LIT:2> : <EOL> return False <EOL> merging_node = cond_nodes [ <NUM_LIT:0> ] <EOL> for proposal in cond_nodes [ <NUM_LIT:1> : ] : <EOL> if ( proposal . inputs [ <NUM_LIT:0> ] == merging_node . inputs [ <NUM_LIT:0> ] and <EOL> not find_up ( proposal , merging_node ) ) : <EOL> mn_ts = merging_node . inputs [ <NUM_LIT:1> : ] [ : merging_node . op . n_outs ] <EOL> mn_fs = merging_node . inputs [ <NUM_LIT:1> : ] [ merging_node . op . n_outs : ] <EOL> pl_ts = proposal . inputs [ <NUM_LIT:1> : ] [ : proposal . op . n_outs ] <EOL> pl_fs = proposal . inputs [ <NUM_LIT:1> : ] [ proposal . op . n_outs : ] <EOL> new_ins = ( [ merging_node . inputs [ <NUM_LIT:0> ] ] + <EOL> mn_ts + pl_ts + mn_fs + pl_fs ) <EOL> mn_name = '<STR_LIT:?>' <EOL> if merging_node . op . name : <EOL> mn_name = merging_node . op . name <EOL> pl_name = '<STR_LIT:?>' <EOL> if proposal . op . name : <EOL> pl_name = proposal . op . name <EOL> new_ifelse = IfElse ( <EOL> n_outs = len ( mn_ts + pl_ts ) , <EOL> as_view = False , <EOL> gpu = False , <EOL> name = mn_name + '<STR_LIT:&>' + pl_name ) <EOL> print ( '<STR_LIT>' ) <EOL> new_outs = new_ifelse ( * new_ins , ** dict ( return_list = True ) ) <EOL> new_outs = [ clone ( x ) for x in new_outs ] <EOL> old_outs = [ ] <EOL> if type ( merging_node . outputs ) not in ( list , tuple ) : <EOL> old_outs += [ merging_node . outputs ] <EOL> else : <EOL> old_outs += merging_node . outputs <EOL> if type ( proposal . outputs ) not in ( list , tuple ) : <EOL> old_outs += [ proposal . outputs ] <EOL> else : <EOL> old_outs += proposal . outputs <EOL> pairs = list ( zip ( old_outs , new_outs ) ) <EOL> fgraph . replace_all_validate ( pairs , reason = '<STR_LIT>' ) <EOL> @ gof . local_optimizer ( [ IfElse ] ) <EOL> def cond_remove_identical ( node ) : <EOL> op = node . op <EOL> if not isinstance ( op , IfElse ) : <EOL> return False <EOL> ts = node . inputs [ <NUM_LIT:1> : ] [ : op . n_outs ] <EOL> fs = node . inputs [ <NUM_LIT:1> : ] [ op . n_outs : ] <EOL> out_map = { } <EOL> for idx in xrange ( len ( node . outputs ) ) : <EOL> if idx not in out_map : <EOL> for jdx in xrange ( idx + <NUM_LIT:1> , len ( node . outputs ) ) : <EOL> if ( ts [ idx ] == ts [ jdx ] and <EOL> fs [ idx ] == fs [ jdx ] and <EOL> jdx not in out_map ) : <EOL> out_map [ jdx ] = idx <EOL> if len ( out_map ) == <NUM_LIT:0> : <EOL> return False <EOL> nw_ts = [ ] <EOL> nw_fs = [ ] <EOL> inv_map = { } <EOL> pos = <NUM_LIT:0> <EOL> for idx in xrange ( len ( node . outputs ) ) : <EOL> if idx not in out_map : <EOL> inv_map [ idx ] = pos <EOL> pos = pos + <NUM_LIT:1> <EOL> nw_ts . append ( ts [ idx ] ) <EOL> nw_fs . append ( fs [ idx ] ) <EOL> new_ifelse = IfElse ( n_outs = len ( nw_ts ) , <EOL> as_view = op . as_view , <EOL> gpu = op . gpu , <EOL> name = op . name ) <EOL> new_ins = [ node . inputs [ <NUM_LIT:0> ] ] + nw_ts + nw_fs <EOL> new_outs = new_ifelse ( * new_ins , ** dict ( return_list = True ) ) <EOL> rval = [ ] <EOL> for idx in xrange ( len ( node . outputs ) ) : <EOL> if idx in out_map : <EOL> rval += [ new_outs [ inv_map [ out_map [ idx ] ] ] ] <EOL> else : <EOL> rval += [ new_outs [ inv_map [ idx ] ] ] <EOL> return rval <EOL> @ gof . local_optimizer ( [ IfElse ] ) <EOL> def cond_merge_random_op ( main_node ) : <EOL> if isinstance ( main_node . op , IfElse ) : <EOL> return False <EOL> all_inp_nodes = set ( ) <EOL> for inp in main_node . inputs : <EOL> all_inp_nodes . add ( inp . owner ) <EOL> cond_nodes = [ x for x in list ( all_inp_nodes ) <EOL> if x and isinstance ( x . op , IfElse ) ] <EOL> if len ( cond_nodes ) < <NUM_LIT:2> : <EOL> return False <EOL> merging_node = cond_nodes [ <NUM_LIT:0> ] <EOL> for proposal in cond_nodes [ <NUM_LIT:1> : ] : <EOL> if ( proposal . inputs [ <NUM_LIT:0> ] == merging_node . inputs [ <NUM_LIT:0> ] and <EOL> not find_up ( proposal , merging_node ) and <EOL> not find_up ( merging_node , proposal ) ) : <EOL> mn_ts = merging_node . inputs [ <NUM_LIT:1> : ] [ : merging_node . op . n_outs ] <EOL> mn_fs = merging_node . inputs [ <NUM_LIT:1> : ] [ merging_node . op . n_outs : ] <EOL> pl_ts = proposal . inputs [ <NUM_LIT:1> : ] [ : proposal . op . n_outs ] <EOL> pl_fs = proposal . inputs [ <NUM_LIT:1> : ] [ proposal . op . n_outs : ] <EOL> new_ins = ( [ merging_node . inputs [ <NUM_LIT:0> ] ] + <EOL> mn_ts + pl_ts + mn_fs + pl_fs ) <EOL> mn_name = '<STR_LIT:?>' <EOL> if merging_node . op . name : <EOL> mn_name = merging_node . op . name <EOL> pl_name = '<STR_LIT:?>' <EOL> if proposal . op . name : <EOL> pl_name = proposal . op . name <EOL> new_ifelse = IfElse ( <EOL> n_outs = len ( mn_ts + pl_ts ) , <EOL> as_view = False , <EOL> gpu = False , <EOL> name = mn_name + '<STR_LIT:&>' + pl_name ) <EOL> new_outs = new_ifelse ( * new_ins , ** dict ( return_list = True ) ) <EOL> old_outs = [ ] <EOL> if type ( merging_node . outputs ) not in ( list , tuple ) : <EOL> old_outs += [ merging_node . outputs ] <EOL> else : <EOL> old_outs += merging_node . outputs <EOL> if type ( proposal . outputs ) not in ( list , tuple ) : <EOL> old_outs += [ proposal . outputs ] <EOL> else : <EOL> old_outs += proposal . outputs <EOL> pairs = list ( zip ( old_outs , new_outs ) ) <EOL> main_outs = clone ( main_node . outputs , replace = pairs ) <EOL> return main_outs </s>
