提交 c27f9f4d authored 作者: James Bergstra's avatar James Bergstra

new doc indexes

上级 35f29474
......@@ -102,7 +102,8 @@ html_theme = 'sphinxdoc'
# The name of an image file (within the static path) to place at the top of
# the sidebar.
html_logo = 'images/theano_logo-200x67.png'
#html_logo = 'images/theano_logo-200x67.png'
html_logo = 'images/theano_logo_allblue_200x54.png'
# 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
......
......@@ -11,15 +11,14 @@ Contents
introduction
LICENSE
install
basic_tutorial/index
advanced_tutorial/index
topics/index
tutorial/index
library/index
extending/index
indexes/index
glossary
links
internal/index
NEWS
examples/index
sandbox/index
.. examples/index
.. advanced/index
.. _advtutorial:
.. _extending:
=================
Advanced Tutorial
=================
================
Extending Theano
================
Before tackling this tutorial, it is highly recommended to read the
:ref:`basictutorial`.
This documentation is for users who want to extend Theano with new Types, new
Operations (Ops), and new graph optimizations.
The advanced tutorial is meant to give the reader a greater
understanding of the building blocks of Theano. Through this tutorial
we are going to define one :ref:`type`, ``double``, and basic
arithmetic :ref:`operations <op>` on that Type. We will first define
them using a Python implementation and then we will add a C
implementation.
Along the way, it also introduces many aspects of how Theano works, so it is
also good for you if you are interested in getting more under the hood with
Theano itself.
This tutorial should be of most use to users who want to extend Theano
with custom types and operations related to these types.
It is a good idea to read this tutorial as well since it provides
grounding for fundamental Theano concepts.
Before tackling this tutorial, it is highly recommended to read the
:ref:`basictutorial`.
The first few pages will walk you through the definition of a new :ref:`type`,
``double``, and a basic arithmetic :ref:`operations <op>` on that Type. We
will start by defining them using a Python implementation and then we will add
a C implementation.
.. toctree::
pipeline
theano_vs_c
graphstructures
type
......@@ -33,8 +33,6 @@ grounding for fundamental Theano concepts.
cop
optimization
tips
unittest
......@@ -68,9 +68,9 @@ Failure
Besides cleanup code, all code has access to the %(fail)s template. For three code blocks, the generated C code will pretty much look like this:
{{{
int failure = 0;
{
.. code-block::
int failure = 0;
{
<code1>
{
<code2>
......@@ -82,21 +82,20 @@ int failure = 0;
label2:
<cleanup2>
}
label1:
label1:
<cleanup1>
}
return failure;
}}}
}
return failure;
And %(fail)s in the nth code block will take the value "{failure = n; goto label<n>;}". This means only the blocks executed up to the failure point are cleaned up and the return value indicates which block failed, which is handy for debugging.
When compiling an Op, we want to sync the outputs so we can get the results from Python. In case of failure, we will not necessarily want to sync. Because of that, typical code will look like this:
{{{
int failure = 0;
<declare input>
<declare output>
{
.. code-block::
int failure = 0;
<declare input>
<declare output>
{
<extract input>
{
<extract output>
......@@ -110,11 +109,10 @@ int failure = 0;
<sync output>
<clean up output>
}
label1:
label1:
<clean up input>
}
return failure;
}}}
}
return failure;
Furthermore, is not necessary to extract the output because we mean to overwrite it anyway. In that case, <extract output> will be a no-op, but of course we may still need to clean up or sync what <perform> will put in the declared outputs.
......@@ -124,8 +122,8 @@ Example ResultBase
The following ResultBase represents a double (we only care about the C part).
{{{
class Double(ResultBase):
.. code-block::
class Double(ResultBase):
<snip>
def c_declare(self):
return "double %(name)s;"
......@@ -137,7 +135,6 @@ class Double(ResultBase):
return "" # nothing to do
def c_sync(self):
return "Py_XDECREF(py_%(name)s); py_%(name)s = PyFloat_FromDouble(%(name)s);"
}}}
Example Op
......@@ -145,8 +142,8 @@ Example Op
The following ResultBase represents addition of two nonnegative doubles (we only care about the C part).
{{{
class Add(Op):
.. code-block::
class Add(Op):
<snip>
def c_var_names(self):
return "[['x', 'y'], ['z']]"
......@@ -158,15 +155,14 @@ class Add(Op):
return "%(z)s = %(x)s + %(y)s;"
def c_code_cleanup(self):
return "" # nothing to do
}}}
Generating a C function
=======================
For the example Op, the generated C function will typically look like this:
{{{
void add(PyObject* storage_x, PyObject* storage_y, PyObject* storage_z) {
.. code-block::
void add(PyObject* storage_x, PyObject* storage_y, PyObject* storage_z) {
PyObject* py_x = PyList_GET_ITEM(storage_x, 0); Py_XINCREF(py_x); // automatic
PyObject* py_y = PyList_GET_ITEM(storage_y, 0); Py_XINCREF(py_y); // automatic
PyObject* py_z = Py_None; // we don't care what's currently in storage_z
......@@ -208,8 +204,7 @@ void add(PyObject* storage_x, PyObject* storage_y, PyObject* storage_z) {
Py_XDECREF(py_x); // always done after _.c_cleanup
}
return failure;
}
}}}
}
Generating a C struct
=====================
......@@ -218,8 +213,8 @@ To accelerate processing a tad, a struct can be generated instead of a function.
Here is a sketch of the struct equivalent of the previous function:
{{{
struct add {
.. code-block::
struct add {
PyObject* storage_x;
PyObject* storage_y;
PyObject* storage_z;
......@@ -240,8 +235,7 @@ struct add {
add() { this->init(); }
~add() { this->cleanup(); }
};
}}}
};
Advantages of using a struct:
* Can be run several times even if we provide the storage only once.
......
......@@ -33,11 +33,11 @@ Question: does it make sense to apply the order to the loop, or is this broadcas
Here is the loop for {{{order == c}}}. Check for errors!
{{{
<initialize iterators>
.. code-block::
<initialize iterators>
i1 = -1
while (++i1 < dim1) {
i1 = -1
while (++i1 < dim1) {
i2 = -1
rank_N-1_accumulator = init
while (++i2 < dim2) {
......@@ -52,8 +52,7 @@ while (++i1 < dim1) {
}
<SET rank 1 output using accumulated inputs>
<NEXT rank 1 iterator>
}
}}}
}
When {{{order == f}}}, the iterators ''ideally'' (but not necessarily) iterate in FORTRAN order, i.e. the while loops are on {{{dimN..dim1}}} instead of {{{dim1..dimN}}}.
......
.. _basictutorial:
==============
Basic Tutorial
==============
Before doing anything in this tutorial, make sure that Theano is
installed on your system (see :ref:`install`).
Done? Alright!
========
Tutorial
========
Let's start an interactive session and import the package you just
installed:
......@@ -23,11 +16,18 @@ of theano. Let's import that subpackage under a handy name. I like
>>> import theano.tensor as T
Now we're ready for the tour:
If that didn't work, Theano is not installed correctly (see :ref:`install`).
Now we're ready for the tour:
.. toctree::
adding
debug_faq
debugmode
examples
numpy
profilemode
randomstreams
tools
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论