提交 344bb891 authored 作者: james@crane's avatar james@crane

updated rest doc for gof.type

上级 e1b16ba2
"""Defines the `Type` class."""
__docformat__ = "restucturedtext en"
import copy import copy
import utils import utils
...@@ -10,50 +13,62 @@ import traceback ...@@ -10,50 +13,62 @@ import traceback
# Type # # Type #
######## ########
class Type(object2): class CLinkerType(object):
"""Interface specification for Types that can be arguments to a `CLinkerOp`.
def filter(self, data, strict = False): A CLinkerType instance is mainly reponsible for providing the C code that
""" interfaces python objects with a C `CLinkerOp` implementation.
Return data or an appropriately wrapped data. Raise an
exception if the data is not of an acceptable type. See WRITEME for a general overview of code generation by `CLinker`.
"""
If strict is True, the data returned must be the same
as the data passed as an argument. If it is False, filter
may cast it to the appropriate type.
"""
raise AbstractFunctionError()
def make_result(self, name = None):
r = Result(self, name = name)
return r
def __call__(self, name = None):
r = self.make_result(name)
r.tag.trace = traceback.extract_stack()[:-1]
return r
def c_is_simple(self): def c_is_simple(self):
""" """Optional: Return True for small or builtin C types.
A hint to tell the compiler that this type is a builtin C
type or a small struct and that its memory footprint is A hint to tell the compiler that this type is a builtin C type or a
negligible. small struct and that its memory footprint is negligible. Simple
objects may be passed on the stack.
""" """
return False return False
def c_literal(self, data): def c_literal(self, data):
"""Optional: WRITEME
:Parameters:
- `data`: WRITEME
WRITEME
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
"""
raise AbstractFunctionError() raise AbstractFunctionError()
def c_declare(self, name, sub): def c_declare(self, name, sub):
""" """Required: Return c code to declare variables that will be
Declares variables that will be instantiated by L{c_extract}. instantiated by `c_extract`.
Example: WRITEME
:Parameters:
- `name`: WRITEME
WRITEME
- `sub`: WRITEME
WRITEME
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_extract(self, name, sub): def c_extract(self, name, sub):
""" """Required: Return c code to extract a PyObject * instance.
The code returned from this function must be templated using The code returned from this function must be templated using
"%(name)s", representing the name that the caller wants to "%(name)s", representing the name that the caller wants to
call this L{Result}. The Python object self.data is in a call this `Result`. The Python object self.data is in a
variable called "py_%(name)s" and this code must set the variable called "py_%(name)s" and this code must set the
variables declared by c_declare to something representative variables declared by c_declare to something representative
of py_%(name)s. If the data is improper, set an appropriate of py_%(name)s. If the data is improper, set an appropriate
...@@ -61,43 +76,90 @@ class Type(object2): ...@@ -61,43 +76,90 @@ class Type(object2):
@todo: Point out that template filling (via sub) is now performed @todo: Point out that template filling (via sub) is now performed
by this function. --jpt by this function. --jpt
WRITEME
:Parameters:
- `name`: WRITEME
WRITEME
- `sub`: WRITEME
WRITEME
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_cleanup(self, name, sub): def c_cleanup(self, name, sub):
""" """Optional: Return c code to clean up after `c_extract`.
This returns C code that should deallocate whatever
L{c_extract} allocated or decrease the reference counts. Do This returns C code that should deallocate whatever `c_extract`
not decrease py_%(name)s's reference count. allocated or decrease the reference counts. Do not decrease
py_%(name)s's reference count.
WRITEME
:Parameters:
- `name`: WRITEME
WRITEME
- `sub`: WRITEME
WRITEME
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_sync(self, name, sub): def c_sync(self, name, sub):
""" """Required: Return c code to pack C types back into a PyObject.
The code returned from this function must be templated using "%(name)s", The code returned from this function must be templated using "%(name)s",
representing the name that the caller wants to call this Result. representing the name that the caller wants to call this Result. The
The returned code may set "py_%(name)s" to a PyObject* and that PyObject* returned code may set "py_%(name)s" to a PyObject* and that PyObject*
will be accessible from Python via result.data. Do not forget to adjust will be accessible from Python via result.data. Do not forget to adjust
reference counts if "py_%(name)s" is changed from its original value. reference counts if "py_%(name)s" is changed from its original value.
:Parameters:
- `name`: WRITEME
WRITEME
- `sub`: WRITEME
WRITEME
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_compile_args(self): def c_compile_args(self):
""" """Optional: Return a list of compile args recommended to compile the
Return a list of compile args recommended to manipulate this L{Result}. code returned by other methods in this class.
WRITEME: example of formatting for -I, -L, -f args.
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_headers(self): def c_headers(self):
""" """Optional: Return a list of header files required by code returned by
Return a list of header files that must be included from C to manipulate this class.
this L{Result}.
WRITEME: example of local file, standard file.
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_libraries(self): def c_libraries(self):
""" """Optional: Return a list of libraries required by code returned by
Return a list of libraries to link against to manipulate this L{Result}. this class.
For example: return ['gsl', 'gslcblas', 'm', 'fftw3', 'g2c']. For example: return ['gsl', 'gslcblas', 'm', 'fftw3', 'g2c'].
...@@ -105,16 +167,118 @@ class Type(object2): ...@@ -105,16 +167,118 @@ class Type(object2):
variable LD_LIBRARY_PATH. No option is provided for an Op to provide an variable LD_LIBRARY_PATH. No option is provided for an Op to provide an
extra library directory because this would change the linking path for extra library directory because this would change the linking path for
other Ops in a potentially disasterous way. other Ops in a potentially disasterous way.
QUESTION: What about via the c_compile_args? a -L option is allowed no?
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def c_support_code(self): def c_support_code(self):
"""Optional: Return utility code for use by a `Result` or `Op` to be
included at global scope prior to the rest of the code for this class.
QUESTION: How many times will this support code be emitted for a graph
with many instances of the same type?
:Exceptions:
- `AbstractFunctionError`: Subclass does not implement this method
""" """
Return utility code for use by this L{Result} or L{Op}s manipulating this raise AbstractFunctionError()
L{Result}.
class PureType(object):
"""Interface specification for result type instances.
A Type instance is mainly reponsible for two things:
- creating `Result` instances (conventionally, `__call__` does this), and
- filtering a value assigned to a `Result` so that the value conforms to restrictions
imposed by the type (also known as casting, this is done by `filter`),
"""
def filter(self, data, strict = False):
"""Required: Return data or an appropriately wrapped/converted data.
Subclass implementation should raise a TypeError exception if the data is not of an
acceptable type.
If strict is True, the data returned must be the same as the data passed as an
argument. If it is False, filter may cast it to an appropriate type.
:Exceptions:
- `AbstractFunctionError`: subclass doesn't implement this function.
""" """
raise AbstractFunctionError() raise AbstractFunctionError()
def make_result(self, name = None):
"""Return a new `Result` instance of Type `self`.
:Parameters:
- `name`: None or str
A pretty string for printing and debugging.
"""
r = Result(self, name = name)
return r
def __call__(self, name = None):
"""Return a new `Result` instance of Type `self`.
:Parameters:
- `name`: None or str
A pretty string for printing and debugging.
"""
r = self.make_result(name)
r.tag.trace = traceback.extract_stack()[:-1]
return r
class Type(object2, PureType, CLinkerType):
"""Convenience wrapper combining `PureType` and `CLinkerType`.
Theano comes with several subclasses of {{{theano.type}}} such as:
- `Generic`: for any python type
- `Tensor`: for numpy.ndarray
- `Sparse`: for scipy.sparse
But you are encouraged to write your own, as described in WRITEME.
In the following code:
.. code-block:: python
# Note: tensor.fvector is a Type (subtype Tensor) instance
# Declare a symbolic floating-point vector using __call__
b = tensor.fvector()
# Create a second Result with the same Type instance
c = tensor.fvector()
Whenever you create a symbolic variable in theano (technically, `Result`) it will contain
a reference to a Type instance.
That reference is typically constant during the lifetime of the Result.
Many variables can refer to a single Type instance, as do b and c above.
The Type instance defines the kind of value which might end up in that variable when executing a
`Function`. In this sense, theano is like a strongly-typed language because the types are
included in the graph before the values. In
our example above, b is a Result which is guaranteed to corresond to a
numpy.ndarray of rank 1 when we try to do some computations with it.
Many `Op` instances will raise an exception if they are applied to inputs with incorrect
types. Type references are also useful to do type-checking in pattern-based optimizations.
"""
class SingletonType(Type): class SingletonType(Type):
__instance = None __instance = None
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论