theano.gof.params_type
– Wrapper class for op params¶
Reference¶
Module for wrapping many Op parameters into one object available in both Python and C code.
The module provides the main public class ParamsType
that allows to bundle many Theano types
into one parameter type, and an internal convenient class Params
which will be automatically
used to create a Params object that is compatible with the ParamsType defined.
The Params object will be available in both Python code (as a standard Python object) and C code (as a specific struct with parameters as struct fields). To be fully-available in C code, Theano types wrapped into a ParamsType must provide a C interface (e.g. TensorType, Scalar, GpuArrayType, or your own type. See Using Op params for more details).
Example of usage¶
Importation:
# Import ParamsType class.
from theano.gof import ParamsType
# If you want to use a tensor and a scalar as parameters,
# you should import required Theano types.
from theano.tensor import TensorType
from theano.scalar import Scalar
In your Op sub-class:
params_type = ParamsType(attr1=TensorType('int32', (False, False)), attr2=Scalar('float64'))
If your op contains attributes attr1
and attr2
, the default op.get_params()
implementation will automatically try to look for it and generate an appropriate Params object.
Attributes must be compatible with the corresponding types defined into the ParamsType
(we will try to convert and downcast if needed). In this example, your_op.attr1
should be a matrix of integers, and your_op.attr2
should be a real number (integer or floating value).
def __init__(value_attr1, value_attr2):
self.attr1 = value_attr1
self.attr2 = value_attr2
In perform()
implementation (with params named param
):
matrix_param = param.attr1
number_param = param.attr2
In c_code()
implementation (with param = sub['params']
):
PyArrayObject* matrix = param->attr1;
npy_float64 number = param->attr2;
/* You won't need to free them or whatever else. */
See QuadraticOpFunc
and QuadraticCOpFunc
in theano/gof/tests/test_params_type.py
for complete working examples.
Combining ParamsType with Theano enumeration types¶
Theano provide some enumeration types that allow to create constant primitive values (integer and floating values)
available in both Python and C code. See theano.gof.type.EnumType
and its subclasses for more details.
If your ParamsType contains Theano enumeration types, then constants defined inside these enumerations will be directly available as ParamsType attributes.
Example:
from theano.gof import ParamsType, EnumType, EnumList
wrapper = ParamsType(enum1=EnumList('CONSTANT_1', 'CONSTANT_2', 'CONSTANT_3'),
enum2=EnumType(PI=3.14, EPSILON=0.001))
# Each enum constant is available as a wrapper attribute:
print(wrapper.CONSTANT_1, wrapper.CONSTANT_2, wrapper.CONSTANT_3,
wrapper.PI, wrapper.EPSILON)
# For convenience, you can also look for a constant by name with
# ``ParamsType.get_enum()`` method.
pi = wrapper.get_enum('PI')
epsilon = wrapper.get_enum('EPSILON')
constant_2 = wrapper.get_enum('CONSTANT_2')
print(pi, epsilon, constant_2)
This implies that a ParamsType cannot contain different enum types with common enum names:
# Following line will raise an error,
# as there is a "CONSTANT_1" defined both in enum1 and enum2.
wrapper = ParamsType(enum1=EnumList('CONSTANT_1', 'CONSTANT_2'),
enum2=EnumType(CONSTANT_1=0, CONSTANT_3=5))
If your enum types contain constant aliases, you can retrive them from ParamsType
with ParamsType.enum_from_alias(alias)
method (see theano.gof.type.EnumType
for more info about enumeration aliases).
wrapper = ParamsType(enum1=EnumList('A', ('B', 'beta'), 'C'),
enum2=EnumList(('D', 'delta'), 'E', 'F'))
b1 = wrapper.B
b2 = wrapper.get_enum('B')
b3 = wrapper.enum_from_alias('beta')
assert b1 == b2 == b3
-
class
theano.gof.params_type.
Params
(params_type, **kwargs)[source]¶ Internal convenient class to wrap many Python objects into one (this class is not safe as the hash method does not check if values are effectively hashable).
Example:
from theano.gof import ParamsType, Params from theano.scalar import Scalar # You must create a ParamsType first: params_type = ParamsType(attr1=Scalar('int32'), key2=Scalar('float32'), field3=Scalar('int64')) # Then you can create a Params object with # the params type defined above and values for attributes. params = Params(params_type, attr1=1, key2=2.0, field3=3) print(params.attr1, params.key2, params.field3) d = dict(attr1=1, key2=2.5, field3=-1) params2 = Params(params_type, **d) print(params2.attr1, params2.key2, params2.field3)
-
class
theano.gof.params_type.
ParamsType
(**kwargs)[source]¶ This class can create a struct of Theano types (like TensorType, GpuArrayType, etc.) to be used as a convenience op parameter wrapping many data.
ParamsType constructor takes key-value args. Key will be the name of the attribute in the struct. Value is the Theano type of this attribute, ie. an instance of (a subclass of)
Type
(eg.TensorType('int64', (False,))
).In a Python code any attribute named
key
will be available via:structObject.key
In a C code, any attribute named
key
will be available via:structObject->key;
Note
This Type is not complete and should never be used for regular graph operations.
-
has_type
(theano_type)[source]¶ Return True if current ParamsType contains the specified Theano type.
-
get_type
(field_name)[source]¶ Return the Theano type associated to the given field name in the current ParamsType.
-
get_field
(theano_type)[source]¶ Return the name (string) of the first field associated to the given Theano type. Fields are sorted in lexicographic order. Raise an exception if this Theano type is not in the current ParamsType.
This method is intended to be used to retrieve a field name when we know that current ParamsType contains the given Theano type only once.
-
get_enum
(key)[source]¶ Look for a constant named
key
in the Theano enumeration types wrapped into current ParamsType. Return value of the constant found, or raise an exception if either the constant is not found or current wrapper does not contain any Theano enumeration type.Example:
from theano.gof import ParamsType, EnumType, EnumList from theano.scalar import Scalar wrapper = ParamsType(scalar=Scalar('int32'), letters=EnumType(A=1, B=2, C=3), digits=EnumList('ZERO', 'ONE', 'TWO')) print(wrapper.get_enum('C')) # 3 print(wrapper.get_enum('TWO')) # 2 # You can also directly do: print(wrapper.C) print(wrapper.TWO)
-
enum_from_alias
(alias)[source]¶ Look for a constant that has alias
alias
in the Theano enumeration types wrapped into current ParamsType. Return value of the constant found, or raise an exception if eitherthere is no constant with this alias,
there is no constant which name is this alias, or
current wrapper does not contain any Theano enumeration type.
Example:
from theano.gof import ParamsType, EnumType, EnumList from theano.scalar import Scalar wrapper = ParamsType(scalar=Scalar('int32'), letters=EnumType(A=(1, 'alpha'), B=(2, 'beta'), C=3), digits=EnumList(('ZERO', 'nothing'), ('ONE', 'unit'), ('TWO', 'couple'))) print(wrapper.get_enum('C')) # 3 print(wrapper.get_enum('TWO')) # 2 print(wrapper.enum_from_alias('alpha')) # 1 print(wrapper.enum_from_alias('nothing')) # 0 # For the following, alias 'C' is not defined, so the method looks for # a constant named 'C', and finds it. print(wrapper.enum_from_alias('C')) # 3
Note
Unlike with constant names, you can NOT access constants values directly with aliases through ParamsType (ie. you can’t write
wrapper.alpha
). You must usewrapper.enum_from_alias()
method to do that.
-
get_params
(*objects, **kwargs)[source]¶ Convenient method to extract fields values from a list of Python objects and key-value args, and wrap them into a
Params
object compatible with current ParamsType.For each field defined in the current ParamsType, a value for this field is looked for in the given objects attributes (looking for attributes with this field name) and key-values args (looking for a key equal to this field name), from left to right (first object, then, …, then last object, then key-value args), replacing a previous field value found with any value found in next step, so that only the last field value found is retained.
Fields values given in objects and kwargs must be compatible with types associated to corresponding fields in current ParamsType.
Example:
import numpy from theano.gof import ParamsType from theano.tensor import dmatrix from theano.scalar import Scalar class MyObject: def __init__(self): self.a = 10 self.b = numpy.asarray([[1, 2, 3], [4, 5, 6]]) params_type = ParamsType(a=Scalar('int32'), b=dmatrix, c=Scalar('bool')) o = MyObject() value_for_c = False # Value for c can't be retrieved from o, so we add a value for that field in kwargs. params = params_type.get_params(o, c=value_for_c) # params.a contains 10 # params.b contains [[1, 2, 3], [4, 5, 6]] # params.c contains value_for_c print(params)
-
extended
(**kwargs)[source]¶ Return a copy of current ParamsType extended with attributes given in kwargs. New attributes must follow same rules as in ParamsType constructor.
-
filter
(data, strict=False, allow_downcast=None)[source]¶ 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, and allow_downcast is True, filter may cast it to an appropriate type. If allow_downcast is False, filter may only upcast it, not lose precision. If allow_downcast is None (default), the behaviour can be Type-dependent, but for now it means only Python floats can be downcasted, and only to floatX scalars.
- Raises
MethodNotDefined – Subclass doesn’t implement this function.
-
values_eq
(a, b)[source]¶ Return True if a and b can be considered exactly equal.
a and b are assumed to be valid values of this Type.
-
values_eq_approx
(a, b)[source]¶ Return True if a and b can be considered approximately equal.
This function is used by theano debugging tools to decide whether two values are equivalent, admitting a certain amount of numerical instability. For example, for floating-point numbers this function should be an approximate comparison.
By default, this does an exact comparison.
- Parameters
a – A potential value for a Variable of this Type.
b – A potential value for a Variable of this Type.
- Returns
- Return type
bool
-
c_compile_args
(c_compiler)[source]¶ Optional: Return a list of compile args recommended to compile the code returned by other methods in this class.
Example
return [‘-ffast-math’]
Compiler arguments related to headers, libraries and search paths should be provided via the functions c_headers, c_libraries, c_header_dirs, and c_lib_dirs.
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_no_compile_args
(c_compiler)[source]¶ Optional: return a list of incompatible gcc compiler arguments.
We will remove those arguments from the command line of gcc. So if another Op adds a compile arg in the graph that is incompatible with this Op, the incompatible arg will not be used. Useful for instance to remove -ffast-math.
EXAMPLE
WRITEME
- Raises
MethodNotDefined – The subclass does not override this method.
-
c_headers
(c_compiler)[source]¶ Optional: Return a list of header files required by code returned by this class.
Examples
return [‘<iostream>’, ‘<math.h>’, ‘/full/path/to/header.h’]
These strings will be prefixed with “#include ” and inserted at the beginning of the c source code.
Strings in this list that start neither with ‘<’ nor ‘”’ will be enclosed in double-quotes.
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_libraries
(c_compiler)[source]¶ Optional: Return a list of libraries required by code returned by this class.
Examples
return [‘gsl’, ‘gslcblas’, ‘m’, ‘fftw3’, ‘g2c’].
The compiler will search the directories specified by the environment variable LD_LIBRARY_PATH in addition to any returned by c_lib_dirs.
Hint: for unix compilers, these are the things that get ‘-l’ prefixed in the compiler cmdline.
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_header_dirs
()[source]¶ Optional: Return a list of header search paths required by code returned by this class.
Examples
return [‘/usr/local/include’, ‘/opt/weirdpath/src/include’]
Provides search paths for headers, in addition to those in any relevant environment variables.
Hint: for unix compilers, these are the things that get ‘-I’ prefixed in the compiler cmdline.
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_lib_dirs
()[source]¶ Optional: Return a list of library search paths required by code returned by this class.
Examples
return [‘/usr/local/lib’, ‘/opt/weirdpath/build/libs’].
Provides search paths for libraries, in addition to those in any relevant environment variables (e.g. LD_LIBRARY_PATH).
Hint: for unix compilers, these are the things that get ‘-L’ prefixed in the compiler cmdline.
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_init_code
()[source]¶ Optional: return a list of code snippets to be inserted in module initialization.
- Raises
MethodNotDefined – The subclass does not override this method.
-
c_support_code
()[source]¶ Optional: Return utility code (a string, or a list of strings) for use by a Variable 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?
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_code_cache_version
()[source]¶ Return a tuple of integers indicating the version of this Type.
An empty tuple indicates an ‘unversioned’ Type that will not be cached between processes.
The cache mechanism may erase cached modules that have been superceded by newer versions. See ModuleCache for details.
-
c_declare
(name, sub, check_input=True)[source]¶ Required: Return c code to declare variables that will be instantiated by c_extract.
- Parameters
name (str) – The name of the
PyObject *
pointer that will the value for this Typesub (dict string -> string) – a dictionary of special codes. Most importantly sub[‘fail’]. See CLinker for more info on sub and
fail
.
Notes
It is important to include the name inside of variables which are declared here, so that name collisions do not occur in the source file that is generated.
The variable called
name
is not necessarily defined yet where this code is inserted. This code might be inserted to create class variables for example, whereas the variablename
might only exist inside certain functions in that class.TODO: Why should variable declaration fail? Is it even allowed to?
- Raises
MethodNotDefined – Subclass does not implement this method.
Examples
-
c_init
(name, sub)[source]¶ Required: Return c code to initialize the variables that were declared by self.c_declare().
Notes
The variable called
name
is not necessarily defined yet where this code is inserted. This code might be inserted in a class constructor for example, whereas the variablename
might only exist inside certain functions in that class.TODO: Why should variable initialization fail? Is it even allowed to?
Examples
-
c_cleanup
(name, sub)[source]¶ Return C code to clean up after c_extract.
This returns C code that should deallocate whatever c_extract allocated or decrease the reference counts. Do not decrease py_%(name)s’s reference count.
WRITEME
- Parameters
name (WRITEME) – WRITEME
sub (WRITEME) – WRITEME
- Raises
MethodNotDefined – Subclass does not implement this method.
-
c_extract
(name, sub, check_input=True)[source]¶ Required: Return c code to extract a PyObject * instance.
The code returned from this function must be templated using
%(name)s
, representing the name that the caller wants to call this Variable. The Python object self.data is in a variable called “py_%(name)s” and this code must set the variables declared by c_declare to something representative of py_%(name)s. If the data is improper, set an appropriate exception and insert “%(fail)s”.- TODO: Point out that template filling (via sub) is now performed
by this function. –jpt
- Parameters
name (str) – The name of the
PyObject *
pointer that will store the value for this Type.sub (dict string -> string) – A dictionary of special codes. Most importantly sub[‘fail’]. See CLinker for more info on sub and
fail
.
- Raises
MethodNotDefined – Subclass does not implement this method.
Examples
-