<s> import inspect <EOL> from abc import ABCMeta <EOL> from collections import OrderedDict <EOL> from functools import wraps <EOL> from operator import attrgetter <EOL> from types import MethodType <EOL> import six <EOL> from six import add_metaclass <EOL> from theano import tensor <EOL> from theano . gof import Variable <EOL> from blocks . graph import add_annotation , Annotation <EOL> from blocks . roles import add_role , PARAMETER , INPUT , OUTPUT <EOL> from blocks . utils import dict_union , pack , repr_attrs , reraise_as , unpack <EOL> from blocks . utils . containers import AnnotatingList <EOL> def create_unbound_method ( func , cls ) : <EOL> """<STR_LIT>""" <EOL> if six . PY2 : <EOL> return MethodType ( func , None , cls ) <EOL> if six . PY3 : <EOL> return func <EOL> property_ = property <EOL> class Parameters ( AnnotatingList ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , brick , * args , ** kwargs ) : <EOL> self . brick = brick <EOL> super ( Parameters , self ) . __init__ ( * args , ** kwargs ) <EOL> def _setitem ( self , key , value ) : <EOL> if isinstance ( value , Variable ) : <EOL> add_role ( value , PARAMETER ) <EOL> add_annotation ( value , self . brick ) <EOL> def __getattr__ ( self , name ) : <EOL> if name == '<STR_LIT>' : <EOL> raise AttributeError <EOL> for l in self . _items : <EOL> if getattr ( l , '<STR_LIT:name>' , None ) == name : <EOL> return l <EOL> raise AttributeError <EOL> class Children ( AnnotatingList ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , brick , * args , ** kwargs ) : <EOL> self . brick = brick <EOL> super ( Children , self ) . __init__ ( * args , ** kwargs ) <EOL> def _setitem ( self , key , value ) : <EOL> if value is not None : <EOL> value . parents . append ( self . brick ) <EOL> def _delitem ( self , key ) : <EOL> child = self . _items [ key ] <EOL> if child is not None : <EOL> child . parents . remove ( self . brick ) <EOL> class Application ( object ) : <EOL> """<STR_LIT>""" <EOL> call_stack = [ ] <EOL> def __init__ ( self , application_function ) : <EOL> self . __doc__ = application_function . __doc__ <EOL> self . _application_function = application_function <EOL> self . application_name = application_function . __name__ <EOL> self . delegate_function = None <EOL> self . properties = { } <EOL> @ property <EOL> def application_function ( self ) : <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> return self . _application_function <EOL> return getattr ( self . brick , '<STR_LIT:_>' + self . application_name ) <EOL> def property ( self , name ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( name , six . string_types ) : <EOL> raise ValueError <EOL> def wrap_property ( application_property ) : <EOL> self . properties [ name ] = application_property . __name__ <EOL> return application_property <EOL> return wrap_property <EOL> def delegate ( self , f ) : <EOL> """<STR_LIT>""" <EOL> self . delegate_function = f . __name__ <EOL> return f <EOL> def __get__ ( self , instance , owner ) : <EOL> """<STR_LIT>""" <EOL> if instance is None : <EOL> return self <EOL> if not hasattr ( instance , "<STR_LIT>" ) : <EOL> instance . _bound_applications = { } <EOL> key = "<STR_LIT>" . format ( self . brick . __name__ , self . application_name ) <EOL> return instance . _bound_applications . setdefault ( <EOL> key , BoundApplication ( self , instance ) ) <EOL> def __getattr__ ( self , name ) : <EOL> if '<STR_LIT>' in self . __dict__ and name in self . properties : <EOL> return property ( create_unbound_method ( <EOL> getattr ( self , self . properties [ name ] ) , self . brick ) ) <EOL> raise AttributeError <EOL> def __setattr__ ( self , name , value ) : <EOL> if '<STR_LIT>' in self . __dict__ and name in self . properties : <EOL> raise AttributeError ( "<STR_LIT>" ) <EOL> super ( Application , self ) . __setattr__ ( name , value ) <EOL> @ property_ <EOL> def inputs ( self ) : <EOL> return self . _inputs <EOL> @ inputs . setter <EOL> def inputs ( self , inputs ) : <EOL> args_names , varargs_name , _ , _ = inspect . getargspec ( <EOL> self . application_function ) <EOL> if not all ( input_ in args_names + [ varargs_name ] for input_ in inputs ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . _inputs = inputs <EOL> @ property_ <EOL> def name ( self ) : <EOL> return self . application_name <EOL> def __call__ ( self , brick , * args , ** kwargs ) : <EOL> if not isinstance ( brick , Brick ) and six . PY2 : <EOL> raise TypeError <EOL> bound_application = self . __get__ ( brick , brick . __class__ ) <EOL> return self . apply ( bound_application , * args , ** kwargs ) <EOL> def apply ( self , bound_application , * args , ** kwargs ) : <EOL> as_dict = kwargs . pop ( '<STR_LIT>' , False ) <EOL> as_list = kwargs . pop ( '<STR_LIT>' , False ) <EOL> if as_list and as_dict : <EOL> raise ValueError <EOL> brick = bound_application . brick <EOL> args_names , varargs_name , _ , _ = inspect . getargspec ( <EOL> self . application_function ) <EOL> args_names = args_names [ <NUM_LIT:1> : ] <EOL> call = ApplicationCall ( bound_application ) <EOL> args = list ( args ) <EOL> if '<STR_LIT>' in args_names : <EOL> args . insert ( args_names . index ( '<STR_LIT>' ) , bound_application ) <EOL> if '<STR_LIT>' in args_names : <EOL> args . insert ( args_names . index ( '<STR_LIT>' ) , call ) <EOL> if not brick . allocated : <EOL> brick . allocate ( ) <EOL> def copy_and_tag ( variable , role , name ) : <EOL> """<STR_LIT>""" <EOL> copy = variable . copy ( ) <EOL> copy . name = _variable_name ( brick . name , self . name , name ) <EOL> add_annotation ( copy , brick ) <EOL> add_annotation ( copy , call ) <EOL> copy . tag . name = name <EOL> add_role ( copy , role ) <EOL> return copy <EOL> for i , input_ in enumerate ( args ) : <EOL> if isinstance ( input_ , tensor . Variable ) : <EOL> if i < len ( args_names ) : <EOL> name = args_names [ i ] <EOL> else : <EOL> name = "<STR_LIT>" . format ( varargs_name , i - len ( args_names ) ) <EOL> args [ i ] = copy_and_tag ( input_ , INPUT , name ) <EOL> for name , input_ in kwargs . items ( ) : <EOL> if isinstance ( input_ , tensor . Variable ) : <EOL> kwargs [ name ] = copy_and_tag ( input_ , INPUT , name ) <EOL> last_brick = self . call_stack [ - <NUM_LIT:1> ] if self . call_stack else None <EOL> if ( last_brick and brick is not last_brick and <EOL> brick not in last_brick . children ) : <EOL> raise ValueError ( '<STR_LIT>' + str ( self . call_stack [ - <NUM_LIT:1> ] ) + '<STR_LIT>' <EOL> '<STR_LIT>' + str ( self . brick ) + '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> self . call_stack . append ( brick ) <EOL> try : <EOL> outputs = self . application_function ( brick , * args , ** kwargs ) <EOL> outputs = pack ( outputs ) <EOL> finally : <EOL> self . call_stack . pop ( ) <EOL> for i , output in enumerate ( outputs ) : <EOL> if isinstance ( output , tensor . Variable ) : <EOL> try : <EOL> name = bound_application . outputs [ i ] <EOL> except AttributeError : <EOL> name = "<STR_LIT>" . format ( i ) <EOL> except IndexError : <EOL> reraise_as ( ValueError ( "<STR_LIT>" ) ) <EOL> outputs [ i ] = copy_and_tag ( outputs [ i ] , <EOL> OUTPUT , name ) <EOL> if as_list : <EOL> return outputs <EOL> if as_dict : <EOL> return OrderedDict ( zip ( bound_application . outputs , outputs ) ) <EOL> return unpack ( outputs ) <EOL> def __reduce__ ( self ) : <EOL> return ( getattr , ( self . brick , self . application_name ) ) <EOL> class BoundApplication ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , application , brick ) : <EOL> self . application = application <EOL> self . brick = brick <EOL> def __getattr__ ( self , name ) : <EOL> if name == '<STR_LIT>' : <EOL> raise AttributeError <EOL> if name in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> return getattr ( self . application , name ) <EOL> if name in self . properties . values ( ) : <EOL> return getattr ( self . application . brick , name ) <EOL> if name in self . properties : <EOL> return getattr ( self , self . properties [ name ] ) ( self . brick ) <EOL> try : <EOL> return getattr ( self . application , name ) <EOL> except AttributeError : <EOL> if self . delegate_function : <EOL> return getattr ( getattr ( self . brick , <EOL> self . delegate_function ) ( ) , <EOL> name ) <EOL> raise <EOL> @ property <EOL> def name ( self ) : <EOL> return self . application . name <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> return self . application . apply ( self , * args , ** kwargs ) <EOL> def rename_function ( function , new_name ) : <EOL> old_name = function . __name__ <EOL> function . __name__ = new_name <EOL> if six . PY3 : <EOL> function . __qualname__ = function . __qualname__ [ : - len ( old_name ) ] + new_name <EOL> return function <EOL> class _Brick ( ABCMeta ) : <EOL> """<STR_LIT>""" <EOL> def __new__ ( mcs , name , bases , namespace ) : <EOL> decorators = namespace . get ( '<STR_LIT>' , [ ] ) <EOL> for decorator in decorators : <EOL> decorator ( mcs , name , bases , namespace ) <EOL> for attr in list ( namespace . values ( ) ) : <EOL> if ( isinstance ( attr , Application ) and <EOL> hasattr ( attr , '<STR_LIT>' ) ) : <EOL> namespace [ '<STR_LIT:_>' + attr . application_name ] = rename_function ( attr . _application_function , <EOL> '<STR_LIT:_>' + attr . application_name ) <EOL> del attr . _application_function <EOL> brick = super ( _Brick , mcs ) . __new__ ( mcs , name , bases , namespace ) <EOL> for attr in namespace . values ( ) : <EOL> if isinstance ( attr , Application ) : <EOL> attr . brick = brick <EOL> return brick <EOL> @ add_metaclass ( _Brick ) <EOL> class Brick ( Annotation ) : <EOL> """<STR_LIT>""" <EOL> print_shapes = False <EOL> def __init__ ( self , name = None ) : <EOL> if name is None : <EOL> name = self . __class__ . __name__ . lower ( ) <EOL> self . name = name <EOL> self . children = [ ] <EOL> self . parents = [ ] <EOL> self . allocated = False <EOL> self . allocation_config_pushed = False <EOL> self . initialized = False <EOL> self . initialization_config_pushed = False <EOL> super ( Brick , self ) . __init__ ( ) <EOL> def __repr__ ( self ) : <EOL> return repr_attrs ( self , '<STR_LIT:name>' ) <EOL> @ property <EOL> def parameters ( self ) : <EOL> return self . _parameters <EOL> @ parameters . setter <EOL> def parameters ( self , value ) : <EOL> self . _parameters = Parameters ( self , value ) <EOL> @ property <EOL> def children ( self ) : <EOL> return self . _children <EOL> @ children . setter <EOL> def children ( self , value ) : <EOL> self . _children = Children ( self , value ) <EOL> def allocate ( self ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> missing_config = [ arg for arg in self . allocation_args <EOL> if getattr ( self , arg ) is NoneAllocation ] <EOL> if missing_config : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT:{}>' . format ( '<STR_LIT:U+002CU+0020>' . join ( missing_config ) ) ) <EOL> if not self . allocation_config_pushed : <EOL> self . push_allocation_config ( ) <EOL> for child in self . children : <EOL> child . allocate ( ) <EOL> self . parameters = [ ] <EOL> self . _allocate ( ) <EOL> self . allocated = True <EOL> def _allocate ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def initialize ( self ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> missing_config = [ arg for arg in self . initialization_args <EOL> if getattr ( self , arg ) is NoneInitialization ] <EOL> if missing_config : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT:{}>' . format ( '<STR_LIT:U+002CU+0020>' . join ( missing_config ) ) ) <EOL> if not self . allocated : <EOL> self . allocate ( ) <EOL> if not self . initialization_config_pushed : <EOL> self . push_initialization_config ( ) <EOL> for child in self . children : <EOL> child . initialize ( ) <EOL> self . _initialize ( ) <EOL> self . initialized = True <EOL> def _initialize ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def push_allocation_config ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _push_allocation_config ( ) <EOL> self . allocation_config_pushed = True <EOL> for child in self . children : <EOL> try : <EOL> child . push_allocation_config ( ) <EOL> except Exception : <EOL> self . allocation_config_pushed = False <EOL> raise <EOL> def _push_allocation_config ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def push_initialization_config ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _push_initialization_config ( ) <EOL> self . initialization_config_pushed = True <EOL> for child in self . children : <EOL> try : <EOL> child . push_initialization_config ( ) <EOL> except Exception : <EOL> self . initialization_config_pushed = False <EOL> raise <EOL> def _push_initialization_config ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def get_dim ( self , name ) : <EOL> """<STR_LIT>""" <EOL> raise ValueError ( "<STR_LIT>" <EOL> . format ( name ) ) <EOL> def get_dims ( self , names ) : <EOL> """<STR_LIT>""" <EOL> return [ self . get_dim ( name ) for name in names ] <EOL> def get_unique_path ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . parents : <EOL> parent = min ( self . parents , key = attrgetter ( '<STR_LIT:name>' ) ) <EOL> return parent . get_unique_path ( ) + [ self ] <EOL> else : <EOL> return [ self ] <EOL> def args_to_kwargs ( args , f ) : <EOL> arg_names , vararg_names , _ , _ = inspect . getargspec ( f ) <EOL> return dict ( ( arg_name , arg ) for arg_name , arg <EOL> in zip ( arg_names + [ vararg_names ] , args ) ) <EOL> class LazyNone ( object ) : <EOL> def __init__ ( self , name ) : <EOL> self . name = name <EOL> def __repr__ ( self ) : <EOL> return self . name <EOL> def __bool__ ( self ) : <EOL> return False <EOL> __nonzero__ = __bool__ <EOL> NoneAllocation = LazyNone ( '<STR_LIT>' ) <EOL> NoneInitialization = LazyNone ( '<STR_LIT>' ) <EOL> def lazy ( allocation = None , initialization = None ) : <EOL> """<STR_LIT>""" <EOL> if not allocation : <EOL> allocation = [ ] <EOL> if not initialization : <EOL> initialization = [ ] <EOL> def lazy_wrapper ( init ) : <EOL> def lazy_init ( * args , ** kwargs ) : <EOL> self = args [ <NUM_LIT:0> ] <EOL> self . allocation_args = ( getattr ( self , '<STR_LIT>' , <EOL> [ ] ) + allocation ) <EOL> self . initialization_args = ( getattr ( self , '<STR_LIT>' , <EOL> [ ] ) + initialization ) <EOL> kwargs = dict_union ( args_to_kwargs ( args , init ) , kwargs ) <EOL> for allocation_arg in allocation : <EOL> kwargs . setdefault ( allocation_arg , NoneAllocation ) <EOL> for initialization_arg in initialization : <EOL> kwargs . setdefault ( initialization_arg , NoneInitialization ) <EOL> return init ( ** kwargs ) <EOL> wraps ( init ) ( lazy_init ) <EOL> return lazy_init <EOL> return lazy_wrapper <EOL> class ApplicationCall ( Annotation ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , application ) : <EOL> self . application = application <EOL> self . metadata = { } <EOL> super ( ApplicationCall , self ) . __init__ ( ) <EOL> def add_auxiliary_variable ( self , variable , roles = None , name = None ) : <EOL> if name : <EOL> variable . name = _variable_name ( <EOL> self . application . brick . name , self . application . name , name ) <EOL> variable . tag . name = name <EOL> name = None <EOL> add_annotation ( variable , self . application . brick ) <EOL> return super ( ApplicationCall , self ) . add_auxiliary_variable ( <EOL> variable , roles , name ) <EOL> def application ( * args , ** kwargs ) : <EOL> r"""<STR_LIT>""" <EOL> if not ( ( args and not kwargs ) or ( not args and kwargs ) ) : <EOL> raise ValueError <EOL> if args : <EOL> application_function , = args <EOL> application = Application ( application_function ) <EOL> return application <EOL> else : <EOL> def wrap_application ( application_function ) : <EOL> application = Application ( application_function ) <EOL> for key , value in kwargs . items ( ) : <EOL> setattr ( application , key , value ) <EOL> return application <EOL> return wrap_application <EOL> def _variable_name ( brick_name , application_name , name ) : <EOL> return "<STR_LIT>" . format ( brick_name , application_name , name ) </s>
