type – Interface for types of variables

Reference

WRITEME

Defines the Type class.

  • class theano.gof.type.CDataType(ctype, freefunc=None, headers=(), header_dirs=(), libraries=(), lib_dirs=(), compile_args=(), extra_support_code='', version=None)[source]
  • Represents opaque C data to be passed around. The intent is toease passing arbitrary data between ops C code.

The constructor builds a type made to represent a C pointer in theano.

Parameters:

  • ctype – The type of the pointer (complete with the *).
  • freefunc – A function to call to free the pointer. This function musthave a void return and take a single pointer argument.
  • version – The version to use in Theano cache system.
  • makevalue(_ptr)[source]
  • Make a value of this type.

Parameters:ptr (int) – Integer representation of a valid pointer value

  • class theano.gof.type.CEnumType(*args, **kwargs)[source]
    • Inherit from:
      • EnumList Op parameter class that allows to create enumeration of constant values that represent C-defined constants.
  • Constant should have same names as in C.
  • In Python, constants will have arbitrary-defined values. They should be used only for choices, not for its values.
  • In C code, the real values defined in C will be used. They could be used either for choices or for its real values.

Like EnumList, you can also define the C type and a C name for the op param.Default C type is int.

  1. enum = CEnumType('CONSTANT_CNAME_1', 'CONSTANT_CNAME_2', 'CONSTANT_CNAME_3', ctype='long')

Like EnumList, you can also add an alias to a constant, with same syntax as in EnumList.

See test theano.gof.tests.test_types.TestEnumTypes.test_op_with_cenumtype() for a working example.

Note

Be sure C constants are available in your C code. If they come from a C header, consider implementingc_headers() and c_header_dirs() in the Op class where you use CEnumType as op parameter type.

  • class theano.gof.type.CLinkerType[source]
  • Interface specification for Types that can be arguments to a CLinkerOp.

A CLinkerType instance is mainly reponsible for providing the C code thatinterfaces python objects with a C CLinkerOp implementation.

