<s> """<STR_LIT>""" <EOL> from __future__ import print_function <EOL> from collections import deque <EOL> from copy import copy <EOL> from itertools import count <EOL> import theano <EOL> from theano import config <EOL> from theano . gof import utils <EOL> from six import string_types , integer_types , iteritems <EOL> from theano . misc . ordered_set import OrderedSet <EOL> __docformat__ = "<STR_LIT>" <EOL> is_same_graph_with_merge = None <EOL> equal_computations = None <EOL> NoParams = object ( ) <EOL> class Node ( utils . object2 ) : <EOL> """<STR_LIT>""" <EOL> def get_parents ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> class Apply ( Node ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , op , inputs , outputs ) : <EOL> self . op = op <EOL> self . inputs = [ ] <EOL> self . tag = utils . scratchpad ( ) <EOL> if not isinstance ( inputs , ( list , tuple ) ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> if not isinstance ( outputs , ( list , tuple ) ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> for input in inputs : <EOL> if isinstance ( input , Variable ) : <EOL> self . inputs . append ( input ) <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" % input ) <EOL> self . outputs = [ ] <EOL> for i , output in enumerate ( outputs ) : <EOL> if isinstance ( output , Variable ) : <EOL> if output . owner is None : <EOL> output . owner = self <EOL> output . index = i <EOL> elif output . owner is not self or output . index != i : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . outputs . append ( output ) <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" % output ) <EOL> def run_params ( self ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( self . op , '<STR_LIT>' ) : <EOL> return self . op . get_params ( self ) <EOL> return NoParams <EOL> def __getstate__ ( self ) : <EOL> d = self . __dict__ <EOL> if hasattr ( self . tag , '<STR_LIT>' ) : <EOL> d = copy ( self . __dict__ ) <EOL> t = d [ "<STR_LIT>" ] <EOL> del t . ufunc <EOL> d [ "<STR_LIT>" ] = t <EOL> return d <EOL> def default_output ( self ) : <EOL> """<STR_LIT>""" <EOL> do = getattr ( self . op , '<STR_LIT>' , None ) <EOL> if do is None : <EOL> if len ( self . outputs ) == <NUM_LIT:1> : <EOL> return self . outputs [ <NUM_LIT:0> ] <EOL> else : <EOL> raise AttributeError ( <EOL> "<STR_LIT>" % self . op ) <EOL> elif not isinstance ( do , integer_types ) : <EOL> raise AttributeError ( "<STR_LIT>" % <EOL> self . op ) <EOL> elif do < <NUM_LIT:0> or do >= len ( self . outputs ) : <EOL> raise AttributeError ( "<STR_LIT>" % <EOL> self . op ) <EOL> return self . outputs [ do ] <EOL> out = property ( default_output , <EOL> doc = "<STR_LIT>" ) <EOL> """<STR_LIT>""" <EOL> def __str__ ( self ) : <EOL> return op_as_string ( self . inputs , self ) <EOL> def __repr__ ( self ) : <EOL> return str ( self ) <EOL> def __asapply__ ( self ) : <EOL> return self <EOL> def clone ( self ) : <EOL> """<STR_LIT>""" <EOL> cp = self . __class__ ( self . op , self . inputs , <EOL> [ output . clone ( ) for output in self . outputs ] ) <EOL> cp . tag = copy ( self . tag ) <EOL> return cp <EOL> def clone_with_new_inputs ( self , inputs , strict = True ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( inputs , ( list , tuple ) ) <EOL> remake_node = False <EOL> new_inputs = inputs [ : ] <EOL> for i , ( curr , new ) in enumerate ( zip ( self . inputs , new_inputs ) ) : <EOL> if not curr . type == new . type : <EOL> if strict : <EOL> new_inputs [ i ] = curr . type . filter_variable ( new ) <EOL> else : <EOL> remake_node = True <EOL> if remake_node : <EOL> new_node = self . op . make_node ( * new_inputs ) <EOL> new_node . tag = copy ( self . tag ) . __update__ ( new_node . tag ) <EOL> else : <EOL> new_node = self . clone ( ) <EOL> new_node . inputs = new_inputs <EOL> return new_node <EOL> def get_parents ( self ) : <EOL> return list ( self . inputs ) <EOL> nin = property ( lambda self : len ( self . inputs ) , doc = '<STR_LIT>' ) <EOL> """<STR_LIT>""" <EOL> nout = property ( lambda self : len ( self . outputs ) , doc = '<STR_LIT>' ) <EOL> """<STR_LIT>""" <EOL> params_type = property ( lambda self : self . op . params_type , doc = '<STR_LIT>' ) <EOL> class Variable ( Node ) : <EOL> """<STR_LIT>""" <EOL> __count__ = count ( <NUM_LIT:0> ) <EOL> def __init__ ( self , type , owner = None , index = None , name = None ) : <EOL> super ( Variable , self ) . __init__ ( ) <EOL> self . tag = utils . scratchpad ( ) <EOL> self . type = type <EOL> if owner is not None and not isinstance ( owner , Apply ) : <EOL> raise TypeError ( "<STR_LIT>" , owner ) <EOL> self . owner = owner <EOL> if index is not None and not isinstance ( index , int ) : <EOL> raise TypeError ( "<STR_LIT>" , index ) <EOL> self . index = index <EOL> if name is not None and not isinstance ( name , string_types ) : <EOL> raise TypeError ( "<STR_LIT>" , name ) <EOL> self . name = name <EOL> self . auto_name = '<STR_LIT>' + str ( next ( self . __count__ ) ) <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . name is not None : <EOL> return self . name <EOL> if self . owner is not None : <EOL> op = self . owner . op <EOL> if self . index == op . default_output : <EOL> return str ( self . owner . op ) + "<STR_LIT>" <EOL> else : <EOL> return str ( self . owner . op ) + "<STR_LIT:.>" + str ( self . index ) <EOL> else : <EOL> return "<STR_LIT>" % str ( self . type ) <EOL> def __repr_test_value__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return repr ( theano . gof . op . get_test_value ( self ) ) <EOL> def __repr__ ( self , firstPass = True ) : <EOL> """<STR_LIT>""" <EOL> to_print = [ str ( self ) ] <EOL> if config . print_test_value and firstPass : <EOL> try : <EOL> to_print . append ( self . __repr_test_value__ ( ) ) <EOL> except AttributeError : <EOL> pass <EOL> return '<STR_LIT:\n>' . join ( to_print ) <EOL> def clone ( self ) : <EOL> """<STR_LIT>""" <EOL> cp = self . __class__ ( self . type , None , None , self . name ) <EOL> cp . tag = copy ( self . tag ) <EOL> return cp <EOL> def __lt__ ( self , other ) : <EOL> raise NotImplementedError ( '<STR_LIT>' , <EOL> self . __class__ . __name__ ) <EOL> def __le__ ( self , other ) : <EOL> raise NotImplementedError ( '<STR_LIT>' , <EOL> self . __class__ . __name__ ) <EOL> def __gt__ ( self , other ) : <EOL> raise NotImplementedError ( '<STR_LIT>' , <EOL> self . __class__ . __name__ ) <EOL> def __ge__ ( self , other ) : <EOL> raise NotImplementedError ( '<STR_LIT>' , <EOL> self . __class__ . __name__ ) <EOL> def get_parents ( self ) : <EOL> if self . owner is not None : <EOL> return [ self . owner ] <EOL> return [ ] <EOL> def eval ( self , inputs_to_values = None ) : <EOL> """<STR_LIT>""" <EOL> if inputs_to_values is None : <EOL> inputs_to_values = { } <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . _fn_cache = dict ( ) <EOL> inputs = tuple ( sorted ( inputs_to_values . keys ( ) , key = id ) ) <EOL> if inputs not in self . _fn_cache : <EOL> self . _fn_cache [ inputs ] = theano . function ( inputs , self ) <EOL> args = [ inputs_to_values [ param ] for param in inputs ] <EOL> rval = self . _fn_cache [ inputs ] ( * args ) <EOL> return rval <EOL> def __getstate__ ( self ) : <EOL> d = self . __dict__ . copy ( ) <EOL> d . pop ( "<STR_LIT>" , None ) <EOL> return d <EOL> class Constant ( Variable ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , type , data , name = None ) : <EOL> Variable . __init__ ( self , type , None , None , name ) <EOL> self . data = type . filter ( data ) <EOL> def equals ( self , other ) : <EOL> return isinstance ( other , Constant ) and self . signature ( ) == other . signature ( ) <EOL> def signature ( self ) : <EOL> return ( self . type , self . data ) <EOL> def merge_signature ( self ) : <EOL> return self . signature ( ) <EOL> def __str__ ( self ) : <EOL> if self . name is not None : <EOL> return self . name <EOL> else : <EOL> name = str ( self . data ) <EOL> if len ( name ) > <NUM_LIT:20> : <EOL> name = name [ : <NUM_LIT:10> ] + '<STR_LIT>' + name [ - <NUM_LIT:10> : ] <EOL> return '<STR_LIT>' % name <EOL> def clone ( self ) : <EOL> """<STR_LIT>""" <EOL> cp = self . __class__ ( self . type , self . data , self . name ) <EOL> cp . tag = copy ( self . tag ) <EOL> return cp <EOL> def __set_owner ( self , value ) : <EOL> """<STR_LIT>""" <EOL> if value is not None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> owner = property ( lambda self : None , __set_owner ) <EOL> value = property ( lambda self : self . data , doc = '<STR_LIT>' ) <EOL> def stack_search ( start , expand , mode = '<STR_LIT>' , build_inv = False ) : <EOL> """<STR_LIT>""" <EOL> if mode not in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> raise ValueError ( '<STR_LIT>' , mode ) <EOL> rval_set = set ( ) <EOL> rval_list = list ( ) <EOL> if mode == '<STR_LIT>' : <EOL> start_pop = start . popleft <EOL> else : <EOL> start_pop = start . pop <EOL> expand_inv = { } <EOL> while start : <EOL> l = start_pop ( ) <EOL> if id ( l ) not in rval_set : <EOL> rval_list . append ( l ) <EOL> rval_set . add ( id ( l ) ) <EOL> expand_l = expand ( l ) <EOL> if expand_l : <EOL> if build_inv : <EOL> for r in expand_l : <EOL> expand_inv . setdefault ( r , [ ] ) . append ( l ) <EOL> start . extend ( expand_l ) <EOL> assert len ( rval_list ) == len ( rval_set ) <EOL> if build_inv : <EOL> return rval_list , expand_inv <EOL> return rval_list <EOL> def ancestors ( variable_list , blockers = None ) : <EOL> """<STR_LIT>""" <EOL> def expand ( r ) : <EOL> if r . owner and ( not blockers or r not in blockers ) : <EOL> return reversed ( r . owner . inputs ) <EOL> dfs_variables = stack_search ( deque ( variable_list ) , expand , '<STR_LIT>' ) <EOL> return dfs_variables <EOL> def inputs ( variable_list , blockers = None ) : <EOL> """<STR_LIT>""" <EOL> vlist = ancestors ( variable_list , blockers ) <EOL> rval = [ r for r in vlist if r . owner is None ] <EOL> return rval <EOL> def variables_and_orphans ( i , o ) : <EOL> """<STR_LIT>""" <EOL> def expand ( r ) : <EOL> if r . owner and r not in i : <EOL> l = list ( r . owner . inputs ) + list ( r . owner . outputs ) <EOL> l . reverse ( ) <EOL> return l <EOL> variables = stack_search ( deque ( o ) , expand , '<STR_LIT>' ) <EOL> orphans = [ r for r in variables if r . owner is None and r not in i ] <EOL> return variables , orphans <EOL> def ops ( i , o ) : <EOL> """<STR_LIT>""" <EOL> ops = set ( ) <EOL> variables , orphans = variables_and_orphans ( i , o ) <EOL> for r in variables : <EOL> if r not in i and r not in orphans : <EOL> if r . owner is not None : <EOL> ops . add ( r . owner ) <EOL> return ops <EOL> def variables ( i , o ) : <EOL> """<STR_LIT>""" <EOL> return variables_and_orphans ( i , o ) [ <NUM_LIT:0> ] <EOL> def orphans ( i , o ) : <EOL> """<STR_LIT>""" <EOL> return variables_and_orphans ( i , o ) [ <NUM_LIT:1> ] <EOL> def clone ( i , o , copy_inputs = True ) : <EOL> """<STR_LIT>""" <EOL> equiv = clone_get_equiv ( i , o , copy_inputs ) <EOL> return [ equiv [ input ] for input in i ] , [ equiv [ output ] for output in o ] <EOL> def clone_get_equiv ( inputs , outputs , copy_inputs_and_orphans = True , memo = None ) : <EOL> """<STR_LIT>""" <EOL> if memo is None : <EOL> memo = { } <EOL> for input in inputs : <EOL> if copy_inputs_and_orphans : <EOL> cpy = input . clone ( ) <EOL> cpy . owner = None <EOL> cpy . index = None <EOL> memo . setdefault ( input , cpy ) <EOL> else : <EOL> memo . setdefault ( input , input ) <EOL> for apply in io_toposort ( inputs , outputs ) : <EOL> for input in apply . inputs : <EOL> if input not in memo : <EOL> if copy_inputs_and_orphans : <EOL> cpy = input . clone ( ) <EOL> memo [ input ] = cpy <EOL> else : <EOL> memo [ input ] = input <EOL> new_apply = apply . clone_with_new_inputs ( [ memo [ i ] for i in apply . inputs ] ) <EOL> memo . setdefault ( apply , new_apply ) <EOL> for output , new_output in zip ( apply . outputs , new_apply . outputs ) : <EOL> memo . setdefault ( output , new_output ) <EOL> for output in outputs : <EOL> if output not in memo : <EOL> memo [ output ] = output . clone ( ) <EOL> return memo <EOL> def general_toposort ( r_out , deps , debug_print = False , <EOL> compute_deps_cache = None , deps_cache = None , <EOL> clients = None ) : <EOL> """<STR_LIT>""" <EOL> if compute_deps_cache is None : <EOL> deps_cache = { } <EOL> def compute_deps_cache ( io ) : <EOL> if io not in deps_cache : <EOL> d = deps ( io ) <EOL> if d : <EOL> if not isinstance ( d , ( list , OrderedSet ) ) : <EOL> raise TypeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> deps_cache [ io ] = list ( d ) <EOL> else : <EOL> deps_cache [ io ] = d <EOL> return d <EOL> else : <EOL> return deps_cache [ io ] <EOL> assert deps_cache is not None <EOL> assert isinstance ( r_out , ( tuple , list , deque ) ) <EOL> reachable , _clients = stack_search ( deque ( r_out ) , compute_deps_cache , <EOL> '<STR_LIT>' , True ) <EOL> if clients is not None : <EOL> clients . update ( _clients ) <EOL> sources = deque ( [ r for r in reachable if not deps_cache . get ( r , None ) ] ) <EOL> rset = set ( ) <EOL> rlist = [ ] <EOL> while sources : <EOL> node = sources . popleft ( ) <EOL> if node not in rset : <EOL> rlist . append ( node ) <EOL> rset . add ( node ) <EOL> for client in _clients . get ( node , [ ] ) : <EOL> deps_cache [ client ] = [ a for a in deps_cache [ client ] <EOL> if a is not node ] <EOL> if not deps_cache [ client ] : <EOL> sources . append ( client ) <EOL> if len ( rlist ) != len ( reachable ) : <EOL> if debug_print : <EOL> print ( '<STR_LIT>' ) <EOL> print ( reachable ) <EOL> print ( rlist ) <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return rlist <EOL> def io_toposort ( inputs , outputs , orderings = None , clients = None ) : <EOL> """<STR_LIT>""" <EOL> iset = set ( inputs ) <EOL> deps_cache = { } <EOL> compute_deps = None <EOL> compute_deps_cache = None <EOL> if not orderings : <EOL> def compute_deps_cache ( obj ) : <EOL> if obj in deps_cache : <EOL> return deps_cache [ obj ] <EOL> rval = [ ] <EOL> if obj not in iset : <EOL> if isinstance ( obj , Variable ) : <EOL> if obj . owner : <EOL> rval = [ obj . owner ] <EOL> elif isinstance ( obj , Apply ) : <EOL> rval = list ( obj . inputs ) <EOL> if rval : <EOL> if not isinstance ( rval , ( list , OrderedSet ) ) : <EOL> raise TypeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> deps_cache [ obj ] = list ( rval ) <EOL> else : <EOL> deps_cache [ obj ] = rval <EOL> else : <EOL> deps_cache [ obj ] = rval <EOL> return rval <EOL> else : <EOL> def compute_deps ( obj ) : <EOL> rval = [ ] <EOL> if obj not in iset : <EOL> if isinstance ( obj , Variable ) : <EOL> if obj . owner : <EOL> rval = [ obj . owner ] <EOL> elif isinstance ( obj , Apply ) : <EOL> rval = list ( obj . inputs ) <EOL> rval . extend ( orderings . get ( obj , [ ] ) ) <EOL> else : <EOL> assert not orderings . get ( obj , [ ] ) <EOL> return rval <EOL> topo = general_toposort ( outputs , deps = compute_deps , <EOL> compute_deps_cache = compute_deps_cache , <EOL> deps_cache = deps_cache , clients = clients ) <EOL> return [ o for o in topo if isinstance ( o , Apply ) ] <EOL> default_leaf_formatter = str <EOL> def default_node_formatter ( op , argstrings ) : <EOL> return "<STR_LIT>" % ( op . op , "<STR_LIT:U+002CU+0020>" . join ( argstrings ) ) <EOL> def io_connection_pattern ( inputs , outputs ) : <EOL> """<STR_LIT>""" <EOL> inner_nodes = io_toposort ( inputs , outputs ) <EOL> connect_pattern_by_var = { } <EOL> nb_inputs = len ( inputs ) <EOL> for i in range ( nb_inputs ) : <EOL> input = inputs [ i ] <EOL> inp_connection_pattern = [ i == j for j in range ( nb_inputs ) ] <EOL> connect_pattern_by_var [ input ] = inp_connection_pattern <EOL> for n in inner_nodes : <EOL> try : <EOL> op_connection_pattern = n . op . connection_pattern ( n ) <EOL> except AttributeError : <EOL> op_connection_pattern = ( [ [ True ] * len ( n . outputs ) ] * <EOL> len ( n . inputs ) ) <EOL> for out_idx in range ( len ( n . outputs ) ) : <EOL> out = n . outputs [ out_idx ] <EOL> out_connection_pattern = [ False ] * nb_inputs <EOL> for inp_idx in range ( len ( n . inputs ) ) : <EOL> inp = n . inputs [ inp_idx ] <EOL> if inp in connect_pattern_by_var : <EOL> inp_connection_pattern = connect_pattern_by_var [ inp ] <EOL> if op_connection_pattern [ inp_idx ] [ out_idx ] : <EOL> out_connection_pattern = [ out_connection_pattern [ i ] or <EOL> inp_connection_pattern [ i ] <EOL> for i in range ( nb_inputs ) ] <EOL> connect_pattern_by_var [ out ] = out_connection_pattern <EOL> global_connection_pattern = [ [ ] for o in range ( len ( inputs ) ) ] <EOL> for out in outputs : <EOL> out_connection_pattern = connect_pattern_by_var [ out ] <EOL> for i in range ( len ( inputs ) ) : <EOL> global_connection_pattern [ i ] . append ( out_connection_pattern [ i ] ) <EOL> return global_connection_pattern <EOL> def is_same_graph ( var1 , var2 , givens = None , debug = False ) : <EOL> """<STR_LIT>""" <EOL> if givens is None : <EOL> givens = { } <EOL> global equal_computations , is_same_graph_with_merge <EOL> if equal_computations is None : <EOL> from theano . gof . opt import is_same_graph_with_merge <EOL> from theano . scan_module . scan_utils import equal_computations <EOL> if not isinstance ( givens , dict ) : <EOL> givens = dict ( givens ) <EOL> rval1 = is_same_graph_with_merge ( var1 = var1 , var2 = var2 , givens = givens ) <EOL> use_equal_computations = True <EOL> if givens : <EOL> ok = True <EOL> in_xs = [ ] <EOL> in_ys = [ ] <EOL> inputs_var = list ( map ( inputs , ( [ var1 ] , [ var2 ] ) ) ) <EOL> all_vars = [ set ( variables ( v_i , v_o ) ) <EOL> for v_i , v_o in ( ( inputs_var [ <NUM_LIT:0> ] , [ var1 ] ) , <EOL> ( inputs_var [ <NUM_LIT:1> ] , [ var2 ] ) ) ] <EOL> def in_var ( x , k ) : <EOL> return x in all_vars [ k - <NUM_LIT:1> ] <EOL> for to_replace , replace_by in iteritems ( givens ) : <EOL> inside = dict ( ( v , [ in_var ( v , k ) for k in ( <NUM_LIT:1> , <NUM_LIT:2> ) ] ) <EOL> for v in ( to_replace , replace_by ) ) <EOL> if ( inside [ to_replace ] [ <NUM_LIT:0> ] and not inside [ to_replace ] [ <NUM_LIT:1> ] and <EOL> inside [ replace_by ] [ <NUM_LIT:1> ] and not inside [ replace_by ] [ <NUM_LIT:0> ] ) : <EOL> in_xs . append ( to_replace ) <EOL> in_ys . append ( replace_by ) <EOL> elif ( inside [ to_replace ] [ <NUM_LIT:1> ] and not inside [ to_replace ] [ <NUM_LIT:0> ] and <EOL> inside [ replace_by ] [ <NUM_LIT:0> ] and not inside [ replace_by ] [ <NUM_LIT:1> ] ) : <EOL> in_xs . append ( replace_by ) <EOL> in_ys . append ( to_replace ) <EOL> else : <EOL> ok = False <EOL> break <EOL> if not ok : <EOL> if debug : <EOL> raise AssertionError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> use_equal_computations = False <EOL> else : <EOL> in_xs = None <EOL> in_ys = None <EOL> if use_equal_computations : <EOL> rval2 = equal_computations ( xs = [ var1 ] , ys = [ var2 ] , <EOL> in_xs = in_xs , in_ys = in_ys ) <EOL> assert rval2 == rval1 <EOL> return rval1 <EOL> def op_as_string ( i , op , <EOL> leaf_formatter = default_leaf_formatter , <EOL> node_formatter = default_node_formatter ) : <EOL> """<STR_LIT>""" <EOL> strs = as_string ( i , op . inputs , leaf_formatter , node_formatter ) <EOL> return node_formatter ( op , strs ) <EOL> def as_string ( i , o , <EOL> leaf_formatter = default_leaf_formatter , <EOL> node_formatter = default_node_formatter ) : <EOL> """<STR_LIT>""" <EOL> i = set ( i ) <EOL> orph = orphans ( i , o ) <EOL> multi = set ( ) <EOL> seen = set ( ) <EOL> for output in o : <EOL> op = output . owner <EOL> if op in seen : <EOL> multi . add ( op ) <EOL> else : <EOL> seen . add ( op ) <EOL> for op in ops ( i , o ) : <EOL> for input in op . inputs : <EOL> op2 = input . owner <EOL> if input in i or input in orph or op2 is None : <EOL> continue <EOL> if op2 in seen : <EOL> multi . add ( op2 ) <EOL> else : <EOL> seen . add ( input . owner ) <EOL> multi = [ x for x in multi ] <EOL> done = set ( ) <EOL> def multi_index ( x ) : <EOL> return multi . index ( x ) + <NUM_LIT:1> <EOL> def describe ( r ) : <EOL> if r . owner is not None and r not in i and r not in orph : <EOL> op = r . owner <EOL> idx = op . outputs . index ( r ) <EOL> if len ( op . outputs ) == <NUM_LIT:1> : <EOL> idxs = "<STR_LIT>" <EOL> else : <EOL> idxs = "<STR_LIT>" % idx <EOL> if op in done : <EOL> return "<STR_LIT>" % ( multi_index ( op ) , idxs ) <EOL> else : <EOL> done . add ( op ) <EOL> s = node_formatter ( op , [ describe ( input ) for input in op . inputs ] ) <EOL> if op in multi : <EOL> return "<STR_LIT>" % ( multi_index ( op ) , s ) <EOL> else : <EOL> return s <EOL> else : <EOL> return leaf_formatter ( r ) <EOL> return [ describe ( output ) for output in o ] <EOL> def view_roots ( r ) : <EOL> """<STR_LIT>""" <EOL> owner = r . owner <EOL> if owner is not None : <EOL> try : <EOL> view_map = owner . op . view_map <EOL> view_map = dict ( ( owner . outputs [ o ] , i ) <EOL> for o , i in iteritems ( view_map ) ) <EOL> except AttributeError : <EOL> return [ r ] <EOL> if r in view_map : <EOL> answer = [ ] <EOL> for i in view_map [ r ] : <EOL> answer += view_roots ( owner . inputs [ i ] ) <EOL> return answer <EOL> else : <EOL> return [ r ] <EOL> else : <EOL> return [ r ] <EOL> def list_of_nodes ( inputs , outputs ) : <EOL> """<STR_LIT>""" <EOL> return stack_search ( <EOL> deque ( [ o . owner for o in outputs ] ) , <EOL> lambda o : [ inp . owner for inp in o . inputs <EOL> if inp . owner and <EOL> not any ( i in inp . owner . outputs for i in inputs ) ] ) </s>
