Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
1efb1539
提交
1efb1539
authored
4月 11, 2016
作者:
Pascal Lamblin
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4335 from fvisin/fix_elemwise
Check RST files in '/theano/doc/' to follow numpy's docstring + Fix elemwise
上级
2034dfb8
bf053fca
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
419 行增加
和
342 行删除
+419
-342
dev_start_guide.txt
doc/dev_start_guide.txt
+277
-217
extending_theano.txt
doc/extending/extending_theano.txt
+5
-36
elemwise.txt
doc/library/tensor/elemwise.txt
+15
-0
index.txt
doc/library/tensor/index.txt
+1
-0
doubleop.py
theano/misc/doubleop.py
+18
-8
elemwise.py
theano/tensor/elemwise.py
+103
-81
没有找到文件。
doc/dev_start_guide.txt
浏览文件 @
1efb1539
...
...
@@ -8,7 +8,7 @@ Contributing
============
You want to contribute to Theano? That is great! This page explain our
workflow and some res
s
ource for doing so.
workflow and some resource for doing so.
Looking for an idea for a first contribution? Check `github issue
<https://github.com/Theano/Theano/issues?q=is%3Aopen+is%3Aissue+label%3A%22Easy+fix%22>`
...
...
@@ -39,11 +39,287 @@ To get up to speed, you'll need to
.. _Sphinx: http://sphinx.pocoo.org/
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _Allowed docstring sections in Napoleon: https://sphinxcontrib-napoleon.readthedocs.org/en/latest/#docstring-sections
.. _NumPy documentation: http://docs.scipy.org/numpy/
.. _unittest: http://docs.python.org/library/unittest.html
.. _nose: http://nose.readthedocs.org/en/latest/
.. _quality_contributions:
Requirements for Quality Contributions
======================================
* All the code should be properly tested.
* The code should be compatible with Python 2.6 and above, as well as Python
3.3 and above (using `six` if needed).
* All the code should respect the
`PEP8 Code Style Guide <http://www.python.org/dev/peps/pep-0008>`_.
* The docstrings of all the classes and functions should respect the
`PEP257 <https://www.python.org/dev/peps/pep-0257/>`_ rules and follow the
`Numpy docstring standard
<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_.
Each point will be referred to more in detail in the following.
Unit tests
----------
When you submit a pull request, your changes will automatically be
tested via Travis-CI. This will post the results of the tests with a
little icon next to your commit. A yellow circle means the tests are
running. A red X means the tests failed and a green circle means the
tests passed.
Just because the tests run automatically does not mean you shouldn't
run them yourself to make sure everything is all right. You can run
only the portion you are modifying to go faster and have travis to
make sure there are no global impacts.
Also, if you are changing GPU code, travis doesn't test that, because
there are no GPUs on the test nodes.
To run the test suite with the default options, you can follow the
instructions of :ref:`testing_installation`.
Each night we execute all the unit tests automatically, with several
sets of options. The result is sent by email to the `theano-buildbot`_
mailing list.
For more detail, see :ref:`metadocumentation_nightly_build`.
To run all the tests with the same configuration as the buildbot, run
this script:
.. code-block:: bash
theano/misc/do_nightly_build
This script accepts arguments that it forwards to nosetests. You can
run only some tests or enable pdb by giving the equivalent nosetests
parameters.
Setting up your Editor for PEP8
-------------------------------
Here are instructions for :ref:`Vim <vim_pep8>` and :ref:`Emacs
<emacs_pep8>`. If you have similar instructions for other text editors
or IDE, please let us know and we will update this documentation.
.. _vim_pep8:
Vim
~~~
Detection of warnings and errors is done by the `pep8`_ script
(or `flake8`_, that also checks for other things, like syntax
errors). Syntax highlighting and general integration into Vim is done by
the `Syntastic`_ plugin for Vim.
To setup VIM:
#. Install flake8 (if not already installed) with::
pip install flake8
.. note:: You can use ``easy_install`` instead of ``pip``, and ``pep8``
instead of ``flake8`` if you prefer. The important thing is that the
``flake8`` or ``pep8`` executable ends up in your ``$PATH``.
#. Install vundle with::
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
#. Edit ``~/.vimrc`` and add the lines:
.. code-block:: python
set nocompatible " be iMproved, required
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'gmarik/Vundle.vim' " let Vundle manage Vundle (required!)
Plugin 'scrooloose/syntastic'
Plugin 'jimf/vim-pep8-text-width'
" Syntastic settings
" You can run checkers explicitly by calling :SyntasticCheck <checker
let g:syntastic_python_checkers = ['flake8'] "use one of the following checkers:
" flake8, pyflakes, pylint, python (native checker)
let g:syntastic_enable_highlighting = 1 "highlight errors and warnings
let g:syntastic_style_error_symbol = ">>" "error symbol
let g:syntastic_warning_symbol = ">>" "warning symbol
let g:syntastic_check_on_open = 1
let g:syntastic_auto_jump = 0 "do not jump to errors when detected
#. Open a new vim and run ``:PluginInstall`` to automatically install the
plugins. When the installation is done, close the installation "window"
with ``:q``.
From now on Vim will check for PEP8 errors and highlight them whenever a
file is saved.
A few useful commands
"""""""""""""""""""""
* Open the list of errors: ``:lopen``, that can be abbreviated in ``:lop``
(denoted ``:lop[en]``).
* Close that list: ``:lcl[ose]``.
* Next error: ``:lne[xt]``.
* Previous error: ``:lp[revious]``.
Once you fix errors, messages and highlighting will still appear in the
fixed file until you save it again.
We can also configure the ``~/.vimrc`` to make it easier to work with Syntastic.
For instance, to add a summary in the status bar, you can add::
set statusline+=%{SyntasticStatuslineFlag()}
To bind F2 and F3 to navigate to previous and next error, you can add::
map <F2> :lprevious<CR>
map <F3> :lnext<CR>
You can prefix those by ``autocmd FileType python`` if you want these
bindings to work only on Python files.
.. _pep8: http://pypi.python.org/pypi/pep8
.. _flake8: http://pypi.python.org/pypi/flake8
.. _Syntastic: https://github.com/scrooloose/syntastic/
.. _pathogen.vim: https://github.com/tpope/vim-pathogen
.. _quickfix: http://vimdoc.sourceforge.net/htmldoc/quickfix.html#quickfix
.. _emacs_pep8:
Emacs
~~~~~
There is an **excellent** system to configure emacs for Python:
`emacs-for-python
<https://github.com/gabrielelanaro/emacs-for-python>`_. It gathers many
emacs config into one, and modifies them to behave together nicely. You
can use it to check for pep8 compliance and for Python syntax errors.
To install it on Linux, you can do like this:
.. code-block:: bash
cd
git clone https://github.com/gabrielelanaro/emacs-for-python.git ~/.emacs.d/emacs-for-python
Then in your ``~/.emacs`` file, add this:
.. code-block:: common-lisp
;; Mandatory
(load-file "~/.emacs.d/emacs-for-python/epy-init.el")
(add-to-list 'load-path "~/.emacs.d/emacs-for-python/") ;; tell where to load the various files
;; Each of them enables different parts of the system.
;; Only the first two are needed for pep8, syntax check.
(require 'epy-setup) ;; It will setup other loads, it is required!
(require 'epy-python) ;; If you want the python facilities [optional]
(require 'epy-completion) ;; If you want the autocompletion settings [optional]
(require 'epy-editing) ;; For configurations related to editing [optional]
;; [newer version of emacs-for-python]
(require 'epy-nose) ;; For shortcut to call nosetests [optional]
;; Define f10 to previous error
;; Define f11 to next error
(require 'epy-bindings) ;; For my suggested keybindings [optional]
;; Some shortcut that do not collide with gnome-terminal,
;; otherwise, "epy-bindings" define f10 and f11 for them.
(global-set-key [f2] 'flymake-goto-prev-error)
(global-set-key [f3] 'flymake-goto-next-error)
;; Next two lines are the checks to do. You can add more if you wish.
(epy-setup-checker "pyflakes %f") ;; For python syntax check
(epy-setup-checker "pep8 -r %f") ;; For pep8 check
.. note::
The script highlights problematic lines. This can make part of the
line not readable depending on the background. To replace the line
highlight by an underline, add this to your emacs configuration
file:
;; Make lines readable when there is an warning [optional]
(custom-set-faces
'(flymake-errline ((((class color)) (:underline "red"))))
'(flymake-warnline ((((class color)) (:underline "yellow")))))
Documentation and docstrings
----------------------------
* The documentation and the API documentation are generated using `Sphinx`_.
* The documentation should be written in `reStructuredText`_ and the
docstrings of all the classes and functions should respect the
`PEP257 <https://www.python.org/dev/peps/pep-0257/>`_ rules and follow the
`Numpy docstring standard
<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_.
* Split the docstrings in sections, according to the `Allowed docstring
sections in Napoleon`_
* To cross-reference other objects (e.g. reference other classes or methods) in
the docstrings, use the
`cross-referencing objects <http://www.sphinx-doc.org/en/stable/domains.html#cross-referencing-python-objects>`_
syntax. ``:py`` can be omitted, see e.g. this
`stackoverflow answer <http://stackoverflow.com/a/7754189>`_.
* See :ref:`metadocumentation`, for some information on how to generate the
documentation.
A Docstring Example
~~~~~~~~~~~~~~~~~~~
Here is an example on how to add a docstring to a class.
.. testcode:: python
import theano
class DoubleOp(theano.Op):
"""
Double each element of a tensor.
Parameters
----------
x : tensor
Input tensor
Returns
-------
tensor
a tensor of the same shape and dtype as the input with all
values doubled.
Notes
-----
this is a test note
See Also
--------
:class:`~theano.tensor.elemwise.Elemwise` : You can use this to replace
this example. Just execute `x * 2` with x being a Theano variable.
.. versionadded:: 0.6
"""
This is how it will show up for files that we auto-list in the library
documentation:
.. automodule:: theano.misc.doubleop
:members:
Installation and configuration
==============================
...
...
@@ -214,222 +490,6 @@ notified of your revision, so it is advised to reply to the comments on
GitHub, to let them know that you have submitted a fix.
.. _quality_contributions:
Tips for Quality Contributions
==============================
Coding Style Auto Check
-----------------------
In Theano, we use the same coding style as the `Pylearn
<http://deeplearning.net/software/pylearn/v2_planning/API_coding_style.html>`_
project, except that we don't use the numpy docstring standard.
The principal thing to know is that we follow the
`PEP 8 <http://www.python.org/dev/peps/pep-0008/>`_ coding style.
We use git hooks provided in the project `pygithooks
<https://github.com/lumberlabs/pygithooks>`_ to validate that commits
respect pep8. This happens when each user commits, not when we
push/merge to the Theano repository. Github doesn't allow us to have
code executed when we push to the repository. So we ask all
contributors to use those hooks.
For historic reason, we currently don't have all files respecting pep8.
We decided to fix everything incrementally. So not all files respect it
now. So we strongly suggest that you use the "increment" pygithooks
config option to have a good workflow. See the pygithooks main page
for how to set it up for Theano and how to enable this option.
Setting up your Editor for PEP8
-------------------------------
Here are instructions for :ref:`Vim <vim_pep8>` and :ref:`Emacs
<emacs_pep8>`. If you have similar instructions for other text editors
or IDE, please let us know and we will update this documentation.
.. _vim_pep8:
Vim
~~~
Detection of warnings and errors is done by the `pep8`_ script
(or `flake8`_, that also checks for other things, like syntax
errors). Syntax highlighting and general integration into Vim is done by
the `Syntastic`_ plugin for Vim.
To install flake8, simply run::
pip install flake8
You can use ``easy_install`` instead of ``pip``, and ``pep8`` instead of
``flake8`` if you prefer. The important thing is that the ``flake8`` or
``pep8`` executable ends up in your ``$PATH``.
To install Syntastic, according to its documentation, the easiest way is
to install `pathogen.vim`_ first.
Here's a relevant extract of pathogen.vim's installation instructions:
Install to ``~/.vim/autoload/pathogen.vim``. Or copy and paste::
mkdir -p ~/.vim/autoload ~/.vim/bundle; \
curl -so ~/.vim/autoload/pathogen.vim \
https://raw.github.com/tpope/vim-pathogen/HEAD/autoload/pathogen.vim
If you don't have ``curl``, use ``wget -O`` instead.
By the way, if you're using Windows, change all occurrences of ``~/.vim``
to ``~\vimfiles``.
Add this to your vimrc::
call pathogen#infect()
Now any plugins you wish to install can be extracted to a subdirectory
under ``~/.vim/bundle``, and they will be added to the ``'runtimepath'``.
Now, we can install Syntastic. From the installation instructions:
.. code-block:: bash
cd ~/.vim/bundle
git clone https://github.com/scrooloose/syntastic.git
Then reload vim, run ``:Helptags``, and check out ``:help syntastic.txt``.
From now on, when you save into a Python file, a syntax check will be
run, and results will be displayed using Vim's `quickfix`_ mechanism
(more precisely, a location-list). A few useful commands are:
* Open the list of errors: ``:lopen``, that can be abbreviated in ``:lop``
(denoted ``:lop[en]``).
* Close that list: ``:lcl[ose]``.
* Next error: ``:lne[xt]``.
* Previous error: ``:lp[revious]``.
Once you fix errors, messages and highlighting will still appear in the
fixed file until you save it again.
We can also configure the ``~/.vimrc`` to make it easier to work with Syntastic.
For instance, to add a summary in the status bar, you can add::
set statusline+=%{SyntasticStatuslineFlag()}
To bind F2 and F3 to navigate to previous and next error, you can add::
map <F2> :lprevious<CR>
map <F3> :lnext<CR>
You can prefix those by ``autocmd FileType python`` if you want these
bindings to work only on Python files.
.. _pep8: http://pypi.python.org/pypi/pep8
.. _flake8: http://pypi.python.org/pypi/flake8
.. _Syntastic: https://github.com/scrooloose/syntastic/
.. _pathogen.vim: https://github.com/tpope/vim-pathogen
.. _quickfix: http://vimdoc.sourceforge.net/htmldoc/quickfix.html#quickfix
.. _emacs_pep8:
Emacs
~~~~~
There is an **excellent** system to configure emacs for Python:
`emacs-for-python
<https://github.com/gabrielelanaro/emacs-for-python>`_. It gathers many
emacs config into one, and modifies them to behave together nicely. You
can use it to check for pep8 compliance and for Python syntax errors.
To install it on Linux, you can do like this:
.. code-block:: bash
cd
git clone https://github.com/gabrielelanaro/emacs-for-python.git ~/.emacs.d/emacs-for-python
Then in your ``~/.emacs`` file, add this:
.. code-block:: common-lisp
;; Mandatory
(load-file "~/.emacs.d/emacs-for-python/epy-init.el")
(add-to-list 'load-path "~/.emacs.d/emacs-for-python/") ;; tell where to load the various files
;; Each of them enables different parts of the system.
;; Only the first two are needed for pep8, syntax check.
(require 'epy-setup) ;; It will setup other loads, it is required!
(require 'epy-python) ;; If you want the python facilities [optional]
(require 'epy-completion) ;; If you want the autocompletion settings [optional]
(require 'epy-editing) ;; For configurations related to editing [optional]
;; [newer version of emacs-for-python]
(require 'epy-nose) ;; For shortcut to call nosetests [optional]
;; Define f10 to previous error
;; Define f11 to next error
(require 'epy-bindings) ;; For my suggested keybindings [optional]
;; Some shortcut that do not collide with gnome-terminal,
;; otherwise, "epy-bindings" define f10 and f11 for them.
(global-set-key [f2] 'flymake-goto-prev-error)
(global-set-key [f3] 'flymake-goto-next-error)
;; Next two lines are the checks to do. You can add more if you wish.
(epy-setup-checker "pyflakes %f") ;; For python syntax check
(epy-setup-checker "pep8 -r %f") ;; For pep8 check
.. note::
The script highlights problematic lines. This can make part of the
line not readable depending on the background. To replace the line
highlight by an underline, add this to your emacs configuration
file:
;; Make lines readable when there is an warning [optional]
(custom-set-faces
'(flymake-errline ((((class color)) (:underline "red"))))
'(flymake-warnline ((((class color)) (:underline "yellow")))))
Unit tests
----------
When you submit a pull request, your changes will automatically be
tested via Travis-CI. This will post the results of the tests with a
little icon next to your commit. A yellow circle means the tests are
running. A red X means the tests failed and a green circle means the
tests passed.
Just because the tests run automatically does not mean you shouldn't
run them yourself to make sure everything is all right. You can run
only the portion you are modifying to go faster and have travis to
make sure there are no global impacts.
Also, if you are changing GPU code, travis doesn't test that, because
there are no GPUs on the test nodes.
To run the test suite with the default options, you can follow the
instructions of :ref:`testing_installation`.
Each night we execute all the unit tests automatically, with several
sets of options. The result is sent by email to the `theano-buildbot`_
mailing list.
For more detail, see :ref:`metadocumentation_nightly_build`.
To run all the tests with the same configuration as the buildbot, run
this script:
.. code-block:: bash
theano/misc/do_nightly_build
This script accepts arguments that it forwards to nosetests. You can
run only some tests or enable pdb by giving the equivalent nosetests
parameters.
More Advanced Git Usage
=======================
...
...
doc/extending/extending_theano.txt
浏览文件 @
1efb1539
...
...
@@ -875,43 +875,12 @@ Modify and execute to compute: numpy.add and numpy.subtract.
Modify and execute the example to return two outputs: x + y
and x - y.
.. _Documentation:
Documentation
-------------
See :ref:`metadocumentation`, for some information on how to generate
the documentation.
Here is an example how to add docstring to a class.
.. testcode:: python
import theano
class DoubleOp(theano.Op):
""" Double each element of a tensor.
:param x: input tensor.
:return: a tensor of the same shape and dtype as the input with all
values doubled.
:note:
this is a test note
:seealso:
You can use the elemwise op to replace this example.
Just execute `x * 2` with x being a Theano variable.
.. versionadded:: 0.6
"""
This is how it will show up for files that we auto-list in the library
documentation:
.. automodule:: theano.misc.doubleop
:members:
Documentation and Coding Style
------------------------------
Please always respect the :ref:`quality_contributions` or your contribution
will not be accepted.
NanGuardMode and AllocEmpty
---------------------------
...
...
doc/library/tensor/elemwise.txt
0 → 100644
浏览文件 @
1efb1539
===================================================================
:mod:`tensor.elemwise` -- Tensor Elemwise
===================================================================
.. testsetup::
from theano.tensor.elemwise import *
.. module:: tensor.elemwise
:platform: Unix, Windows
:synopsis: Tensor Elemwise
.. moduleauthor:: LISA
.. automodule:: theano.tensor.elemwise
:members:
doc/library/tensor/index.txt
浏览文件 @
1efb1539
...
...
@@ -23,6 +23,7 @@ They are grouped into the following sections:
shared_randomstreams
signal/index
utils
elemwise
extra_ops
io
opt
...
...
theano/misc/doubleop.py
浏览文件 @
1efb1539
...
...
@@ -5,19 +5,29 @@ import theano
class
DoubleOp
(
theano
.
Op
):
""" Double each element of a tensor.
"""
Double each element of a tensor.
:param x: input tensor.
Parameters
----------
x : tensor
Input tensor
:return: a tensor of the same shape and dtype as the input with all
Returns
-------
tensor
a tensor of the same shape and dtype as the input with all
values doubled.
:note:
this is a test note
Notes
-----
this is a test note
See Also
--------
:class:`~theano.tensor.elemwise.Elemwise` : You can use this to replace
this example. Just execute `x * 2` with x being a Theano variable.
:seealso:
You can use the elemwise op to replace this example.
Just execute `x * 2` with x being a Theano variable.
.. versionadded:: 0.6
"""
...
...
theano/tensor/elemwise.py
浏览文件 @
1efb1539
...
...
@@ -76,18 +76,22 @@ class DimShuffle(Op):
If True, the output will be a view of the input.
If False (default), the output will be a copy of the input.
If j = new_order[i] is an index, the output's ith dimension
Note
----
If `j = new_order[i]` is an index, the output's ith dimension
will be the input's jth dimension.
If
new_order[i] is 'x'
, the output's ith dimension will
If
`new_order[i]` is `x`
, the output's ith dimension will
be 1 and Broadcast operations will be allowed to do broadcasting
over that dimension.
If
input.broadcastable[i] == False then i
must be found in new_order.
If
`input.broadcastable[i] == False` then `i`
must be found in new_order.
Broadcastable dimensions, on the other hand, can be discarded.
Extended Summary
----------------
DimShuffle((False, False, False), ['x', 2, 'x', 0, 1])
Note
----
.. code-block:: python
DimShuffle((False, False, False), ['x', 2, 'x', 0, 1])
This op will only work on 3d tensors with no broadcastable
dimensions. The first dimension will be broadcastable,
...
...
@@ -96,7 +100,9 @@ class DimShuffle(Op):
shape (20, 30, 40), the resulting tensor will have dimensions
(1, 40, 1, 20, 30). (AxBxC tensor is mapped to 1xCx1xAxB tensor)
DimShuffle((True, False), [1])
.. code-block:: python
DimShuffle((True, False), [1])
This op will only work on 2d tensors with the first dimension
broadcastable.
...
...
@@ -105,20 +111,23 @@ class DimShuffle(Op):
If the tensor has shape (1, 20), the resulting tensor will have shape
(20, ).
More examples :
DimShuffle((), ['x']) -> make a 0d (scalar) into a 1d vector
DimShuffle((False, False), [0, 1]) -> identity
DimShuffle((False, False), [1, 0]) -> inverts the 1st and 2nd dimensions
DimShuffle((False,), ['x', 0]) -> make a row out
of a 1d vector (N to 1xN)
DimShuffle((False,), [0, 'x']) -> make a column
out of a 1d vector (N to Nx1)
DimShuffle((False, False, False), [2, 0, 1]) -> AxBxC to CxAxB
DimShuffle((False, False), [0, 'x', 1]) -> AxB to Ax1xB
DimShuffle((False, False), [1, 'x', 0]) -> AxB to Bx1xA
The reordering of the dimensions can be done in numpy with the
transpose function.
Example
-------
.. code-block:: python
DimShuffle((), ['x']) # make a 0d (scalar) into a 1d vector
DimShuffle((False, False), [0, 1]) # identity
DimShuffle((False, False), [1, 0]) # inverts the 1st and 2nd dimensions
DimShuffle((False,), ['x', 0]) # make a row out of a 1d vector
# (N to 1xN)
DimShuffle((False,), [0, 'x']) # make a column out of a 1d vector
# (N to Nx1)
DimShuffle((False, False, False), [2, 0, 1]) # AxBxC to CxAxB
DimShuffle((False, False), [0, 'x', 1]) # AxB to Ax1xB
DimShuffle((False, False), [1, 'x', 0]) # AxB to Bx1xA
The reordering of the dimensions can be done with the numpy.transpose
function.
Adding, subtracting dimensions can be done with reshape.
"""
...
...
@@ -300,13 +309,14 @@ class DimShuffle(Op):
# get the copy / view of the input depending on whether we're doingi
# things inplace or not.
if
self
.
inplace
:
get_base
=
[
'{ PyArrayObject *
%(basename)
s =
%(input)
s'
,
'Py_INCREF((PyObject*)
%(basename)
s)'
]
get_base
=
[
'{ PyArrayObject *
%(basename)
s =
%(input)
s'
,
'Py_INCREF((PyObject*)
%(basename)
s)'
]
else
:
get_base
=
[(
'{ PyArrayObject *
%(basename)
s = '
'(PyArrayObject*)PyArray_FromAny((PyObject*)
%(input)
s,'
' NULL, 0, 0, NPY_ARRAY_ALIGNED|NPY_ARRAY_ENSURECOPY,'
' NULL)'
)]
get_base
=
[
(
'{ PyArrayObject *
%(basename)
s = '
'(PyArrayObject*)PyArray_FromAny((PyObject*)
%(input)
s,'
' NULL, 0, 0, NPY_ARRAY_ALIGNED|NPY_ARRAY_ENSURECOPY,'
' NULL)'
)]
shape_statements
=
[
'npy_intp dimensions[
%
i]'
%
nd_out
]
for
i
,
o
in
enumerate
(
self
.
new_order
):
...
...
@@ -343,12 +353,9 @@ class DimShuffle(Op):
)
for
i
in
xrange
(
nd_out
-
2
,
-
1
,
-
1
):
strides_statements
.
append
(
"if (strides[
%(i)
s] == 0) strides[
%(i)
s] = strides[
%(i)
s+1] * dimensions[
%(i)
s+1]"
%
dict
(
i
=
str
(
i
)))
"if (strides[
%(i)
s] == 0) strides[
%(i)
s] = strides[
%(i)
s+1] * "
"dimensions[
%(i)
s+1]"
%
dict
(
i
=
str
(
i
)))
#
# PyObject* PyArray_New(PyTypeObject* subtype, int nd, npy_intp* dims, int type_num,
# npy_intp* strides, void* data, int itemsize, int flags, PyObject* obj)
#
close_bracket
=
[
# create a new array,
(
'
%(res)
s = (PyArrayObject*)PyArray_New(&PyArray_Type, '
...
...
@@ -482,17 +489,17 @@ class Elemwise(OpenMPOp):
variable number of inputs), whereas the numpy function may
not have varargs.
Examples
----
----
Elemwise(add) #
represents + on tensors (x + y)
Elemwise(add, {0 : 0}) #
represents the += operation (x += y)
Elemwise(add, {0 : 1}) #
represents += on the second argument (y += x)
Elemwise(mul)(rand(10, 5), rand(1, 5)) # the second input is completed
#
along the first dimension to match the first input
Elemwise(true_div)(rand(10, 5), rand(10, 1)) # same but along the
#
second dimension
Elemwise(int_div)(rand(1, 5), rand(10, 1)) #
the output has size (10, 5)
Elemwise(log)(rand(3, 4, 5))
Note
----
| Elemwise(add)
represents + on tensors (x + y)
| Elemwise(add, {0 : 0})
represents the += operation (x += y)
| Elemwise(add, {0 : 1})
represents += on the second argument (y += x)
| Elemwise(mul)(rand(10, 5), rand(1, 5)) the second input is completed
\
along the first dimension to match the first input
| Elemwise(true_div)(rand(10, 5), rand(10, 1)) same but along the
\
second dimension
| Elemwise(int_div)(rand(1, 5), rand(10, 1))
the output has size (10, 5)
|
Elemwise(log)(rand(3, 4, 5))
"""
...
...
@@ -781,7 +788,8 @@ class Elemwise(OpenMPOp):
# the gradient contains a constant, translate it as
# an equivalent TensorType of size 1 and proper number of
# dimensions
res
=
theano
.
tensor
.
constant
(
numpy
.
asarray
(
r
.
data
),
dtype
=
r
.
type
.
dtype
)
res
=
theano
.
tensor
.
constant
(
numpy
.
asarray
(
r
.
data
),
dtype
=
r
.
type
.
dtype
)
return
DimShuffle
((),
[
'x'
]
*
nd
,
inplace
=
False
)(
res
)
new_r
=
Elemwise
(
node
.
op
,
{})(
*
[
transform
(
ipt
)
for
ipt
in
node
.
inputs
])
...
...
@@ -1127,15 +1135,20 @@ class Elemwise(OpenMPOp):
idtypes
+
list
(
real_odtypes
))])
preloops
=
{}
for
i
,
(
loop_order
,
dtype
)
in
enumerate
(
zip
(
loop_orders
,
dtypes
)):
for
i
,
(
loop_order
,
dtype
)
in
enumerate
(
zip
(
loop_orders
,
dtypes
)):
for
j
,
index
in
enumerate
(
loop_order
):
if
index
!=
'x'
:
preloops
.
setdefault
(
j
,
""
)
preloops
[
j
]
+=
(
"
%%
(lv
%(i)
s)s_iter = (
%(dtype)
s*)(PyArray_DATA(
%%
(lv
%(i)
s)s));
\n
"
%
locals
())
%
sub
preloops
[
j
]
+=
(
"
%%
(lv
%(i)
s)s_iter = (
%(dtype)
s*)"
"(PyArray_DATA(
%%
(lv
%(i)
s)s));
\n
"
%
locals
())
%
sub
break
else
:
# all broadcastable
preloops
.
setdefault
(
0
,
""
)
preloops
[
0
]
+=
(
"
%%
(lv
%(i)
s)s_iter = (
%(dtype)
s*)(PyArray_DATA(
%%
(lv
%(i)
s)s));
\n
"
%
locals
())
%
sub
preloops
[
0
]
+=
(
"
%%
(lv
%(i)
s)s_iter = (
%(dtype)
s*)"
"(PyArray_DATA(
%%
(lv
%(i)
s)s));
\n
"
%
locals
())
%
sub
init_array
=
preloops
.
get
(
0
,
" "
)
loop
=
"""
...
...
@@ -1202,7 +1215,8 @@ class Elemwise(OpenMPOp):
dtype_
%(x)
s&
%(x)
s_i = ((dtype_
%(x)
s*) PyArray_DATA(
%(x)
s))[0];
"""
%
locals
()
if
self
.
openmp
:
contig
+=
"""#pragma omp parallel for if(n>=
%
d)"""
%
(
config
.
openmp_elemwise_minsize
)
contig
+=
"""#pragma omp parallel for if(n>=
%
d)
"""
%
(
config
.
openmp_elemwise_minsize
)
contig
+=
"""
for(int i=0; i<n; i++){
%(index)
s
...
...
@@ -1259,7 +1273,8 @@ class Elemwise(OpenMPOp):
for
output
in
node
.
outputs
])
version
.
append
(
self
.
scalar_op
.
c_code_cache_version_apply
(
scalar_node
))
for
i
in
node
.
inputs
+
node
.
outputs
:
version
.
append
(
get_scalar_type
(
dtype
=
i
.
type
.
dtype
)
.
c_code_cache_version
())
version
.
append
(
get_scalar_type
(
dtype
=
i
.
type
.
dtype
)
.
c_code_cache_version
())
version
.
append
((
'openmp'
,
self
.
openmp
))
if
all
(
version
):
return
tuple
(
version
)
...
...
@@ -1298,20 +1313,22 @@ class CAReduce(Op):
- List of dimensions that we want to reduce
- If None, all dimensions are reduced
Examples
--------
CAReduce(add) -> sum (ie, acts like the numpy sum operation)
CAReduce(mul) -> product
CAReduce(maximum) -> max
CAReduce(minimum) -> min
CAReduce(or_) -> any # not lazy
CAReduce(and_) -> all # not lazy
CAReduce(xor) -> a bit at 1 tell that there was an odd number of bit at
that position that where 1.
0 it was an even number ...
Note
----
.. code-block:: python
CAReduce(add) # sum (ie, acts like the numpy sum operation)
CAReduce(mul) # product
CAReduce(maximum) # max
CAReduce(minimum) # min
CAReduce(or_) # any # not lazy
CAReduce(and_) # all # not lazy
CAReduce(xor) # a bit at 1 tell that there was an odd number of
# bit at that position that where 1. 0 it was an
# even number ...
In order to (eventually) optimize memory usage patterns,
L{CAReduce}
makes zero guarantees on the order in which it
CAReduce
makes zero guarantees on the order in which it
iterates over the dimensions and the elements of the
array(s). Therefore, to ensure consistent variables, the scalar
operation represented by the reduction must be both commutative
...
...
@@ -1507,7 +1524,8 @@ class CAReduce(Op):
if
hasattr
(
self
,
'acc_dtype'
)
and
self
.
acc_dtype
is
not
None
:
if
self
.
acc_dtype
==
'float16'
:
raise
theano
.
gof
.
utils
.
MethodNotDefined
(
"no c_code for float16"
)
raise
theano
.
gof
.
utils
.
MethodNotDefined
(
"no c_code for "
"float16"
)
acc_type
=
TensorType
(
broadcastable
=
node
.
outputs
[
0
]
.
broadcastable
,
dtype
=
self
.
acc_dtype
)
...
...
@@ -1684,7 +1702,8 @@ for(int i=0;i<PyArray_NDIM(%(iname)s);i++){
for
output
in
node
.
outputs
])
version
.
append
(
self
.
scalar_op
.
c_code_cache_version_apply
(
scalar_node
))
for
i
in
node
.
inputs
+
node
.
outputs
:
version
.
append
(
get_scalar_type
(
dtype
=
i
.
type
.
dtype
)
.
c_code_cache_version
())
version
.
append
(
get_scalar_type
(
dtype
=
i
.
type
.
dtype
)
.
c_code_cache_version
())
if
all
(
version
):
return
tuple
(
version
)
else
:
...
...
@@ -1695,7 +1714,7 @@ class All(CAReduce):
""" Applies `bitwise and` to all the values of a tensor along the
specified axis(es).
Equivalent to
CAReduce(scalar.and_, axis=axis)
.
Equivalent to
`CAReduce(scalar.and
\
_, axis=axis)`
.
"""
...
...
@@ -1727,7 +1746,7 @@ class Any(CAReduce):
""" Applies `bitwise or` to all the values of a tensor along the
specified axis(es).
Equivalent to
CAReduce(scalar.or_, axis=axis)
.
Equivalent to
`CAReduce(scalar.or
\
_, axis=axis)`
.
"""
...
...
@@ -1778,17 +1797,19 @@ class CAReduceDtype(CAReduce):
It must be commutative and associative.
axis
-
the dimension along which we want to reduce
-
list of dimensions that we want to reduce
-
if None, all dimensions are reduced
*
the dimension along which we want to reduce
*
list of dimensions that we want to reduce
*
if None, all dimensions are reduced
dtype
The dtype of the returned tensor. If None, then we use the default
dtype which is the same as the input tensor's dtype except when:
- the input dtype is a signed integer of precision < 64 bit, in
which case we use int64
- the input dtype is an unsigned integer of precision < 64 bit, in
which case we use uint64
* the input dtype is a signed integer of precision < 64 bit, in which
case we use int64
* the input dtype is an unsigned integer of precision < 64 bit, in
which case we use uint64
This default dtype does _not_ depend on the value of "acc_dtype".
This behavior is similar in spirit to that of numpy (except numpy
uses the default machine integer while we always use 64 bit
...
...
@@ -1798,10 +1819,11 @@ class CAReduceDtype(CAReduce):
The dtype of the internal accumulator.
If None (default), we use the dtype in the list below,
or the input dtype if its precision is higher:
- for int dtypes, we use at least int64;
- for uint dtypes, we use at least uint64;
- for float dtypes, we use at least float64;
- for complex dtypes, we use at least complex128.
* for int dtypes, we use at least int64;
* for uint dtypes, we use at least uint64;
* for float dtypes, we use at least float64;
* for complex dtypes, we use at least complex128.
"""
...
...
@@ -1930,7 +1952,7 @@ class Sum(CAReduceDtype):
"""
Sums all the values of a tensor along the specified axis(es).
Equivalent to
CAReduceDtype(scalar.add, axis=axis, dtype=dtype)
,
Equivalent to
`CAReduceDtype(scalar.add, axis=axis, dtype=dtype)`
,
with the difference that this defines the gradient of sum wrt its
tensor input.
...
...
@@ -2005,7 +2027,7 @@ class Prod(CAReduceDtype):
"""
Multiplies all the values of a tensor along the specified axis(es).
Equivalent to
CAReduce(scalar.prod, axis = axis)
, with the
Equivalent to
`CAReduce(scalar.prod, axis = axis)`
, with the
difference that this defines the gradient of prod wrt its tensor
input.
...
...
@@ -2052,10 +2074,9 @@ class Prod(CAReduceDtype):
"incoming gradient", ie. the gradient of the cost relative to the
output/product).
-----
With zeros, things get more complicated. For a given group, we have 3
cases:
* No zeros in the group. Use previous trick.
* If only one zero is present, then the gradient for that element is
non-zero, but is zero for all others.
...
...
@@ -2188,7 +2209,8 @@ class MulWithoutZeros(scalar.BinaryScalarOp):
def
c_code_cache_version
(
self
):
return
(
1
,)
mul_without_zeros
=
MulWithoutZeros
(
scalar
.
upcast_out
,
name
=
'mul_without_zeros'
)
mul_without_zeros
=
MulWithoutZeros
(
scalar
.
upcast_out
,
name
=
'mul_without_zeros'
)
class
ProdWithoutZeros
(
CAReduceDtype
):
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论