提交 58a2fe2b authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Merged

syntax: glob syntax: glob
*.o
*.orig
*.pyc
*.pyo
*.so
*.sw?
*~ *~
Theano.egg-info
\#*\# \#*\#
build build
compiled/*.cpp compiled/*.cpp
...@@ -11,12 +18,6 @@ doc/.build/ ...@@ -11,12 +18,6 @@ doc/.build/
doc/indexes/oplist.txt doc/indexes/oplist.txt
doc/indexes/typelist.txt doc/indexes/typelist.txt
html html
*.o
*.orig
pdf pdf
pull.sh pull.sh
*.pyc setuptools-*.egg
*.pyo
*.so
*.sw?
Theano.egg-info
...@@ -77,7 +77,7 @@ attribute. ...@@ -77,7 +77,7 @@ attribute.
For detailed documentation on the Exception, see :api:`BadDestroyMap`. For detailed documentation on the Exception, see :api:`BadDestroyMap`.
For detailed documentation on the ``destroy_map`` attribute, see :ref:`_inplace`. For detailed documentation on the ``destroy_map`` attribute, see :ref:`inplace`.
BadViewMap BadViewMap
...@@ -89,7 +89,7 @@ optimization system via the ``view_map`` attribute. ...@@ -89,7 +89,7 @@ optimization system via the ``view_map`` attribute.
For detailed documentation on the Exception, see :api:`BadViewMap`. For detailed documentation on the Exception, see :api:`BadViewMap`.
For detailed documentation on the ``view_map`` attribute, see :ref:`_views`. For detailed documentation on the ``view_map`` attribute, see :ref:`views`.
StochasticOrder StochasticOrder
......
...@@ -5,21 +5,20 @@ ...@@ -5,21 +5,20 @@
Advanced Topics Advanced Topics
=============== ===============
Structure
=========
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
debug_faq
debugmode
env
features
optimization
compilation
ccodegen
function
module
pipeline pipeline
profilemode
unittest unittest
profilemode
debug_faq
debugmode
.. env
.. features
.. optimization
.. compilation
.. ccodegen
.. function
.. module
...@@ -10,7 +10,7 @@ compiling a Theano function. ...@@ -10,7 +10,7 @@ compiling a Theano function.
Definition of the computation graph Definition of the computation graph
=================================== -----------------------------------
By creating Theano :ref:`Variables <variable>` using By creating Theano :ref:`Variables <variable>` using
``theano.tensor.lscalar`` or ``theano.tensor.dmatrix`` or by using ``theano.tensor.lscalar`` or ``theano.tensor.dmatrix`` or by using
...@@ -22,9 +22,9 @@ in the :ref:`graphstructures` article. ...@@ -22,9 +22,9 @@ in the :ref:`graphstructures` article.
Compilation of the computation graph Compilation of the computation graph
==================================== ------------------------------------
Once the user has built a computation graph, he can use Once the user has built a computation graph, she can use
``theano.function`` or a ``theano.Method`` in a ``theano.module`` in ``theano.function`` or a ``theano.Method`` in a ``theano.module`` in
order to make one or more functions that operate on real data. Both order to make one or more functions that operate on real data. Both
function and Method take a list of input :ref:`Variables <variable>` function and Method take a list of input :ref:`Variables <variable>`
...@@ -37,7 +37,7 @@ computation graph in the compilation phase: ...@@ -37,7 +37,7 @@ computation graph in the compilation phase:
Step 1 - Create an Env Step 1 - Create an Env
====================== ^^^^^^^^^^^^^^^^^^^^^^
The subgraph given by the end user is wrapped in a structure called The subgraph given by the end user is wrapped in a structure called
:ref:`env`. That structure defines several hooks on adding and :ref:`env`. That structure defines several hooks on adding and
...@@ -56,7 +56,7 @@ inputs declared as immutable. ...@@ -56,7 +56,7 @@ inputs declared as immutable.
Step 2 - Execute main Optimizer Step 2 - Execute main Optimizer
=============================== ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once the Env is made, an :ref:`optimizer <optimization>` is produced Once the Env is made, an :ref:`optimizer <optimization>` is produced
by the :ref:`mode` passed to ``function`` or to the Method/Module's by the :ref:`mode` passed to ``function`` or to the Method/Module's
...@@ -68,7 +68,7 @@ The optimizer is typically obtained through :ref:`optdb <optdb>`. ...@@ -68,7 +68,7 @@ The optimizer is typically obtained through :ref:`optdb <optdb>`.
Step 3 - Execute linker to obtain a thunk Step 3 - Execute linker to obtain a thunk
========================================= ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once the computation graph is optimized, the :ref:`linker` is Once the computation graph is optimized, the :ref:`linker` is
extracted from the Mode. It is then called with the Env as argument to extracted from the Mode. It is then called with the Env as argument to
...@@ -99,21 +99,10 @@ case if ``borrow`` was True, the thunk would be allowed to reuse (or ...@@ -99,21 +99,10 @@ case if ``borrow`` was True, the thunk would be allowed to reuse (or
Step 4 - Wrap the thunk in a pretty package Step 4 - Wrap the thunk in a pretty package
=========================================== ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The thunk returned by the linker along with input and output The thunk returned by the linker along with input and output
containers is unwieldy. ``function`` and ``Method`` hide that containers is unwieldy. ``function`` and ``Method`` hide that
complexity away so that it can be used like a normal function with complexity away so that it can be used like a normal function with
arguments and return values. arguments and return values.
...@@ -10,7 +10,7 @@ an argument when compiling your graph. Using ProfileMode is a three-step ...@@ -10,7 +10,7 @@ an argument when compiling your graph. Using ProfileMode is a three-step
process. process.
Creating a ProfileMode Instance Creating a ProfileMode Instance
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------------
First create a ProfileMode instance. First create a ProfileMode instance.
...@@ -33,7 +33,7 @@ find where most of the computation time is being spent. In this context, ...@@ -33,7 +33,7 @@ find where most of the computation time is being spent. In this context,
'fast_run' optimizer and ``gof.OpWiseCLinker`` are the most appropriate choices. 'fast_run' optimizer and ``gof.OpWiseCLinker`` are the most appropriate choices.
Compiling your Graph with ProfileMode Compiling your Graph with ProfileMode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once the ProfileMode instance is created, simply compile your graph as you Once the ProfileMode instance is created, simply compile your graph as you
would normally, by specifying the mode parameter. would normally, by specifying the mode parameter.
...@@ -45,7 +45,7 @@ would normally, by specifying the mode parameter. ...@@ -45,7 +45,7 @@ would normally, by specifying the mode parameter.
>>> minst = m.make(mode=profmode) >>> minst = m.make(mode=profmode)
Retrieving Timing Information Retrieving Timing Information
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once your graph is compiled, simply run the program or operation you wish to Once your graph is compiled, simply run the program or operation you wish to
profile, then call ``profmode.print_summary()``. This will provide you with profile, then call ``profmode.print_summary()``. This will provide you with
......
...@@ -15,7 +15,7 @@ Unit Testing revolves around the following principles: ...@@ -15,7 +15,7 @@ Unit Testing revolves around the following principles:
This page is in no way meant to replace tutorials on Python's unittest module, for this we refer the reader to the `official documentation <http://docs.python.org/library/unittest.html>`_. We will however adress certain specificities about how unittests relate to theano. This page is in no way meant to replace tutorials on Python's unittest module, for this we refer the reader to the `official documentation <http://docs.python.org/library/unittest.html>`_. We will however adress certain specificities about how unittests relate to theano.
How to Run Unit Tests ? How to Run Unit Tests ?
======================= -----------------------
Running all unit tests Running all unit tests
...@@ -36,7 +36,7 @@ Running a specific unit test ...@@ -36,7 +36,7 @@ Running a specific unit test
Folder Layout Folder Layout
============= -------------
"tests" directories are scattered throughout theano. Each tests subfolder is "tests" directories are scattered throughout theano. Each tests subfolder is
meant to contain the unittests which validate the .py files in the parent folder. meant to contain the unittests which validate the .py files in the parent folder.
......
差异被折叠。
差异被折叠。
...@@ -158,9 +158,3 @@ version that it produces in the code I gave above. ...@@ -158,9 +158,3 @@ version that it produces in the code I gave above.
div = BinaryDoubleOp(name = 'div', div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y, fn = lambda x, y: x / y,
ccode = "%(z)s = %(x)s / %(y)s;") ccode = "%(z)s = %(x)s / %(y)s;")
**Next:** `Views and inplace operations`_
.. _Views and inplace operations: ../inplace.html
...@@ -440,9 +440,3 @@ Final version ...@@ -440,9 +440,3 @@ Final version
return "" return ""
double = Double() double = Double()
**Next:** `Implementing the arithmetic Ops in C`_
.. _Implementing the arithmetic Ops in C: cop.html
...@@ -266,16 +266,3 @@ Final version ...@@ -266,16 +266,3 @@ Final version
We add one utility function, ``__str__``. That way, when we print We add one utility function, ``__str__``. That way, when we print
``double``, it will print out something sensible. ``double``, it will print out something sensible.
**Next:** `Making arithmetic Ops on double`_
.. _Making arithmetic Ops on double: op.html
...@@ -150,9 +150,3 @@ with numpy arrays may be found :ref:`here <predefinedtypes>`. ...@@ -150,9 +150,3 @@ with numpy arrays may be found :ref:`here <predefinedtypes>`.
You, the user---not the system architecture---have to choose whether your You, the user---not the system architecture---have to choose whether your
program will use 32- or 64-bit integers (``i`` prefix vs. the ``l`` prefix) program will use 32- or 64-bit integers (``i`` prefix vs. the ``l`` prefix)
and floats (``f`` prefix vs. the ``d`` prefix). and floats (``f`` prefix vs. the ``d`` prefix).
**Next:** `More examples`_
.. _More examples: examples.html
...@@ -255,8 +255,5 @@ array(5.9000000000000004) ...@@ -255,8 +255,5 @@ array(5.9000000000000004)
array(5.9000000000000004) array(5.9000000000000004)
**Next:** `Using Module`_
.. _Using Module: module.html
.. _automatic differentiation: http://en.wikipedia.org/wiki/Automatic_differentiation .. _automatic differentiation: http://en.wikipedia.org/wiki/Automatic_differentiation
...@@ -47,12 +47,12 @@ Here we instantiate an empty Module. ...@@ -47,12 +47,12 @@ Here we instantiate an empty Module.
>>> m.state = T.dscalar() >>> m.state = T.dscalar()
>>> m.inc = T.dscalar('inc')
Then we declare a Variable for use with our Module. That Variable will Then we declares for use with our Module.
be a :ref:`member` of the Module, which means that it will be Since we assign these input Variables as attributes of the Module,
accessible as a field of the object we will create later (for reading they will be *member Variables* of the Module.
and writing). It will also be accessible from any :ref:`method` Member Variables are special in a few ways, which we will see shortly.
defined in our Module.
.. note:: .. note::
...@@ -60,11 +60,6 @@ defined in our Module. ...@@ -60,11 +60,6 @@ defined in our Module.
be given the name 'state' automatically. be given the name 'state' automatically.
>>> m.inc = T.dscalar('inc')
The ``inc`` variable doesn't need to be declared as a member of ``m`` because
we only use it as a Method input.
.. note:: .. note::
Since we made it a member of ``m``, the ``acc`` object will have an Since we made it a member of ``m``, the ``acc`` object will have an
...@@ -74,9 +69,10 @@ we only use it as a Method input. ...@@ -74,9 +69,10 @@ we only use it as a Method input.
>>> m.new_state = m.state + m.inc >>> m.new_state = m.state + m.inc
This line creates a Variable corresponding to some symbolic computation. It This line creates a Variable corresponding to some symbolic computation.
doesn't matter to Theano whether we put it inside ``m`` or not. Feel free to Although this line also assigns a Variable to a Module attribute, it does not
put such results of symbolic computation wherever is most convenient. become a member Variable like state and inc because it represents an expression
result.
>>> m.add = Method(m.inc, m.new_state, {m.state: m.new_state}) >>> m.add = Method(m.inc, m.new_state, {m.state: m.new_state})
...@@ -97,16 +93,18 @@ Calling ``make`` on ``m`` creates an object that can do real ...@@ -97,16 +93,18 @@ Calling ``make`` on ``m`` creates an object that can do real
computation and whose attributes contain values such as numbers and numpy computation and whose attributes contain values such as numbers and numpy
ndarrays. ndarrays.
The keyword arguments given to make are optional and are used to At this point something special happens for our member Variables too.
assign initial values to each Member. If a Member is omitted, the In the 'acc' object, make allocates room to store numbers for m's member
initial value is None. Variables. By using the string 'state' as a keyword argument, we tell Theano to
store the number 0 for the member Variable called 'state'. By not mentioning
the 'inc' variable, we associate None to the 'inc' Variable.
>>> acc.state, acc.inc >>> acc.state, acc.inc
array(0.0), None array(0.0), None
Since state was declared as a Member, we can access it easily using Since 'state' was declared as a member Variable of 'm', we can access it's value
'.state'. in the 'acc' object by the same attribute. Ditto for 'inc'.
.. note:: .. note::
...@@ -118,18 +116,24 @@ Since state was declared as a Member, we can access it easily using ...@@ -118,18 +116,24 @@ Since state was declared as a Member, we can access it easily using
>>> acc.add(2) >>> acc.add(2)
array(2.0) array(2.0)
>>> acc.state >>> acc.state, acc.inc
array(2.0) array(2.0), None
When we call the ``acc.add`` method, all the updates given to the When we call the ``acc.add`` method, the value 2 is used for the symbolic 'm.inc'
corresponding Method's ``updates`` field are performed. We only had The first line evaluates the output and all the updates given to the
'acc' Method's ``updates`` field. We only had
one update which mapped ``state`` to ``new_state`` and you can see one update which mapped ``state`` to ``new_state`` and you can see
that it works as intended, adding the argument to the internal state. that it works as intended, adding the argument to the internal state.
Note also that 'acc.inc' is still None after our call. Since 'm.inc' was listed
as an input the Method, the method got it's own private storage container for
'm.inc'. If we had left 'm.inc' out of the Method input list, then it the
method would have used the module's storage for ``m.inc`` instead.
>>> acc.state = 39.99 >>> acc.state = 39.99
The state is also easy to set. When we manually set the value of a member The state can also be set. When we manually set the value of a member
attribute like this, then subsequent calls to the methods of our module will attribute like this, then subsequent calls to the methods of our module will
use the new value. use the new value.
...@@ -282,3 +286,4 @@ WRITEME ...@@ -282,3 +286,4 @@ WRITEME
...@@ -166,14 +166,3 @@ Ops ...@@ -166,14 +166,3 @@ Ops
There are a lot of operations available in the ``theano.tensor`` package. There are a lot of operations available in the ``theano.tensor`` package.
See :ref:`oplist`. See :ref:`oplist`.
**Next:** `Wrapping up`_
.. _Wrapping up: wrapup.html
...@@ -42,8 +42,8 @@ source_suffix = '.txt' ...@@ -42,8 +42,8 @@ source_suffix = '.txt'
master_doc = 'contents' master_doc = 'contents'
# General substitutions. # General substitutions.
project = 'theano' project = 'Theano'
copyright = '2008-2009, LISA lab' copyright = '2008--2009, LISA lab'
# The default replacements for |version| and |release|, also used in various # The default replacements for |version| and |release|, also used in various
# other places throughout the built documents. # other places throughout the built documents.
...@@ -64,7 +64,7 @@ today_fmt = '%B %d, %Y' ...@@ -64,7 +64,7 @@ today_fmt = '%B %d, %Y'
# List of directories, relative to source directories, that shouldn't be searched # List of directories, relative to source directories, that shouldn't be searched
# for source files. # for source files.
#exclude_dirs = [] exclude_dirs = ['images']
# The reST default role (used for this markup: `text`) to use for all documents. # The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None #default_role = None
...@@ -101,7 +101,7 @@ html_style = 'default.css' ...@@ -101,7 +101,7 @@ html_style = 'default.css'
# The name of an image file (within the static path) to place at the top of # The name of an image file (within the static path) to place at the top of
# the sidebar. # the sidebar.
#html_logo = None html_logo = 'images/theano_logo-200x67.png'
# The name of an image file (within the static path) to use as favicon of the # The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
...@@ -111,7 +111,7 @@ html_style = 'default.css' ...@@ -111,7 +111,7 @@ html_style = 'default.css'
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['.static'] html_static_path = ['.static', 'images']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format. # using the given strftime format.
...@@ -119,7 +119,7 @@ html_last_updated_fmt = '%b %d, %Y' ...@@ -119,7 +119,7 @@ html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to # If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities. # typographically correct entities.
#html_use_smartypants = True html_use_smartypants = True
# Custom sidebar templates, maps document names to template names. # Custom sidebar templates, maps document names to template names.
#html_sidebars = {} #html_sidebars = {}
...@@ -159,18 +159,19 @@ htmlhelp_basename = 'theanodoc' ...@@ -159,18 +159,19 @@ htmlhelp_basename = 'theanodoc'
#latex_paper_size = 'letter' #latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt'). # The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt' latex_font_size = '11pt'
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]). # (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [ latex_documents = [
('contents', 'theano.tex', 'theano Documentation', ('contents', 'theano.tex', 'theano Documentation',
'LISA lab', 'manual'), 'LISA lab, University of Montreal', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of
# the title page. # the title page.
#latex_logo = None #latex_logo = 'images/snake_theta2-trans.png'
latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts, # For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters. # not chapters.
......
...@@ -6,7 +6,7 @@ Contents ...@@ -6,7 +6,7 @@ Contents
======== ========
.. toctree:: .. toctree::
:maxdepth: 3 :maxdepth: 2
LICENSE LICENSE
introduction introduction
...@@ -16,8 +16,9 @@ Contents ...@@ -16,8 +16,9 @@ Contents
advanced_tutorial/index advanced_tutorial/index
advanced/index advanced/index
indexes/index indexes/index
examples/index
glossary glossary
links links
internal/index internal/index
sandbox/index
.. examples/index
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="345.86591"
height="115.13724"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.45.1"
sodipodi:docbase="/home/olivier/hg/theano"
sodipodi:docname="theano_logo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
inkscape:export-filename="/home/olivier/hg/theano/theano_logo_big.png"
inkscape:export-xdpi="273.58655"
inkscape:export-ydpi="273.58655">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="248.50886"
inkscape:cy="97.530852"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="1680"
inkscape:window-height="1030"
inkscape:window-x="0"
inkscape:window-y="0"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-219.06115,-88.23416)">
<path
id="path5572"
d="M 245.99986,202.38198 C 235.76172,199.76305 230.3317,195.18454 224.56469,184.30815 C 220.37775,176.41173 219.14676,170.92373 219.06742,159.80009 C 219.02952,154.48681 219.14363,153.33451 219.96737,150.71192 L 220.91072,147.70853 L 222.03485,150.91475 C 223.32792,154.60284 224.5932,157.2101 225.42491,157.90035 C 225.91931,158.31066 226.04839,157.45384 226.31509,151.99127 C 226.48664,148.47733 226.74177,144.59829 226.88203,143.3712 C 227.13637,141.14611 227.14306,141.13711 229.37079,140.02194 C 233.6165,137.89661 241.51289,137.62549 255.7355,139.11671 C 262.25557,139.80033 276.27711,139.65881 278.302,138.88894 C 280.15154,138.18575 280.55926,136.52884 280.07117,131.69921 C 279.49474,125.99537 279.0548,124.08561 277.22091,119.32634 C 272.4649,106.98367 264.75123,100.69911 254.31572,100.6648 C 244.91721,100.6339 237.20308,106.18784 232.64521,116.26692 C 228.63554,125.13371 226.84755,134.63837 225.79128,152.70119 L 225.49476,157.77183 L 224.6018,156.08339 C 220.32764,148.00176 218.55416,134.3005 220.39244,123.56361 C 221.81624,115.24763 224.72248,108.02444 229.43922,101.07873 C 233.51167,95.08179 239.33503,91.22689 247.37024,89.20891 C 252.54529,87.90924 256.08615,87.90924 261.2612,89.20891 C 269.29641,91.22689 275.11977,95.08179 279.19222,101.07873 C 283.85913,107.95107 286.81123,115.24029 288.1872,123.28884 C 289.11587,128.72102 289.26704,136.96138 288.48572,139.5625 C 287.80095,141.84221 282.75423,149.25874 282.58446,148.23482 C 282.51467,147.81394 282.66002,147.09129 282.90745,146.62895 C 283.60255,145.33016 282.97412,144.79606 281.91813,145.78812 C 281.09814,146.55845 280.95497,146.57992 280.4772,146.00425 C 279.46931,144.78981 279.09827,146.0508 280.02317,147.54731 C 281.09294,149.27824 281.11194,149.86163 280.09855,149.86163 C 279.6655,149.86163 279.2114,150.02307 279.08945,150.2204 C 278.12451,151.78171 263.15706,152.14918 251.27333,150.90331 C 242.48708,149.98217 235.49959,150.17874 233.86598,151.393 C 232.52086,152.39282 230.73981,155.92513 230.13832,158.78596 C 229.56685,161.50406 229.89814,169.75383 230.71167,173.06316 C 231.53272,176.40313 234.44347,181.26714 237.48117,184.37536 C 245.97324,193.06457 259.99042,193.16426 268.52866,184.59618 C 272.82158,180.28826 276.28725,173.36771 275.26986,171.13477 C 275.01206,170.56897 274.80113,169.46845 274.80113,168.68918 C 274.80113,167.27252 276.03299,164.34881 276.84003,163.85004 C 277.97809,163.14668 279.2633,160.34344 279.2633,158.56453 C 279.2633,156.50464 279.81574,155.1351 280.64665,155.1351 C 281.94053,155.1351 281.78744,149.84815 280.42796,147.58266 C 279.38328,145.84176 279.47773,145.48404 280.68309,146.61641 C 281.46075,147.34699 281.69721,147.42235 281.69721,146.93962 C 281.69721,146.59338 282.00521,146.05957 282.38164,145.75336 C 282.9932,145.2559 283.02559,145.28301 282.68588,146.00793 C 282.47678,146.45415 282.35906,148.62448 282.4243,150.8309 C 282.5319,154.47038 282.63024,154.91126 283.48431,155.58307 C 284.25335,156.18799 284.4647,156.82757 284.6386,159.07597 C 284.78839,161.01273 285.24037,162.64716 286.16384,164.59151 C 287.23183,166.84012 287.43789,167.69463 287.27043,169.18035 C 287.15459,170.2081 286.70684,171.3939 286.24597,171.89349 C 285.2295,172.99536 281.11174,180.12521 280.69642,181.50246 C 279.94371,183.99856 277.41503,189.23736 275.76462,191.71994 C 273.21329,195.55768 270.45935,197.86457 265.70147,200.14953 C 258.59319,203.56326 253.06615,204.18955 245.99986,202.38198 z "
style="fill:#000000;fill-opacity:1" />
<text
xml:space="preserve"
style="font-size:15.53327274px;font-style:normal;font-weight:normal;fill:#7799ee;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="285.01266"
y="186.09427"
id="text5574"
transform="scale(1.0402212,0.961334)"><tspan
sodipodi:role="line"
id="tspan5576"
x="285.01266"
y="186.09427"
style="font-size:93.19962311px;font-weight:normal;fill:#7799ee;fill-opacity:1;font-family:MgOpen Modata"
dx="0 -4.2857141 -6.4285722 -5 -5.7142901 -6.0714293"
dy="0 0 -1.3672954 0.35714287 1.0101526 -1.0101526">Theano</tspan></text>
</g>
</svg>
.. _install: .. _install:
=================
Installing Theano Installing Theano
================= =================
...@@ -9,7 +9,7 @@ Installing Theano ...@@ -9,7 +9,7 @@ Installing Theano
If you are a member of LISA Labo, have a look at :ref:`lisa_labo` for If you are a member of LISA Labo, have a look at :ref:`lisa_labo` for
lab-specific installation instructions. lab-specific installation instructions.
------------
Requirements Requirements
------------ ------------
...@@ -43,7 +43,6 @@ The following libraries and software are optional: ...@@ -43,7 +43,6 @@ The following libraries and software are optional:
To download bleeding-edge To download bleeding-edge
------------
Easy install Easy install
------------ ------------
...@@ -63,7 +62,6 @@ on your system: ...@@ -63,7 +62,6 @@ on your system:
.. Theano, when we figure out where to put it. .. Theano, when we figure out where to put it.
--------------
Manual install Manual install
-------------- --------------
...@@ -124,7 +122,6 @@ You may also download the latest source directly as a gzip'd tar file: ...@@ -124,7 +122,6 @@ You may also download the latest source directly as a gzip'd tar file:
`<http://pylearn.org/hg/theano/archive/tip.tar.gz>`__. `<http://pylearn.org/hg/theano/archive/tip.tar.gz>`__.
---------------------------
Configuring the environment Configuring the environment
--------------------------- ---------------------------
...@@ -161,7 +158,7 @@ automatic code generation, but that way is much, much slower. ...@@ -161,7 +158,7 @@ automatic code generation, but that way is much, much slower.
running unit tests. running unit tests.
Setting this value will make the unit tests deterministic. Setting this value will make the unit tests deterministic.
---
Mac Mac
--- ---
...@@ -185,7 +182,7 @@ Mac ...@@ -185,7 +182,7 @@ Mac
TODO: check if this is still valid TODO: check if this is still valid
-------
Windows Windows
------- -------
...@@ -194,7 +191,6 @@ never even been tested, so feel free to explore this uncharted ...@@ -194,7 +191,6 @@ never even been tested, so feel free to explore this uncharted
territory and inform us of your progress! territory and inform us of your progress!
----------------------------
Generating the documentation Generating the documentation
---------------------------- ----------------------------
......
...@@ -64,4 +64,33 @@ old changes by hand. ...@@ -64,4 +64,33 @@ old changes by hand.
For more info, check out the `homepage <http://www.selenic.com/mercurial/wiki/>`_ and `hg book <http://hgbook.red-bean.com/hgbook.html>`_. For more info, check out the `homepage <http://www.selenic.com/mercurial/wiki/>`_ and `hg book <http://hgbook.red-bean.com/hgbook.html>`_.
Tip: Commit before pull
------------------------
"This is the general rule of thumb when using Mercurial: finish your work
and commit it before you start pulling in stuff from the outside world."
-Martin Geisler
(http://www.selenic.com/pipermail/mercurial/2008-April/018817.html)
Tip: Graph logs
---------------
Update your .hgrc::
[ui]
username = Foo Bar <barfoo@iro.umontreal.ca>
[extensions]
hgext.graphlog =
Now try::
hg glog
Troubleshooting
---------------
If you get message: "abort: push
creates new remote heads!", read `this thread
<http://www.selenic.com/pipermail/mercurial/2008-April/018804.html>`_
to understand.
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
Internal documentation Internal documentation
====================== ======================
Structure If you're feeling ambitious, go fix some `pylint
========= <http://lgcm.iro.umontreal.ca/auto_theano_pylint/pylint_global.html>` errors!
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
dev_start_guide dev_start_guide
hg_primer lisa_labo
mammouth mammouth
metadocumentation metadocumentation
python
hg_primer
.. _lisa_labo::
===============================
LISA Labo specific instructions
===============================
Tips for running at LISA
------------------------
Use the fast BLAS library that Fred installed, by setting
`THEANO_BLAS_LDFLAGS=-lgoto`.
Tips for running on a cluster
-----------------------------
OUTDATED(was for mammouth1, should be updated for mammouth2)
Use something like the following in your .bashrc:
.. code-block:: bash
#use the intel math-kernel library for BLAS routines
THEANO_BLAS_LDFLAGS=-lmkl
# use up to two threads in the MKL routines
OMP_NUM_THREADS=2
# IMPORTANT!
# Use the local-temporary directory as a cache.
# If several jobs start simultaneously and use a common
# cache, then the cache may be corrupted.
# Theano is not process-safe or thread-safe in this sense.
THEANO_COMPILEDIR=/ltmp/<username>_theano
You may also need to run the following from your shell:
.. code-block:: bash
module add python # for the current shell session
module initadd python # for this and future sessions
Lastly, if ``./filename.py`` doesn't work, try ``python filename.py``.
...@@ -4,13 +4,17 @@ Running Theano on Mammouth ...@@ -4,13 +4,17 @@ Running Theano on Mammouth
To run Theano on the Mammouth cluster, follow these simple steps: To run Theano on the Mammouth cluster, follow these simple steps:
* Make sure to source Fred's .local.bashrc file. It contains all the goodies for using the latest and greatest (optimized) libraries (numpy, scipy, etc.) * Make sure to source Fred's .local.bashrc file. It contains all
>>> source /home/bastienf/.local.bashrc the goodies for using the latest and greatest (optimized) libraries
(numpy, scipy, etc.)
* set THEANO_BLAS_LDFLAGS='-lmkl -lguide -fopenmp' >>> source /home/bastienf/.local.bashrc
Perhaps even put this in your ``.bashrc``
* ``set THEANO_BLAS_LDFLAGS='-lmkl -lguide -fopenmp'``
Note: the -lguide flag works, however the fix should probably be considered temporary. Note: the -lguide flag works, however the fix should probably be considered temporary.
Intel has deprecated libguide.so in favor of the newer library libiomp5.so. However, Intel has deprecated libguide.so in favor of the newer library libiomp5.so. However,
both libraries are mutually exclusive and one component (theano, numpy or scipy?) already both libraries are mutually exclusive and one component (theano, numpy or scipy?) already
seems to be using libguide.so (hence -liomp5 causes a linking error when compiling thunks) seems to be using libguide.so (hence -liomp5 causes a linking error when compiling thunks)
...@@ -51,6 +51,16 @@ API documentation is processed by `epydoc ...@@ -51,6 +51,16 @@ API documentation is processed by `epydoc
<http://epydoc.sourceforge.net/manual-othermarkup.html#restructuredtext>`__ <http://epydoc.sourceforge.net/manual-othermarkup.html#restructuredtext>`__
for details about how to use reST with epydoc documentation. for details about how to use reST with epydoc documentation.
Use ReST for API and Sphinx documentation
-----------------------------------------
* ReST is standardized. epydoc is not. trac wiki-markup is not.
This means that ReST can be cut-and-pasted between epydoc, code, other
docs, and TRAC. This is a huge win!
* ReST is extensible: we can write our own roles and directives to automatically link to WIKI, for example.
* ReST has figure and table directives, and can be converted (using a standard tool) to latex documents.
* No text documentation has good support for math rendering, but ReST is closest: it has three renderer-specific solutions (render latex, use latex to build images for html, use itex2mml to generate MathML)
How to build documentation How to build documentation
--------------------------------------- ---------------------------------------
...@@ -80,6 +90,7 @@ When you push to the main repository, the following file is run:: ...@@ -80,6 +90,7 @@ When you push to the main repository, the following file is run::
It calls ``epydoc`` and ``sphinx`` on the code. It calls ``epydoc`` and ``sphinx`` on the code.
*It would be nice to explain this stuff in a little more depth:* *It would be nice to explain this stuff in a little more depth:*
* Who calls refresh-epydoc.sh ? * Who calls refresh-epydoc.sh ?
* What exactly does it do? * What exactly does it do?
* Where does the output go? * Where does the output go?
...@@ -135,6 +146,7 @@ TO WRITE ...@@ -135,6 +146,7 @@ TO WRITE
--------------------------------------- ---------------------------------------
*There is other stuff to document here, e.g.:* *There is other stuff to document here, e.g.:*
* where the documentation is getting built, and epy. * where the documentation is getting built, and epy.
* How epydoc and sphinx are integrated * How epydoc and sphinx are integrated
* Explain the special magic in ./doc/scripts/docgen.py * Explain the special magic in ./doc/scripts/docgen.py
......
.. _python:
================
Python booster
================
`This page
<http://wordaligned.org/articles/essential-python-reading-list>`_ will
give you a warm feeling in your stomach.
Non-Basic Python features
-------------------------
Theano doesn't use your grandfather's python.
* properties
a specific attribute that has get and set methods which python automatically invokes.
See [http://www.python.org/doc/newstyle/ New style classes].
* static methods vs. class methods vs. instance methods
* Decorators:
.. code-block:: python
@f
def g():
...
runs function ``f`` before each invocation of ``g``.
See `PEP 0318 <http://www.python.org/dev/peps/pep-0318/>`_.
``staticmethod`` is a specific decorator, since python 2.2
* ``__metaclass__`` is kinda like a decorator for classes. It runs the metaclass __init__ after the class is defined
* ``setattr`` + ``getattr`` + ``hasattr``
* ``*args`` is a tuple like argv in C++, ``**kwargs`` is a keyword args version
* ``pass`` is no-op.
* functions (function objects) can have attributes too. This technique
is often used to define a function's error messages.
.. code-block:: python
def f(): return f.a
f.a = 5
f() # returns 5
* Warning about mutual imports:
* script a.py file defined a class A.
* script a.py imported file b.py
* file b.py imported a, and instantiated a.A()
* script a.py instantiated its own A(), and passed it to a function in b.py
* that function saw its argument as being of type __main__.A, not a.A.
Incidentally, this behaviour is one of the big reasons to put autotests in
different files from the classes they test!
If all the test cases were put into <file>.py directly, then during the test
cases, all <file>.py classes instantiated by unit tests would have type
``__main__.<classname>``, instead of type ``<file>.<classname>``. This should never
happen under normal usage, and can cause problems (like the one you are/were
experiencing).
...@@ -7,17 +7,16 @@ Introduction ...@@ -7,17 +7,16 @@ Introduction
Theano is a Python library that allows you to define, optimize, and Theano is a Python library that allows you to define, optimize, and
efficiently evaluate mathematical expressions involving multi-dimensional efficiently evaluate mathematical expressions involving multi-dimensional
arrays. Theano was written at the LISA_ lab to support the development arrays. Using Theano, it is not uncommon to see speed improvements of
of efficient machine learning algorithms while minimizing human time. We ten-fold over using pure NumPy.
use it especially in gradient-based learning techniques.
Theano melds some aspects of a computer algebra system (CAS) with Theano melds some aspects of a computer algebra system (CAS) with
aspects of an optimizing compiler. It can even transform some or all aspects of an optimizing compiler. It can even transform some or
of the expression into C code and compile it into native machine all of the mathematical expression into C code and compile it into
instructions. This combination of CAS with optimizing compilation native machine instructions. This combination of CAS with optimizing
is particularly useful for computational fields in which complicated compilation is particularly useful for computational fields in which
mathematical expressions are evaluated numerous times over large data complicated mathematical expressions are evaluated repeatedly and evaluation
sets. speed is critical.
Theano supports a range of numerical types in multiple dimensions and Theano supports a range of numerical types in multiple dimensions and
a number of well-tested operations. It also allows you to compute the a number of well-tested operations. It also allows you to compute the
...@@ -36,10 +35,12 @@ not limited to: ...@@ -36,10 +35,12 @@ not limited to:
* using inplace operations wherever it is safe to do so. * using inplace operations wherever it is safe to do so.
Theano defines several optimizations which improve the numerical Theano defines several optimizations which improve the numerical
stability of computations. It also provides a framework to add and test stability of computations.
new optimizers.
Theano was named after the `Greek mathematician`_, who may have Theano was written at the LISA_ lab to support the development
of efficient machine learning algorithms while minimizing human time. We
use it especially in gradient-based learning techniques.
Theano is named after the `Greek mathematician`_, who may have
been Pythagoras' wife. been Pythagoras' wife.
Theano is released under a BSD license (:ref:`link <license>`) Theano is released under a BSD license (:ref:`link <license>`)
......
.. _links: .. _links:
=====
Links Links
===== =====
...@@ -9,7 +9,7 @@ This page lists links to various resources. ...@@ -9,7 +9,7 @@ This page lists links to various resources.
Theano requirements Theano requirements
=================== -------------------
- mercurial_: A distributed revision control system (RCS). - mercurial_: A distributed revision control system (RCS).
- nosetests_: A system for unit tests. - nosetests_: A system for unit tests.
...@@ -19,7 +19,7 @@ Theano requirements ...@@ -19,7 +19,7 @@ Theano requirements
Libraries we might want to look at or use Libraries we might want to look at or use
========================================= -----------------------------------------
This is a sort of memo for developers and would-be developers. This is a sort of memo for developers and would-be developers.
......
...@@ -2,14 +2,22 @@ ...@@ -2,14 +2,22 @@
.. _numpy: .. _numpy:
=============== ***************
NumPy refresher NumPy refresher
=============== ***************
Here are some quick guides to NumPy:
* `Numpy quick guide for Matlab users <http://www.scipy.org/NumPy_for_Matlab_Users>`__
* `More detailed table showing the NumPy equivalent of Matlab commands <http://www.scribd.com/doc/26685/Matlab-Python-and-R>`__
.. TODO [DefineBroadcasting Broadcasting]
.. Broadcastable - Implicitly assume that all previous entries are true.
.. [TODO: More doc, e.g. see _test_tensor.py]
---------------------------------------
Matrix conventions for machine learning Matrix conventions for machine learning
--------------------------------------- =======================================
Rows are horizontal and columns are vertical. Rows are horizontal and columns are vertical.
Every row is an example. Therefore, inputs[10,5] is a matrix of 10 examples with 5 dimensions per. Every row is an example. Therefore, inputs[10,5] is a matrix of 10 examples with 5 dimensions per.
......
The following may go either in:
a) numpy refresher.
b) more details of broadcasting in the types section.
=== broadcastable ===
The {{{broadcastable}}} field of a {{{Tensor}}} must be a tuple of boolean values. Each value corresponds to a dimension of the {{{Tensor}}} and specifies whether the {{{Tensor}}} can be "broadcasted" along that dimension.
A value of {{{True}}} means two things:
* The size of the corresponding dimension will necessarily be 1.
* If needed, the {{{Tensor}}} can be ''broadcasted'' or ''replicated'' along the corresponding dimension to emulate a larger {{{Tensor}}}.
A value of {{{False}}} means that the corresponding dimension can take any nonnegative value and that the {{{Tensor}}} cannot be replicated along it (regardless of whether it is 1 or not).
Example: to define a ''row'' type, set broadcastable to {{{(True, False)}}}: this means the shape must be like {{{(1, n)}}}. If you add a row of shape {{{(1, n)}}} to a matrix of shape {{{(m, n)}}}, the row will be "broadcasted" or "replicated" {{{m}}} times along the first dimension, producing a virtual matrix of the correct size {{{(m, n)}}}. Therefore, adding a row to a matrix will add the row to each row of the matrix. If the value of {{{broadcastable}}} for the first dimension of the row was {{{False}}}, the operation would instead raise an exception complaining that the dimensions are not the same.
Similarly, the broadcastable pattern for a column is {{{(False, True)}}}: this means the shape must be like {{{(m, 1)}}}, therefore adding a column to a matrix will add that column to each column of the matrix. Several Ops, such as {{{DimShuffle}}}, can add or remove broadcastable dimensions.
The length of {{{broadcastable}}} is the number of dimensions of the {{{Tensor}}}.
Want to know about Theano's `function design
<http://groups.google.com/group/theano-dev/browse_thread/thread/fd4c6947d8a20510>`?
'''Historical Interest. This has been addressed for now. 20080904'''
There are several [http://en.wikipedia.org/wiki/Comparison_of_free_software_hosting_facilities project hosting services] online, but none is perfect for theano.
Wishlist:
- version control (mercurial)
- bugtracker (TRAC, ideally)
- wiki
- release file hosting
- mailing list
- reliability of hosting service
Currently, [http://sharesource.org/ sharesource] and [http://www.assembla.com/ assembla] are the only hosting services that support mercurial that I know of. Sharesource is young, but supports all the required features. I'll make an account, and see what I can do with it...
Should we get a domain name? To my dismay, theano.org, theano.com and theano.net are all taken. The first two seem legit, but theano.net doesn't look like it has anything on it and expires on May 29, so maybe there's a chance we can snag it? -ob
We could also get [http://www.theano.io]. -jpt
--------
On Fri, May 09, 2008 at 03:49:31PM -0400, Joseph Turian wrote:
> Another option for backup:
>
> Since we have access to LGCM, there is a single SQLite db file (AFAIK)
> that we can back up periodically.
> e.g. cron job to gzip and email it to us once a week.
There are instructions for how to backup a Trac site, i just haven't gotten
around to it. Currently, the whole directory is rsynced to the lisa account,
which is close to ok, but not quite.
> Besides mailing list, is there anything else we need? Besides figuring
> out how to administer trac? :}
Writing scripts to update p-omega1/.ssh/authorized_keys2 automatically from
certain user accounts' authorized_keys2 file. I've written this script, but not
really tested it.
Hooking up mercurial to trac would be nice, so we can associate commits and
tickets.
lgcm's uptime is usually about a week or two at max, so there's the pain in the
ass of having to re-log in, start up a screen session, find the directories,
restart trac, restart hg serve. We should be restarting hg serve for tlearn too
soon.
Even if I do set up the authorized_keys2 script to do the right thing, the users
on TRAC and the users on the system are totally independent, so adding a new
user is non-standard and only I can do it right now.
My choices seem to be:
- document all these hoops and good ideas
- fix them so they are easier to use and document
- replace them with hosting service
All of these options take time, mental effort, and the support of our
development group (look the large number of messages today on the topic)... so
i'm trying to find the least of all evils. The Right Thing doesn't seem to have
appeared yet.
Theano uses several tricks to obtain good performance:
* common sub-expression elimination
* [custom generated] C code for many operations
* pre-allocation of temporary storage
* loop fusion (which gcc normally can't do)
On my neural net experiments for my course projects, I was getting around 10x
speed improvements over basic numpy by using theano.
[More specific speed tests would be nice.]
With a little work, Theano could also implement more sophisticated
optimizations:
* automatic ordering of matrix multiplications
* profile-based memory layout decisions (e.g. row-major vs. col-major)
* gcc intrinsics to use MMX, SSE2 parallelism for faster element-wise arithmetic
* conditional expressions
Other software to look at and maybe recommend to users:
* [http://www.pytables.org/moin PyTables] - This is looking really
promising for dataset storage and experiment logging... This might
actually be useful for large data sets.
* [http://matplotlib.sourceforge.net/ MatPlotLib] - visualization tools
(plot curves interactively, like matlab's figure window)
* [http://www.pythonware.com/products/pil/ PIL] - Python Image Library:
write your matrices out in png! (Kinda a weird recommendation, I think)
* [http://www.logilab.org/857 pylint] - Syntax checker for python to
help beautify your code. (We'd be hypocrites to recommend this :)
* [http://www.winpdb.org/ Winpdb] - A Platform Independent Python
Debugger. (Except it doesn't really help you debug Theano graphs)
* [http://wiki.python.org/moin/IntegratedDevelopmentEnvironments Python Integrated Development Environments] - for all your coding needs
...@@ -87,8 +87,17 @@ Several things should be learned from the above example: ...@@ -87,8 +87,17 @@ Several things should be learned from the above example:
TODO: Rewrite this documentation to do things in a smarter way. TODO: Rewrite this documentation to do things in a smarter way.
Speed
-----
For faster sparse code:
* Construction: lil_format is fast for many inserts.
* Operators: "Since conversions to and from the COO format are
quite fast, you can use this approach to efficiently implement lots
computations on sparse matrices." (Nathan Bell on scipy mailing list)
Misc Misc
---------------------------------------- ----
The sparse equivalent of dmatrix is csc_matrix and csr_matrix. The sparse equivalent of dmatrix is csc_matrix and csr_matrix.
:api:`TrueDot` vs. :api:`StructuredDot` :api:`TrueDot` vs. :api:`StructuredDot`
......
...@@ -13,7 +13,7 @@ from setuptools import setup, find_packages ...@@ -13,7 +13,7 @@ from setuptools import setup, find_packages
setup(name="Theano", setup(name="Theano",
version="0.1", version="0.1",
description="Optimizing compiler for mathematical expressions", description="Optimizing compiler for mathematical expressions",
long_description="""Theano is a Python library that allows you to define, optimize, and efficiently evaluate mathematical expressions involving multi-dimensional arrays. Theano was written at the LISA lab to support the development of efficient machine learning algorithms while minimizing human time. We use it especially in gradient-based learning techniques.""", long_description="""Theano is a Python library that allows you to define, optimize, and efficiently evaluate mathematical expressions involving multi-dimensional arrays. Using Theano, it is not uncommon to see speed improvements of ten-fold over using pure NumPy."""
author="LISA laboratory, University of Montreal", author="LISA laboratory, University of Montreal",
author_email="theano-dev@googlegroups.com", author_email="theano-dev@googlegroups.com",
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
......
"""Provides `DebugMode`, an evaluation mode for debugging theano internals.""" """Provides `DebugMode`, an evaluation mode for debugging theano internals."""
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
import time, copy, sys import time, copy, sys, copy_reg
from StringIO import StringIO from StringIO import StringIO
import numpy import numpy
...@@ -1123,6 +1123,9 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions ...@@ -1123,6 +1123,9 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions
fn = self.function_builder(_fn, _i, _o, self.indices, self.outputs, defaults, self.unpack_single, self) fn = self.function_builder(_fn, _i, _o, self.indices, self.outputs, defaults, self.unpack_single, self)
return fn return fn
def _pickle_DebugMode_Maker(maker):
raise NotImplementedError('DebugMode is not picklable (yet)')
copy_reg.pickle(_Maker, _pickle_DebugMode_Maker)
######################## ########################
# #
......
import numpy import sys
import numpy, scipy
import scipy.sparse import scipy.sparse
from theano import gof from theano import gof
...@@ -34,9 +35,8 @@ class BROKEN_ON_PURPOSE_StructuredDotCSC(gof.Op): ...@@ -34,9 +35,8 @@ class BROKEN_ON_PURPOSE_StructuredDotCSC(gof.Op):
(a_nrows, b.shape[0]), (a_nrows, b.shape[0]),
copy = False) copy = False)
# TODO: todense() is automatic in 0.7.0, just remove the following line: # TODO: todense() is automatic in 0.7.0, just remove the following line:
# out[0] = numpy.asarray(a.dot(b).todense()) z = a * b
out[0] = a.dot(b)+0.5 if self.py_offset else a.dot(b) #ERROR TO ADD THIS CRAPPY OFFSET out[0] = z+0.5 if self.py_offset else z #ERROR TO ADD THIS CRAPPY OFFSET
#assert _is_dense(out[0])
def c_code(self, node, name, (a_val, a_ind, a_ptr, a_nrows, b), (z,), sub): def c_code(self, node, name, (a_val, a_ind, a_ptr, a_nrows, b), (z,), sub):
return """ return """
......
...@@ -381,24 +381,102 @@ class T_picklefunction(unittest.TestCase): ...@@ -381,24 +381,102 @@ class T_picklefunction(unittest.TestCase):
x,s = T.scalars('xs') x,s = T.scalars('xs')
f = function([x, In(a, value=1.0,name='a'), In(s, value=0.0, update=s+a*x, mutable=True)], s+a*x) f = function([x, In(a, value=1.0,name='a'), In(s, value=0.0, update=s+a*x, mutable=True)], s+a*x)
print f.maker.function_builder
try:
g = copy.deepcopy(f) g = copy.deepcopy(f)
except NotImplementedError, e:
if e[0].startswith('DebugMode is not picklable'):
return
else:
raise
#if they both return, assume that they return equivalent things. #if they both return, assume that they return equivalent things.
#print [(k,id(k)) for k in f.finder.keys()]
#print [(k,id(k)) for k in g.finder.keys()]
self.failIf(g.container[x].storage is f.container[x].storage) self.failIf(g.container[0].storage is f.container[0].storage)
self.failIf(g.container[a].storage is f.container[a].storage) self.failIf(g.container[1].storage is f.container[1].storage)
self.failIf(g.container[s].storage is f.container[s].storage) self.failIf(g.container[2].storage is f.container[2].storage)
self.failIf(x in g.container)
self.failIf(x in g.value)
self.failIf(g.value[a] is f.value[a]) # should not have been copied self.failIf(g.value[1] is f.value[1]) # should not have been copied
self.failIf(g.value[s] is f.value[s]) # should have been copied because it is mutable. self.failIf(g.value[2] is f.value[2]) # should have been copied because it is mutable.
self.failIf((g.value[s] != f.value[s]).any()) # its contents should be identical self.failIf((g.value[2] != f.value[2]).any()) # its contents should be identical
self.failUnless(f(2, 1) == g(2)) #they should be in sync, default value should be copied. self.failUnless(f(2, 1) == g(2)) #they should be in sync, default value should be copied.
self.failUnless(f(2, 1) == g(2)) #they should be in sync, default value should be copied. self.failUnless(f(2, 1) == g(2)) #they should be in sync, default value should be copied.
f(1,2) # put them out of sync f(1,2) # put them out of sync
self.failIf(f(1, 2) == g(1, 2)) #they should not be equal anymore. self.failIf(f(1, 2) == g(1, 2)) #they should not be equal anymore.
def test_pickle(self):
a = T.scalar() # the a is for 'anonymous' (un-named).
x,s = T.scalars('xs')
f = function([x, In(a, value=1.0,name='a'), In(s, value=0.0, update=s+a*x, mutable=True)], s+a*x)
try:
g = cPickle.loads(cPickle.dumps(f))
except NotImplementedError, e:
if e[0].startswith('DebugMode is not picklable'):
return
else:
raise
#if they both return, assume that they return equivalent things.
#print [(k,id(k)) for k in f.finder.keys()]
#print [(k,id(k)) for k in g.finder.keys()]
self.failIf(g.container[0].storage is f.container[0].storage)
self.failIf(g.container[1].storage is f.container[1].storage)
self.failIf(g.container[2].storage is f.container[2].storage)
self.failIf(x in g.container)
self.failIf(x in g.value)
self.failIf(g.value[1] is f.value[1]) # should not have been copied
self.failIf(g.value[2] is f.value[2]) # should have been copied because it is mutable.
self.failIf((g.value[2] != f.value[2]).any()) # its contents should be identical
self.failUnless(f(2, 1) == g(2)) #they should be in sync, default value should be copied.
self.failUnless(f(2, 1) == g(2)) #they should be in sync, default value should be copied.
f(1,2) # put them out of sync
self.failIf(f(1, 2) == g(1, 2)) #they should not be equal anymore.
def test_optimizations_preserved(self):
a = T.dvector() # the a is for 'anonymous' (un-named).
x = T.dvector('x')
s = T.dvector('s')
xm = T.dmatrix('x')
sm = T.dmatrix('s')
f = function([a, x, s, xm, sm], ((a.T.T)*(tensor.dot(xm, (sm.T.T.T)) + x).T * (x/x) + s))
old_default_mode = compile.mode.default_mode
try:
str_f = cPickle.dumps(f)
compile.mode.default_mode = mode_module.Mode(linker='py', optimizer=None)
g = cPickle.loads(str_f)
#print g.maker.mode
#print compile.mode.default_mode
except NotImplementedError, e:
if e[0].startswith('DebugMode is not pickl'):
g = 'ok'
finally:
compile.mode.default_mode = old_default_mode
if g == 'ok':
return
assert f.maker is not g.maker
assert f.maker.env is not g.maker.env
tf = f.maker.env.toposort()
tg = f.maker.env.toposort()
assert len(tf) == len(tg)
for nf, ng in zip(tf, tg):
assert nf.op == ng.op
assert len(nf.inputs) == len(ng.inputs)
assert len(nf.outputs) == len(ng.outputs)
assert [i.type for i in nf.inputs] == [i.type for i in ng.inputs]
assert [i.type for i in nf.outputs] == [i.type for i in ng.outputs]
# class T_function_examples(unittest.TestCase): # class T_function_examples(unittest.TestCase):
# def test_accumulator(self): # def test_accumulator(self):
# """Test low-level interface with state.""" # """Test low-level interface with state."""
......
...@@ -900,9 +900,8 @@ class EquilibriumOptimizer(NavigatorOptimizer): ...@@ -900,9 +900,8 @@ class EquilibriumOptimizer(NavigatorOptimizer):
lopt_change = self.process_node(env, node, lopt) lopt_change = self.process_node(env, node, lopt)
process_count[lopt] += 1 if lopt_change else 0 process_count[lopt] += 1 if lopt_change else 0
changed |= lopt_change changed |= lopt_change
except: finally:
self.detach_updater(env, u) self.detach_updater(env, u)
raise
self.detach_updater(env, u) self.detach_updater(env, u)
if max_use_abort: if max_use_abort:
print >> sys.stderr, "WARNING: EquilibriumOptimizer max'ed out" print >> sys.stderr, "WARNING: EquilibriumOptimizer max'ed out"
......
...@@ -120,7 +120,7 @@ class EquilibriumDB(DB): ...@@ -120,7 +120,7 @@ class EquilibriumDB(DB):
return opt.EquilibriumOptimizer(opts, return opt.EquilibriumOptimizer(opts,
max_depth=5, max_depth=5,
max_use_ratio=10, max_use_ratio=10,
failure_callback=opt.NavigatorOptimizer.warn) failure_callback=opt.NavigatorOptimizer.warn_inplace)
class SequenceDB(DB): class SequenceDB(DB):
......
...@@ -378,6 +378,8 @@ CSR = CSM('csr') ...@@ -378,6 +378,8 @@ CSR = CSM('csr')
class CSMGrad(gof.op.Op): class CSMGrad(gof.op.Op):
def __init__(self, kmap=None): def __init__(self, kmap=None):
self.kmap = kmap self.kmap = kmap
if self.kmap is None:
self.view_map = {0 : [1]}
def __eq__(self, other): def __eq__(self, other):
return type(self) == type(other) and _kmap_eq(self.kmap, other.kmap) return type(self) == type(other) and _kmap_eq(self.kmap, other.kmap)
...@@ -676,7 +678,8 @@ class StructuredDot(gof.Op): ...@@ -676,7 +678,8 @@ class StructuredDot(gof.Op):
if a.shape[1] != b.shape[0]: if a.shape[1] != b.shape[0]:
raise ValueError('shape mismatch in StructuredDot.perform', (a.shape, b.shape)) raise ValueError('shape mismatch in StructuredDot.perform', (a.shape, b.shape))
variable = a.dot(b) #variable = a.dot(b) # deprecated
variable = a * b
assert _is_dense(variable) # scipy 0.7 automatically converts to dense assert _is_dense(variable) # scipy 0.7 automatically converts to dense
# dot of an NxM sparse matrix, with a Mx1 dense matrix, returns vector not matrix # dot of an NxM sparse matrix, with a Mx1 dense matrix, returns vector not matrix
...@@ -738,7 +741,8 @@ class StructuredDotCSC(gof.Op): ...@@ -738,7 +741,8 @@ class StructuredDotCSC(gof.Op):
a = sparse.csc_matrix((a_val, a_ind, a_ptr), a = sparse.csc_matrix((a_val, a_ind, a_ptr),
(a_nrows, b.shape[0]), (a_nrows, b.shape[0]),
copy = False) copy = False)
out[0] = a.dot(b) #out[0] = a.dot(b)
out[0] = a * b
assert _is_dense(out[0]) # scipy 0.7 automatically converts to dense assert _is_dense(out[0]) # scipy 0.7 automatically converts to dense
def c_code(self, node, name, (a_val, a_ind, a_ptr, a_nrows, b), (z,), sub): def c_code(self, node, name, (a_val, a_ind, a_ptr, a_nrows, b), (z,), sub):
...@@ -881,7 +885,8 @@ class StructuredDotCSR(gof.Op): ...@@ -881,7 +885,8 @@ class StructuredDotCSR(gof.Op):
a = sparse.csr_matrix((a_val, a_ind, a_ptr), a = sparse.csr_matrix((a_val, a_ind, a_ptr),
(len(a_ptr)-1, b.shape[0]), (len(a_ptr)-1, b.shape[0]),
copy = True) #use view_map before setting this to False copy = True) #use view_map before setting this to False
out[0] = a.dot(b) #out[0] = a.dot(b)
out[0] = a * b
assert _is_dense(out[0]) # scipy 0.7 automatically converts to dense, but not .6 sometimes assert _is_dense(out[0]) # scipy 0.7 automatically converts to dense, but not .6 sometimes
def c_code(self, node, name, (a_val, a_ind, a_ptr, b), (z,), sub): def c_code(self, node, name, (a_val, a_ind, a_ptr, b), (z,), sub):
......
...@@ -185,11 +185,11 @@ class test_structureddot(unittest.TestCase): ...@@ -185,11 +185,11 @@ class test_structureddot(unittest.TestCase):
imvals = 1.0 * numpy.arange(bsize*spmat.shape[1]).reshape(bsize,spmat.shape[1]) imvals = 1.0 * numpy.arange(bsize*spmat.shape[1]).reshape(bsize,spmat.shape[1])
outvals = f(kernvals,imvals) outvals = f(kernvals,imvals)
# compare to scipy # compare to scipy
c = spmat.dot(imvals.T) c = spmat * (imvals.T)
assert _is_dense(c) assert _is_dense(c)
assert numpy.all(outvals == c) assert numpy.all(outvals == c)
tensor.verify_grad(None, buildgraphCSC, [kernvals,imvals]) tensor.verify_grad(buildgraphCSC, [kernvals,imvals])
## ##
# Test compressed-sparse row matrices ### # Test compressed-sparse row matrices ###
...@@ -207,11 +207,11 @@ class test_structureddot(unittest.TestCase): ...@@ -207,11 +207,11 @@ class test_structureddot(unittest.TestCase):
imvals = 1.0 * numpy.arange(bsize*spmat.shape[1]).reshape(bsize,spmat.shape[1]) imvals = 1.0 * numpy.arange(bsize*spmat.shape[1]).reshape(bsize,spmat.shape[1])
outvals = f(kernvals,imvals) outvals = f(kernvals,imvals)
# compare to scipy # compare to scipy
c = spmat.dot(imvals.T) c = spmat * (imvals.T)
assert _is_dense(c) assert _is_dense(c)
assert numpy.all(outvals == c) assert numpy.all(outvals == c)
tensor.verify_grad(None, buildgraphCSR, [kernvals,imvals]) tensor.verify_grad( buildgraphCSR, [kernvals,imvals])
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -858,7 +858,7 @@ class MaxAndArgmax(Op): ...@@ -858,7 +858,7 @@ class MaxAndArgmax(Op):
axis = x.type.ndim - 1 axis = x.type.ndim - 1
axis = _as_tensor_variable(axis) axis = _as_tensor_variable(axis)
inputs = [x, axis] inputs = [x, axis]
broadcastable = [False] * (x.type.ndim - 1) broadcastable = [False] * (x.type.ndim - 1) #TODO: be less conservative
outputs = [tensor(x.type.dtype, broadcastable), outputs = [tensor(x.type.dtype, broadcastable),
tensor(axis.type.dtype, broadcastable)] tensor(axis.type.dtype, broadcastable)]
return Apply(self, inputs, outputs) return Apply(self, inputs, outputs)
......
...@@ -706,32 +706,17 @@ class Canonizer(gof.LocalOptimizer): ...@@ -706,32 +706,17 @@ class Canonizer(gof.LocalOptimizer):
return False return False
new = self.merge_num_denum(num, denum) new = self.merge_num_denum(num, denum)
if new.dtype != out.dtype: if new.type.dtype != out.type.dtype:
#new = T.fill(out, new) #new = T.fill(out, new)
elem_op = T.Elemwise(scalar.Identity(scalar.specific_out(getattr(scalar, out.type.dtype)))) elem_op = T.Elemwise(scalar.Identity(scalar.specific_out(getattr(scalar, out.type.dtype))))
new = T.fill(out, elem_op(new)) new = elem_op(new)
if new.broadcastable != out.broadcastable: if new.type.broadcastable != out.type.broadcastable:
#this case is tricky... we need to provide exactly the same kind of broadcastable new = T.fill(out, new)
#pattern, but only if legal...
dlen = len(new.broadcastable) - len(out.broadcastable)
if dlen > 0:
#try to take the leading ranks of new.broadcastable, which should be broadcastable
# ranks
#if this means skipping over nonbroadcastable ranks, then DimShuffle will fail
dimshuffle_op = T.DimShuffle(new.broadcastable,
range(dlen, len(new.broadcastable)))
new = dimshuffle_op(new)
elif dlen < 0:
#we have to boost up a scalar or something
dimshuffle_op = T.DimShuffle(new.broadcastable,
['x' for x in range(-dlen)] + range(0, len(new.broadcastable)))
new = dimshuffle_op(new)
# if our if's above worked, this should be true. OTW investigate. # if our if's above worked, this should be true. OTW investigate.
if new.type != out.type: if new.type != out.type:
print >> sys.stderr, 'CANONIZE FAILED: new out = ', new, out print >> sys.stderr, 'CANONIZE FAILED: new, out = ', new, ',', out, 'types', new.type, ',', out.type
assert new.type == out.type assert new.type == out.type
return [new] return [new]
......
import traceback import traceback, StringIO
import operator import operator
from theano.tensor import * from theano.tensor import *
...@@ -628,18 +628,26 @@ class T_max_and_argmax(unittest.TestCase): ...@@ -628,18 +628,26 @@ class T_max_and_argmax(unittest.TestCase):
self.failUnless(numpy.all(i == numpy.argmax(data,0))) self.failUnless(numpy.all(i == numpy.argmax(data,0)))
def test2_invalid(self): def test2_invalid(self):
n = as_tensor_variable(numpy.random.rand(2,3)) n = as_tensor_variable(numpy.random.rand(2,3))
old_stderr = sys.stderr
sys.stderr = StringIO.StringIO()
try: try:
eval_outputs(max_and_argmax(n,3)) eval_outputs(max_and_argmax(n,3))
assert False
except ValueError, e: except ValueError, e:
return pass
self.fail() finally:
sys.stderr = old_stderr
def test2_invalid_neg(self): def test2_invalid_neg(self):
n = as_tensor_variable(numpy.random.rand(2,3)) n = as_tensor_variable(numpy.random.rand(2,3))
old_stderr = sys.stderr
sys.stderr = StringIO.StringIO()
try: try:
eval_outputs(max_and_argmax(n,-3)) eval_outputs(max_and_argmax(n,-3))
assert False
except ValueError, e: except ValueError, e:
return pass
self.fail() finally:
sys.stderr = old_stderr
def test2_valid_neg(self): def test2_valid_neg(self):
n = as_tensor_variable(numpy.random.rand(2,3)) n = as_tensor_variable(numpy.random.rand(2,3))
v,i = eval_outputs(max_and_argmax(n,-1)) v,i = eval_outputs(max_and_argmax(n,-1))
...@@ -678,13 +686,16 @@ class T_subtensor(unittest.TestCase): ...@@ -678,13 +686,16 @@ class T_subtensor(unittest.TestCase):
n = as_tensor_variable(numpy.ones(3)) n = as_tensor_variable(numpy.ones(3))
t = n[7] t = n[7]
self.failUnless(isinstance(t.owner.op, Subtensor)) self.failUnless(isinstance(t.owner.op, Subtensor))
old_stderr = sys.stderr
sys.stderr = StringIO.StringIO()
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
assert 0
except Exception, e: except Exception, e:
if e[0] != 'index out of bounds': if e[0] != 'index out of bounds':
raise raise
return finally:
self.fail() sys.stderr = old_stderr
def test1_err_subslice(self): def test1_err_subslice(self):
n = as_tensor_variable(numpy.ones(3)) n = as_tensor_variable(numpy.ones(3))
try: try:
...@@ -748,20 +759,28 @@ class T_subtensor(unittest.TestCase): ...@@ -748,20 +759,28 @@ class T_subtensor(unittest.TestCase):
n = as_tensor_variable(numpy.ones((2,3))*5) n = as_tensor_variable(numpy.ones((2,3))*5)
t = n[0,4] t = n[0,4]
self.failUnless(isinstance(t.owner.op, Subtensor)) self.failUnless(isinstance(t.owner.op, Subtensor))
old_stderr = sys.stderr
sys.stderr = StringIO.StringIO()
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
assert 0
except IndexError, e: except IndexError, e:
return pass
self.fail() finally:
sys.stderr = old_stderr
def test2_err_bounds1(self): def test2_err_bounds1(self):
n = as_tensor_variable(numpy.ones((2,3))*5) n = as_tensor_variable(numpy.ones((2,3))*5)
t = n[4:5,2] t = n[4:5,2]
self.failUnless(isinstance(t.owner.op, Subtensor)) self.failUnless(isinstance(t.owner.op, Subtensor))
old_stderr = sys.stderr
sys.stderr = StringIO.StringIO()
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
except Exception, e: except Exception, e:
if e[0] != 'index out of bounds': if e[0] != 'index out of bounds':
raise raise
finally:
sys.stderr = old_stderr
def test2_ok_elem(self): def test2_ok_elem(self):
n = as_tensor_variable(numpy.asarray(range(6)).reshape((2,3))) n = as_tensor_variable(numpy.asarray(range(6)).reshape((2,3)))
t = n[0,2] t = n[0,2]
...@@ -1364,12 +1383,19 @@ class t_dot(unittest.TestCase): ...@@ -1364,12 +1383,19 @@ class t_dot(unittest.TestCase):
def not_aligned(self, x, y): def not_aligned(self, x, y):
z = dot(x,y) z = dot(x,y)
# constant folding will complain to stderr that things are not aligned
# this is normal, testers are not interested in seeing that output.
old_stderr = sys.stderr
sys.stderr = StringIO.StringIO()
try: try:
tz = eval_outputs([z]) tz = eval_outputs([z])
assert False # should have raised exception
except ValueError, e: except ValueError, e:
self.failUnless( self.failUnless(
e[0].split()[1:4] == ['are', 'not', 'aligned'] or # reported by numpy e[0].split()[1:4] == ['are', 'not', 'aligned'] or # reported by numpy
e[0].split()[2:5] == ['do', 'not', 'agree'], e) # reported by blas return self.fail() e[0].split()[2:5] == ['do', 'not', 'agree'], e) # reported by blas return self.fail()
finally:
sys.stderr = old_stderr
def test_align_1_1(self): self.not_aligned(self.rand(5), self.rand(6)) def test_align_1_1(self): self.not_aligned(self.rand(5), self.rand(6))
def test_align_1_2(self): self.not_aligned(self.rand(5), self.rand(6,4)) def test_align_1_2(self): self.not_aligned(self.rand(5), self.rand(6,4))
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论