55import abc
66import logging
77from collections import abc as cabc
8- from typing import Callable
8+ from typing import Callable , Collection , Tuple , Union
99
1010from boltons .setutils import IndexedSet as iset
1111
@@ -43,43 +43,6 @@ def reparse_operation_data(name, needs, provides):
4343class Operation (abc .ABC ):
4444 """An abstract class representing a data transformation by :meth:`.compute()`."""
4545
46- def __init__ (self , name , needs = None , provides = None ):
47- """
48- Create a new layer instance.
49- Names may be given to this layer and its inputs and outputs. This is
50- important when connecting layers and data in a Network object, as the
51- names are used to construct the graph.
52-
53- :param str name:
54- The name the operation (e.g. conv1, conv2, etc..)
55-
56- :param list needs:
57- Names of input data objects this layer requires.
58-
59- :param list provides:
60- Names of output data objects this provides.
61-
62- """
63-
64- # (Optional) names for this layer, and the data it needs and provides
65- self .name = name
66- self .needs = needs
67- self .provides = provides
68-
69- def __eq__ (self , other ):
70- """
71- Operation equality is based on name of layer.
72- (__eq__ and __hash__ must be overridden together)
73- """
74- return bool (self .name is not None and self .name == getattr (other , "name" , None ))
75-
76- def __hash__ (self ):
77- """
78- Operation equality is based on name of layer.
79- (__eq__ and __hash__ must be overridden together)
80- """
81- return hash (self .name )
82-
8346 @abc .abstractmethod
8447 def compute (self , named_inputs , outputs = None ):
8548 """
@@ -89,23 +52,12 @@ def compute(self, named_inputs, outputs=None):
8952 End-users should simply call the operation with `named_inputs` as kwargs.
9053
9154 :param list named_inputs:
92- A list of :class:`Data` objects on which to run the layer's
93- feed-forward computation.
55+ the input values with which to feed the computation.
9456 :returns list:
9557 Should return a list values representing
9658 the results of running the feed-forward computation on
9759 ``inputs``.
9860 """
99- pass
100-
101- def __repr__ (self ):
102- """
103- Display more informative names for the Operation class
104- """
105- clsname = type (self ).__name__
106- needs = aslist (self .needs , "needs" )
107- provides = aslist (self .provides , "provides" )
108- return f"{ clsname } ({ self .name !r} , needs={ needs !r} , provides={ provides !r} )"
10961
11062
11163class FunctionalOperation (Operation ):
@@ -119,19 +71,38 @@ def __init__(
11971 self ,
12072 fn : Callable ,
12173 name ,
122- needs = None ,
123- provides = None ,
74+ needs : Union [ Collection , str ] = None ,
75+ provides : Union [ Collection , str ] = None ,
12476 * ,
125- parents = None ,
77+ parents : Tuple = None ,
12678 returns_dict = None ,
12779 ):
80+ """
81+ Build a new operation out of some function and its requirements.
82+
83+ :param name:
84+ a name for the operation (e.g. `'conv1'`, `'sum'`, etc..);
85+ it will be prefixed by `parents`.
86+ :param needs:
87+ Names of input data objects this operation requires.
88+ :param provides:
89+ Names of output data objects this provides.
90+ :param parent:
91+ a tuple wth the names of the parents, prefixing `name`,
92+ but also kept for equality/hash check.
93+
94+ """
95+ ## Set op-data early, for repr() to work on errors.
12896 self .fn = fn
97+ self .name = name
98+ self .needs = needs
99+ self .provides = provides
129100 self .parents = parents
130101 self .returns_dict = returns_dict
131- ## Set op-data early, for repr() to work on errors.
132- super ().__init__ (name , needs , provides )
133102 if not fn or not callable (fn ):
134- raise ValueError (f"Operation was not provided with a callable: { self .fn } " )
103+ raise ValueError (
104+ f"Operation was not provided with a callable: { fn } \n { self } "
105+ )
135106 if parents and not isinstance (parents , tuple ):
136107 raise ValueError (
137108 f"Operation `parents` must be tuple, was { parents } \n { self } "
@@ -143,21 +114,15 @@ def __init__(
143114 )
144115
145116 def __eq__ (self , other ):
146- """
147- Operation equality is based on name of layer.
148- (__eq__ and __hash__ must be overridden together)
149- """
117+ """Operation identity is based on `name` and `parents`."""
150118 return bool (
151119 self .name is not None
152120 and self .name == getattr (other , "name" , None )
153121 and self .parents == getattr (other , "parents" , None )
154122 )
155123
156124 def __hash__ (self ):
157- """
158- Operation equality is based on name of layer.
159- (__eq__ and __hash__ must be overridden together)
160- """
125+ """Operation identity is based on `name` and `parents`."""
161126 return hash (self .name ) ^ hash (self .parents )
162127
163128 def __repr__ (self ):
0 commit comments