See WRITEME for a general overview of code generation by CLinker.

  • ccleanup(_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 decreasepy%(name)s’s reference count.

WRITEME

Parameters:

  1. - **name** (_WRITEME_) WRITEME
  2. - **sub** (_WRITEME_) WRITEMERaises:

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 notbe cached between processes.

The cache mechanism may erase cached modules that have beensuperceded by newer versions. See ModuleCache for details.

  • cdeclare(_name, sub, check_input=True)[source]
  • Required: Return c code to declare variables that will beinstantiated by c_extract.

Parameters:

  1. - **name** (_str_) The name of the <code>PyObject *</code> pointer that willthe value for this Type
  2. - **sub** (_dict string -&gt; string_) a dictionary of special codes. Most importantlysub[‘fail’]. See CLinker for more info on _sub_ and <code>fail</code>.

Notes

It is important to include the name inside of variables whichare declared here, so that name collisions do not occur in thesource file that is generated.

The variable called name is not necessarily defined yetwhere this code is inserted. This code might be inserted tocreate class variables for example, whereas the variable namemight 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_element_type()[source]
  • Optional: Return the name of the primitive C type of items into variableshandled by this type.

e.g:

  • For TensorType(dtype='int64', …): should return "npy_int64".
  • For GpuArrayType(dtype='int32', …): should return "ga_int".
  • cextract(_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 tocall this Variable. The Python object self.data is in avariable called “py%(name)s” and this code must set thevariables declared by c_declare to something representativeof py%(name)s. If the data is improper, set an appropriateexception and insert “%(fail)s”.

  1. - TODO: Point out that template filling (via sub) is now performed
  2. - by this function. jpt

Parameters:

  1. - **name** (_str_) The name of the <code>PyObject *</code> pointer that willstore the value for this Type.
  2. - **sub** (_dict string -&gt; string_) A dictionary of special codes. Most importantlysub[‘fail’]. See CLinker for more info on _sub_ and <code>fail</code>.Raises:

MethodNotDefined – Subclass does not implement this method.

Examples

  • cextract_out(_name, sub, check_input=True)[source]
  • Optional: C code to extract a PyObject * instance.

Unlike c_extract, c_extract_out has to accept Py_None,meaning that the variable should be left uninitialized.

  • cinit(_name, sub)[source]
  • Required: Return c code to initialize the variables that were declaredby self.c_declare().

Notes

The variable called name is not necessarily defined yetwhere this code is inserted. This code might be inserted in aclass constructor for example, whereas the variable namemight only exist inside certain functions in that class.

TODO: Why should variable initialization fail? Is it even allowed to?

Examples

  • c_is_simple()[source]
  • Optional: Return True for small or builtin C types.

A hint to tell the compiler that this type is a builtin C type or asmall struct and that its memory footprint is negligible. Simpleobjects may be passed on the stack.

  • cliteral(_data)[source]
  • Optional: WRITEME

Parameters:data (WRITEME) – WRITEMERaises:MethodNotDefined – Subclass does not implement this method.

  • csync(_name, sub)[source]
  • Required: Return C code to pack C types back into a PyObject.

The code returned from this function must be templated using“%(name)s”, representing the name that the caller wants tocall this Variable. The returned code may set “py%(name)s”to a PyObject and that PyObject will be accessible fromPython via variable.data. Do not forget to adjust referencecounts if “py%(name)s” is changed from its original value.

Parameters:

  1. - **name** (_WRITEME_) WRITEME
  2. - **sub** (_WRITEME_) WRITEMERaises:

MethodNotDefined – Subclass does not implement this method.

  • class theano.gof.type.EnumList(*args, **kwargs)[source]
    • Inherit from:
      • EnumType Op parameter class that allows to create enumeration of constant values.Same as EnumType, but automatically gives an unique integer value for each constant in a list ofconstants names (constant at index i in the list will receive value i,with i from 0 to len(constants) - 1).

Example:

  1. enum = EnumList('CONSTANT_1', 'CONSTANT_2', 'CONSTANT_3', 'CONSTANT_4', 'CONSTANT_5')
  2. print (enum.CONSTANT_1, enum.CONSTANT_2, enum.CONSTANT_3, enum.CONSTANT_4, enum.CONSTANT_5)
  3. # will print: 0 1 2 3 4

Like EnumType, you can also define the C type and a C name for the op param.Default C type is int:

  1. enum = EnumList('CONSTANT_1', 'CONSTANT_2', 'CONSTANT_3', 'CONSTANT_4', ctype='unsigned int')

Like EnumType, you can also add an alias to a constant, by replacing the only constant name(e.g. 'CONSTANT_NAME') by a couple with constant name first and constant alias second(e.g. ('CONSTANT_NAME', 'constant_alias')).

  1. enum = EnumList(('A', 'alpha'), ('B', 'beta'), 'C', 'D', 'E', 'F', ('G', 'gamma'))

See test class theano.gof.tests.test_types.TestOpEnumList for a working example.

  • class theano.gof.type.EnumType(**kwargs)[source]
    • Main subclasses:
      • EnumList
      • CEnumType Op parameter class that allows to create enumerations of constant values.
  • Constants are available as object attributes in Python code and as macro-defined constants in C code.
  • Constants can be floating values, integers, or booleans (automatically converted to integers).
  • Constants name must start with a capital letter and contain capital letters, underscores or digits.
  • A constant can have an alias, and then be available through both constant name and constant alias.

Example

  1. enum = EnumType(CONSTANT_1=1, CONSTANT_2=2.5, CONSTANT_3=False, CONSTANT_4=True)
  2. print (enum.CONSTANT_1, enum.CONSTANT_2, enum.CONSTANT_3, enum.CONSTANT_4)
  3. # will print 1 2.5 0 1

In C code:

  1. int constant_1 = CONSTANT_1;
  2. double constant_2 = CONSTANT_2;
  3. int constant_3 = CONSTANT_3; // constant_3 == 0
  4. int constant_4 = CONSTANT_4; // constant_4 == 1

You can also specify a C type for the op param. Default C type is double.

  1. enum = EnumType(CONSTANT_1=0, CONSTANT_2=1, CONSTANT_3=2, ctype='size_t')
  2. # In C code, the Op param will then be a ``size_t``.

Note

You can also specify a C name (cname) or the current enumeration. This C name may beused to name functions related to that specific enumeration, e.g. for debuggingpurposes. Default C name is the C type (with any sequence of spaces replaced withan underscore). If you want to debug and your C type is quite generic (e.g.int or double), we recommend you specify a C name.

C name must be a valid C identifier.

  1. enum = EnumType(CONSTANT_1=0, CONSTANT_2=1, CONSTANT_3=2,
  2. ctype='size_t', cname='MyEnumName')

Example with aliases

When creating an enum, you can give some aliases to specific constants while keeping other constants without aliases.An alias must be a string, and there is currently no string format constraints.

To give an alias to a constant in the EnumType constructor, use the following key-value syntax:

  1. constant_name=(constant_alias, constant_value)

You can then retrieve a constant from an alias with method EnumType.fromalias().

Aliases are intended to be used in Python code only (only constants names are available in C code).Especially, an alias will be recognized by Enumtype.filter() method with non-strict filtering,allowing a maximum flexibility for converting strings to numeric constants available in Python and C code.

  1. from theano.gof import EnumType
  2.  
  3. # You can remark that constant 'C' does not have an alias.
  4. enum = EnumType(A=('alpha', 1), B=('beta', 2), C=3, D=('delta', 4))
  5.  
  6. # Constants are all directly available by name.
  7. print(enum.A, enum.B, enum.C, enum.D)
  8.  
  9. # But we can also now get some constants by alias.
  10. a = enum.fromalias('alpha')
  11. b = enum.fromalias('beta')
  12. d = enum.fromalias('delta')
  13.  
  14. # If method fromalias() receives an unknown alias,
  15. # it will looks for a constant with this alias
  16. # as exact constant name.
  17. c = enum.fromalias('C') # will get enum.C
  18.  
  19. # An alias defined in an EnumType will be correctly converted with non-strict filtering.
  20. value = enum.filter('delta', strict=False)
  21. # value now contaisn enum.D, ie. 4.

Note

This Type (and subclasses) is not complete and should never be used for regular graph operations.

  • c_to_string()[source]
  • Return code for a C function that will convert an enumeration valueto a string representation. The function prototype is:
  1. int theano_enum_to_string_<cname>(<ctype> value, char* output_string);

Where ctype and cname are the C type and the C name of current Theano enumeration.

output_string should be large enough to contain the longest name in this enumeration.

If given value is unknown, the C function sets a Python ValueError exception and returns a non-zero.

This C function may be useful to retrieve some runtime informations.It is available in C code when theano flag config.cmodule.debug is set to True.

  • fromalias(alias)[source]
  • Get a constant value by its alias.If there is not such alias in this enum, look for a constantwith this alias as constant name.

  • get_aliases()[source]

  • Return the sorted tuple of all aliases in this enumeration.

  • hasalias(_alias)[source]

  • return True if and only if this enum has this alias.
  • class theano.gof.type.Generic[source]
  • Represents a generic Python object.

This class implements the PureType and CLinkerType interfacesfor generic PyObject instances.

EXAMPLE of what this means, or when you would use this type.

WRITEME

  • class theano.gof.type.PureType[source]
  • Interface specification for variable type instances.

A Type instance is mainly reponsible for two things:

  • creating Variable instances (conventionally, call does this), and
  • filtering a value assigned to a Variable so that the valueconforms to restrictions imposed by the type (also known ascasting, this is done by filter).
  • class Constant(type, data, name=None)[source]
  • A Constant is a Variable with a value field that cannot bechanged at runtime.

Constant nodes make eligible numerous optimizations: constant inlining inC code, constant folding, etc.

Notes

The data field is filtered by what is provided in the constructor for theConstant’s type field.

WRITEME

  1. - <code>clone</code>()[[source]](https://github.com/Theano/theano/blob/d395439aec5a6ddde8ef5c266fd976412a5c5695/theano/gof/graph.py#L601-L609)[](#theano.gof.type.PureType.Constant.clone)
  2. -

We clone this object, but we don’t clone the data to lower memoryrequirement. We suppose that the data will never change.

  1. - <code>value</code>[[source]](https://github.com/Theano/theano/blob/d395439aec5a6ddde8ef5c266fd976412a5c5695/theano/gof/type.py)[](#theano.gof.type.PureType.Constant.value)
  2. -

read-only data access method

  • class PureType.Variable(type, owner=None, index=None, name=None)[source]
  • A Variable is a node in an expression graph that represents avariable.

The inputs and outputs of every Apply (theano.gof.Apply) are Variable_instances. The input and output arguments to create a _function are alsoVariable instances. A Variable is like a strongly-typed variable insome other languages; each Variable contains a reference to a Type_instance that defines the kind of value the _Variable can take in acomputation.

A Variable is a container for four important attributes:

  1. - <code>type</code> a _Type_ instance defining the kind of value this_Variable_ can have,
  2. - <code>owner</code> either None (for graph roots) or the _Apply_ instanceof which _self_ is an output,
  3. - <code>index</code> the integer such that <code>owner.outputs[index] is

thisvariable (ignored if _owner is None),

  1. - <code>name</code> a string to use in pretty-printing and debugging.

There are a few kinds of Variables to be aware of: A Variable which is theoutput of a symbolic computation has a reference to the Apply instance towhich it belongs (property: owner) and the position of itself in the owner’soutput list (property: index).

  1. -

Variable (this base type) is typically the output of a symboliccomputation.

  1. -

Constant (a subclass) which adds a default and un-replaceablevalue, and requires that owner is None.

  1. -
  2. - _TensorVariable_ subclass of Variable that represents a numpy.ndarray
  3. -

object.

  1. -

TensorSharedVariable Shared version of TensorVariable.

  1. -

SparseVariable subclass of Variable that representsa scipy.sparse.{csc,csr}_matrix object.

  1. -

GpuArrayVariable subclass of Variable that represents our object onthe GPU that is a subset of numpy.ndarray.

  1. -

RandomVariable.

A Variable which is the output of a symbolic computation will have an ownernot equal to None.

Using the Variables’ owner field and the Apply nodes’ inputs fields, one cannavigate a graph from an output all the way to the inputs. The oppositedirection is not possible until a FunctionGraph has annotated the Variableswith the clients field, ie, before the compilation process has begun aVariable does not know which Apply nodes take it as input.

Parameters:

  1. - **type** (_a Type instance_) The type governs the kind of data that can be associated with thisvariable.
  2. - **owner** (_None__ or __Apply instance_) The Apply instance which computes the value for this variable.
  3. - **index** (_None__ or __int_) The position of this Variable in owner.outputs.
  4. - **name** (_None__ or __str_) A string for pretty-printing and debugging.

Examples

  1. import theano
  2. from theano import tensor
  3.  
  4. a = tensor.constant(1.5) # declare a symbolic constant
  5. b = tensor.fscalar() # declare a symbolic floating-point scalar
  6.  
  7. c = a + b # create a simple expression
  8.  
  9. f = theano.function([b], [c]) # this works because a has a value associated with it already
  10.  
  11. assert 4.0 == f(2.5) # bind 2.5 to an internal copy of b and evaluate an internal c
  12.  
  13. theano.function([a], [c]) # compilation error because b (required by c) is undefined
  14.  
  15. theano.function([a,b], [c]) # compilation error because a is constant, it can't be an input
  16.  
  17. d = tensor.value(1.5) # create a value similar to the constant 'a'
  18. e = d + b
  19. theano.function([d,b], [e]) # this works. d's default value of 1.5 is ignored.

The python variables a,b,c all refer to instances of typeVariable. The Variable refered to by a is also an instance ofConstant.

compile.function uses each Apply instance’s inputs attribute togetherwith each Variable’s owner field to determine which inputs are necessaryto compute the function’s outputs.

  1. - <code>clone</code>()[[source]](https://github.com/Theano/theano/blob/d395439aec5a6ddde8ef5c266fd976412a5c5695/theano/gof/graph.py#L435-L455)[](#theano.gof.type.PureType.Variable.clone)
  2. -

Return a new Variable like self.

Returns:A new Variable instance (or subclass instance) with no owner orindex.Return type:Variable instance

Notes

Tags are copied to the returned instance.

Name is copied to the returned instance.

  1. - <code>eval</code>(_inputs_to_values=None_)[[source]](https://github.com/Theano/theano/blob/d395439aec5a6ddde8ef5c266fd976412a5c5695/theano/gof/graph.py#L478-L527)[](#theano.gof.type.PureType.Variable.eval)
  2. -

Evaluates this variable.

Parameters:inputs_to_values – A dictionary mapping theano Variables to values.

Examples

  1. >>> import numpy as np
  2. >>> import theano.tensor as T
  3. >>> x = T.dscalar('x')
  4. >>> y = T.dscalar('y')
  5. >>> z = x + y
  6. >>> np.allclose(z.eval({x : 16.3, y : 12.1}), 28.4)
  7. True

We passed eval() a dictionary mapping symbolic theanovariables to the values to substitute for them, and it returnedthe numerical value of the expression.

Notes

eval will be slow the first time you call it on a variable –it needs to call function() to compile the expression behindthe scenes. Subsequent calls to eval() on that same variablewill be fast, because the variable caches the compiled function.

This way of computing has more overhead than a normal Theanofunction, so don’t use it too much in real scripts.

  • PureType.convertvariable(_var)[source]
  • Patch variable so that its type will match self, if possible.

If the variable can’t be converted, this should return None.

The conversion can only happen if the following implication istrue for all possible val.

self.is_valid_value(val) => var.type.is_valid_value(val)

For the majority of types this means that you can only havenon-broadcastable dimensions become broadcastable and not theinverse.

The default is to not convert anything which is always safe.

  • PureType.filter(data, strict=False, allow_downcast=None)[source]
  • Required: Return data or an appropriately wrapped/converted data.

Subclass implementation should raise a TypeError exception ifthe data is not of an acceptable type.

If strict is True, the data returned must be the same as thedata passed as an argument. If it is False, and allow_downcastis True, filter may cast it to an appropriate type. Ifallow_downcast is False, filter may only upcast it, not loseprecision. If allow_downcast is None (default), the behaviour can beType-dependent, but for now it means only Python floats can bedowncasted, and only to floatX scalars.

Raises:MethodNotDefined – Subclass doesn’t implement this function.

  • PureType.filtervariable(_other, allow_convert=True)[source]
  • Convert a symbolic variable into this Type, if compatible.

For the moment, the only Types compatible with one another areTensorType and GpuArrayType, provided they have the samenumber of dimensions, same broadcasting pattern, and samedtype.

If Types are not compatible, a TypeError should be raised.

  • PureType.isvalid_value(_a)[source]
  • Required: Return True for any python object a that would be alegal value for a Variable of this Type.

  • PureType.makevariable(_name=None)[source]

  • Return a new Variable instance of Type self.

Parameters:name (None or str) – A pretty string for printing and debugging.

  • PureType.valuevalidity_msg(_a)[source]
  • Optional: Return a message explaining the output ofis_valid_value.

  • PureType.valueseq(_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.

  • PureType.valueseq_approx(_a, b)[source]
  • Return True if a and b can be considered approximately equal.

This function is used by theano debugging tools to decidewhether two values are equivalent, admitting a certain amountof numerical instability. For example, for floating-pointnumbers this function should be an approximate comparison.

By default, this does an exact comparison.

Parameters:

  1. - **a** A potential value for a Variable of this Type.
  2. - **b** A potential value for a Variable of this Type.Returns:

Return type: bool

  • class theano.gof.type.SingletonType[source]
  • Convenient Base class for a Type subclass with no attributes.

It saves having to implement eq and hash.

  • class theano.gof.type.Type[source]
  • Convenience wrapper combining PureType and CLinkerType.

Theano comes with several subclasses of such as:

  • Generic: for any python type
  • TensorType: for numpy.ndarray
  • SparseType: for scipy.sparse But you are encouraged to write your own, as described in WRITEME.

The following code illustrates the use of a Type instance,here tensor.fvector:

  1. # Declare a symbolic floating-point vector using __call__
  2. b = tensor.fvector()
  3.  
  4. # Create a second Variable with the same Type instance
  5. c = tensor.fvector()

Whenever you create a symbolic variable in theano (technically,Variable) it will contain a reference to a Type instance. Thatreference is typically constant during the lifetime of theVariable. Many variables can refer to a single Type instance, asdo b and c above. The Type instance defines the kind of valuewhich might end up in that variable when executing a Function.In this sense, theano is like a strongly-typed language becausethe types are included in the graph before the values. In ourexample above, b is a Variable which is guaranteed to correspondto a numpy.ndarray of rank 1 when we try to do some computationswith it.

Many Op instances will raise an exception if they are applied toinputs with incorrect types. Type references are also useful todo type-checking in pattern-based optimizations.