提交 bfd8a94a authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Remove obsolete :api: role, and replace refs.

Also removes now unused scripts.
上级 1bde7f38
...@@ -23,7 +23,7 @@ import sys, os ...@@ -23,7 +23,7 @@ import sys, os
# Add any Sphinx extension module names here, as strings. They can be extensions # Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'ext'] extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo']
todo_include_todos = True todo_include_todos = True
...@@ -175,7 +175,7 @@ latex_documents = [ ...@@ -175,7 +175,7 @@ latex_documents = [
# 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 = 'images/snake_theta2-trans.png' #latex_logo = 'images/snake_theta2-trans.png'
latex_logo = None latex_logo = 'images/theano_logo_allblue_200x46.png'
# 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.
......
import sys
import re
import os
from docutils import nodes, utils
from docutils.parsers.rst import roles
import epydoc.docwriter.xlink as xlink
def role_fn(name, rawtext, text, lineno, inliner,
options={}, content=[]):
node = nodes.reference(rawtext, text, refuri = "http://pylearn.org/theano/wiki/%s" % text)
return [node], []
_TARGET_RE = re.compile(r'^(.*?)\s*<(?:URI:|URL:)?([^<>]+)>$')
def create_api_role(name, problematic):
"""
Create and register a new role to create links for an API documentation.
Create a role called `name`, which will use the URL resolver registered as
``name`` in `api_register` to create a link for an object.
:Parameters:
`name` : `str`
name of the role to create.
`problematic` : `bool`
if True, the registered role will create problematic nodes in
case of failed references. If False, a warning will be raised
anyway, but the output will appear as an ordinary literal.
"""
def resolve_api_name(n, rawtext, text, lineno, inliner,
options={}, content=[]):
# Check if there's separate text & targets
m = _TARGET_RE.match(text)
if m: text, target = m.groups()
else: target = text
# node in monotype font
text = utils.unescape(text)
node = nodes.literal(rawtext, text, **options)
# Get the resolver from the register and create an url from it.
try:
url = xlink.api_register[name].get_url(target)
except IndexError, exc:
msg = inliner.reporter.warning(str(exc), line=lineno)
if problematic:
prb = inliner.problematic(rawtext, text, msg)
return [prb], [msg]
else:
return [node], []
if url is not None:
node = nodes.reference(rawtext, '', node, refuri=url, **options)
return [node], []
roles.register_local_role(name, resolve_api_name)
def setup(app):
try:
xlink.set_api_file('api', os.path.join(app.outdir, 'api', 'api-objects.txt'))
apiroot = os.getenv('THEANO_API_ROOT')
if not apiroot:
apiroot = os.path.join(os.path.realpath('api'), '')
xlink.set_api_root('api', apiroot)
#xlink.create_api_role('api', True)
create_api_role('api', True)
except IOError:
print >>sys.stderr, 'WARNING: Could not find api file! API links will not work.'
app.add_role("wiki", role_fn)
...@@ -44,7 +44,7 @@ What needs to be defined ...@@ -44,7 +44,7 @@ What needs to be defined
In order to be C-compatible, a Type must define several additional In order to be C-compatible, a Type must define several additional
methods, which all start with the ``c_`` prefix. The complete list can methods, which all start with the ``c_`` prefix. The complete list can
be found in the documentation for :api:`gof.type.Type`. Here, we'll focus on be found in the documentation for :class:`.gof.type.Type`. Here, we'll focus on
the most important ones: the most important ones:
......
...@@ -10,7 +10,7 @@ Making the double type ...@@ -10,7 +10,7 @@ Making the double type
Type's contract Type's contract
=============== ===============
In Theano's framework, a ``Type`` (:api:`gof.type.Type`) In Theano's framework, a ``Type`` (:class:`.gof.type.Type`)
is any object which defines the following is any object which defines the following
methods. To obtain the default methods described below, the Type should methods. To obtain the default methods described below, the Type should
be an instance of ``Type`` or should be an instance of a be an instance of ``Type`` or should be an instance of a
......
...@@ -252,3 +252,10 @@ to both. ...@@ -252,3 +252,10 @@ to both.
As you read through examples of Theano code, you will probably see many As you read through examples of Theano code, you will probably see many
instances of Modules being nested in this way. instances of Modules being nested in this way.
===================================================================
:mod:`module` -- API documentation
===================================================================
.. automodule:: theano.compile.module
:members:
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
env env
toolbox toolbox
type
.. _libdoc_gof_type:
================================================
:mod:`type` -- Interface for types of variables
================================================
.. module:: env
:platform: Unix, Windows
:synopsis: Interface for types of symbolic variables
.. moduleauthor:: LISA
---------
Reference
---------
.. automodule:: theano.gof.type
:members:
...@@ -133,7 +133,7 @@ analogous to a function. ...@@ -133,7 +133,7 @@ analogous to a function.
A Module is meant to contain Components. A Module is meant to contain Components.
Attributes which are not Components themselves must at least be transform-able Attributes which are not Components themselves must at least be transform-able
into Components by :api:`compile.module.wrap`. If a Module contains something into Components by :func:`.compile.module.wrap`. If a Module contains something
that is not convertible into a Component, then it is not possible to compile that is not convertible into a Component, then it is not possible to compile
that Module with ``make``. that Module with ``make``.
......
.. _module: .. _module2:
###### ######
Module Module
......
...@@ -62,7 +62,7 @@ What is staticmethod, st_impl? ...@@ -62,7 +62,7 @@ What is staticmethod, st_impl?
implicitly take the class instance as a first argument. Hence, st_impl implicitly take the class instance as a first argument. Hence, st_impl
can be used for Op implementations when no information from the Op can be used for Op implementations when no information from the Op
instance is needed. This can be useful for testing an implementation. instance is needed. This can be useful for testing an implementation.
See :api:`XlogX` for an example. See the ``XlogX`` class below for an example.
**This documentation is useful when we show users how to write Ops. **This documentation is useful when we show users how to write Ops.
Olivier says this behavior should be discouraged but I feel that st_impl Olivier says this behavior should be discouraged but I feel that st_impl
...@@ -72,7 +72,7 @@ should be encouraged where possible.** ...@@ -72,7 +72,7 @@ should be encouraged where possible.**
how do we write scalar ops and upgrade them to tensor ops? how do we write scalar ops and upgrade them to tensor ops?
============================================================ ============================================================
**Olivier says that :api:`XlogX` gives a good example. In fact, I would **Olivier says that** :class:`~theano.tensor.xlogx.XlogX` **gives a good example. In fact, I would
like to beef xlogx up into our running example for demonstrating how to like to beef xlogx up into our running example for demonstrating how to
write an Op:** write an Op:**
......
...@@ -112,8 +112,8 @@ Misc ...@@ -112,8 +112,8 @@ Misc
---- ----
The sparse equivalent of dmatrix is csc_matrix and csr_matrix. The sparse equivalent of dmatrix is csc_matrix and csr_matrix.
:api:`Dot` vs. :api:`StructuredDot` :class:`~theano.sparse.basic.Dot` vs. :class:`~theano.sparse.basic.StructuredDot`
---------------------------------------- ---------------------------------------------------------------------------------
Often when you use a sparse matrix it is because there is a meaning to the Often when you use a sparse matrix it is because there is a meaning to the
structure of non-zeros. The gradient on terms outside that structure structure of non-zeros. The gradient on terms outside that structure
......
...@@ -73,19 +73,9 @@ if __name__ == '__main__': ...@@ -73,19 +73,9 @@ if __name__ == '__main__':
print ' --help: this help' print ' --help: this help'
sys.exit(0) sys.exit(0)
options['--all'] = not (bool(options['--epydoc']) ^ bool(options['--rst'])) if not (options['--epydoc'] or options['--rst']):
# Default is now rst
if 0: options['--rst'] = True
import gen_oplist
print 'Generating oplist...'
gen_oplist.print_file(open('%s/doc/indexes/oplist.txt' % throot, 'w'))
print 'oplist done!'
if 0:
import gen_typelist
print 'Generating typelist...'
gen_typelist.print_file(open('%s/doc/indexes/typelist.txt' % throot, 'w'))
print 'typelist done!'
def mkdir(path): def mkdir(path):
try: try:
...@@ -96,8 +86,6 @@ if __name__ == '__main__': ...@@ -96,8 +86,6 @@ if __name__ == '__main__':
outdir = options['-o'] or (throot + '/html') outdir = options['-o'] or (throot + '/html')
mkdir(outdir) mkdir(outdir)
os.chdir(outdir) os.chdir(outdir)
mkdir("doc")
mkdir("api")
# Make sure the appropriate 'theano' directory is in the PYTHONPATH # Make sure the appropriate 'theano' directory is in the PYTHONPATH
pythonpath = os.environ.get('PYTHONPATH', '') pythonpath = os.environ.get('PYTHONPATH', '')
...@@ -105,6 +93,7 @@ if __name__ == '__main__': ...@@ -105,6 +93,7 @@ if __name__ == '__main__':
os.environ['PYTHONPATH'] = pythonpath os.environ['PYTHONPATH'] = pythonpath
if options['--all'] or options['--epydoc']: if options['--all'] or options['--epydoc']:
mkdir("api")
from epydoc.cli import cli from epydoc.cli import cli
sys.path[0:0] = [throot] sys.path[0:0] = [throot]
...@@ -120,6 +109,7 @@ if __name__ == '__main__': ...@@ -120,6 +109,7 @@ if __name__ == '__main__':
# TODO # TODO
if options['--all'] or options['--rst']: if options['--all'] or options['--rst']:
mkdir("doc")
import sphinx import sphinx
sys.path[0:0] = [os.path.join(throot, 'doc')] sys.path[0:0] = [os.path.join(throot, 'doc')]
sphinx.main(['', '-E', os.path.join(throot, 'doc'), '.']) sphinx.main(['', '-E', os.path.join(throot, 'doc'), '.'])
......
"""script to generate doc/oplist.txt, which compiles to :doc:`oplist`. """
__docformat__ = "restructuredtext en"
import sys, os
throot = "/".join(sys.path[0].split("/")[:-2])
sys.path[0:0] = [throot]
from theano import gof
def print_title(file, title_string, under_char, over_char=''):
l = len(title_string)
if over_char:
print >>file, over_char * l
print >>file, title_string
if under_char:
print >>file, under_char * l
print >>file, ""
def print_hline(file):
print >>file, '-' * 80
class Entry:
"""Structure for generating the oplist file"""
symbol = None
name = None
module = None
docstring = None
tags = []
def __init__(self, symbol, name, current_module):
self.symbol = symbol
self.name = name
self.module = symbol.__module__ # current_module.__name__ # symbol.__module__
self.docstring = symbol.__doc__
self.tags = ['%s' % current_module.__name__] + getattr(symbol, '__oplist_tags', [])
def mini_desc(self, maxlen=50):
"""Return a short description of the op"""
def chomp(s):
"""interpret and left-align a docstring"""
if 'subtensor' in s:
debug = 0
else:
debug = 0
r = []
leadspace = True
for c in s:
if leadspace and c in ' \n\t':
continue
else:
leadspace = False
if c == '\n':
if debug:
print >> sys.stderr, 'breaking'
break
if c in '\t*`':
c = ' ';
r.append(c)
if debug:
print >> sys.stderr, r
return "".join(r)
minmax = 5
assert maxlen >= minmax
if not self.docstring:
return "" #+ '(no doc)'
elif len(self.docstring) < maxlen:
return chomp(self.docstring)
else:
return "%s ..."% chomp(self.docstring[:maxlen-minmax])
apilink = property(lambda self: ":api:`%s <%s.%s>`"% (self.name, self.module, self.name))
"""Return the ReST link into the epydoc of this symbol"""
class EntryOp(Entry):
def __init__(self, symbol, *args):
has_perform = hasattr(symbol, 'perform')
if symbol is gof.Op:
raise TypeError('not an Op subclass')
if not issubclass(symbol, gof.Op):
raise TypeError('not an Op subclass')
Entry.__init__(self, symbol, *args)
class EntryConstructor(Entry):
def __init__(self, symbol, name, module):
is_op = isinstance(symbol, gof.Op)
is_ctor = symbol in getattr(module, '__oplist_constructor_list', [])
if not (is_op or is_ctor):
raise TypeError('not a constructor', symbol)
Entry.__init__(self, symbol, name, module)
def search_entries(module_list, ops = None, constructors = None, seen = None):
if ops is None: ops = []
if constructors is None: constructors = []
if seen is None: seen = set()
modules = []
for module in module_list:
symbol_name_list = [s for s in dir(module) if not s[0] == '_']
for symbol_name in symbol_name_list:
symbol = getattr(module, symbol_name)
try:
if symbol in seen:
continue
seen.add(symbol)
except TypeError:
pass
if type(symbol) == type(module): # module
modules.append(symbol)
try:
ops.append(EntryOp(symbol, symbol_name, module))
except TypeError:
try:
constructors.append(EntryConstructor(symbol, symbol_name, module))
except TypeError:
pass
for symbol in modules:
search_entries([symbol], ops, constructors, seen)
return ops, constructors
def print_entries(file, ops, constructors):
tags = {}
for o in ops + constructors:
for t in o.tags:
tags.setdefault(t, []).append(o)
for t in tags:
print_title(file, t, '=')
tagged_ops = [op for op in tags[t] if isinstance(op, EntryOp)]
if len(tagged_ops):
print_title(file, 'Op Classes', '-')
for op in tagged_ops:
print >>file, "- %s" % op.apilink
print >>file, " %s" % op.mini_desc()
print >>file, ""
tagged_ops = [op for op in tags[t] if isinstance(op, EntryConstructor)]
if len(tagged_ops):
print_title(file, 'Op Constructors', '-')
for op in tagged_ops:
print >>file, "- %s" % op.apilink
print >>file, " %s" % op.mini_desc()
print >>file, ""
def print_file(file):
print >>file, '.. _oplist:\n\n'
print_title(file, "Op List", "~", "~")
print >>file, """
This page lists the `Op Classes` and `constructors` that are provided by the Theano library.
`Op Classes` drive from :api:`Op`, whereas `constructors` are typically `Op Class` instances, but may be true Python functions.
In the future, this list may distinguish `constructors` that are Op instances from true Python functions.
"""
print_hline(file)
print >>file, ""
print >>file, ".. contents:: "
print >>file, ""
ops, constructors = search_entries([theano])
print_entries(file, ops, constructors)
print >>file, ""
import theano
if __name__ == "__main__":
"""Generate the op list"""
if len(sys.argv) >= 2:
file = open(sys.argv[1], 'w')
else:
file = sys.stdout
print_file(file)
from gen_oplist import print_title, print_hline
def print_file(file):
print >>file, '.. _typelist:\n\n'
print_title(file, "Type List", "~", "~")
print >>file, "*THIS PAGE IS A PLACEHOLDER: WRITEME*"
print >>file, ""
print_hline(file)
print >>file, ""
print >>file, ".. contents::"
print >>file, ""
print_title(file, "Type Classes", '=')
print >>file, "- scalar.Scalar\n"
print >>file, "- tensor.Tensor\n"
print >>file, "- sparse.Sparse\n"
print_title(file, "Type Instances", '=')
print >>file, "- scalar.int8\n"
print >>file, "- tensor.lvector\n"
print >>file, "- sparse.??\n"
print >>file, ""
if __name__ == '__main__':
if len(sys.argv) >= 2:
file = open(sys.argv[1], 'w')
else:
file = sys.stdout
print_file(file)
...@@ -223,10 +223,9 @@ class Variable(utils.object2): ...@@ -223,10 +223,9 @@ class Variable(utils.object2):
A Variable which is the output of a symbolic computation will have an owner != None. A Variable which is the output of a symbolic computation will have an owner != None.
Code Example **Code Example**
============
.. python:: .. code-block:: python
import theano import theano
from theano import tensor from theano import tensor
......
...@@ -340,7 +340,8 @@ class Type(object2, PureType, CLinkerType): ...@@ -340,7 +340,8 @@ class Type(object2, PureType, CLinkerType):
The following following code illustrates the use of a Type instance, here tensor.fvector: The following following code illustrates the use of a Type instance, here tensor.fvector:
.. python:: .. code-block:: python
# Declare a symbolic floating-point vector using __call__ # Declare a symbolic floating-point vector using __call__
b = tensor.fvector() b = tensor.fvector()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论