Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
91ebcb3c
提交
91ebcb3c
authored
5月 23, 2021
作者:
Brandon T. Willard
提交者:
Brandon T. Willard
5月 24, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add doc warnings, fix small formatting issues, and remove outdated sections
上级
81da9eb8
显示空白字符变更
内嵌
并排
正在显示
16 个修改的文件
包含
54 行增加
和
278 行删除
+54
-278
dev_start_guide.rst
doc/dev_start_guide.rst
+4
-3
cop.rst
doc/extending/cop.rst
+2
-2
extending_aesara.rst
doc/extending/extending_aesara.rst
+8
-8
extending_aesara_c.rst
doc/extending/extending_aesara_c.rst
+1
-1
index.rst
doc/extending/index.rst
+1
-0
jax_op.rst
doc/extending/jax_op.rst
+4
-4
other_ops.rst
doc/extending/other_ops.rst
+4
-4
unittest.rst
doc/extending/unittest.rst
+21
-217
index.rst
doc/index.rst
+5
-1
install.rst
doc/install.rst
+0
-1
index.rst
doc/internal/index.rst
+0
-3
metadocumentation.rst
doc/internal/metadocumentation.rst
+0
-28
introduction.rst
doc/introduction.rst
+1
-3
scan.rst
doc/library/scan.rst
+1
-1
basic.rst
doc/library/tensor/basic.rst
+2
-2
updating.rst
doc/updating.rst
+0
-0
没有找到文件。
doc/dev_start_guide.rst
浏览文件 @
91ebcb3c
...
...
@@ -4,6 +4,10 @@
Developer Start Guide
=====================
.. warning::
This document is outdated.
Contributing
============
...
...
@@ -243,9 +247,6 @@ Documentation and docstrings
`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>`_
...
...
doc/extending/cop.rst
浏览文件 @
91ebcb3c
.. _cop:
====================================
====================================
=
Implementing the arithmetic COps in C
====================================
====================================
=
Now that we have set up our ``double`` type properly to allow C
implementations for operations that work on it, all we have to do now
...
...
doc/extending/extending_aesara.rst
浏览文件 @
91ebcb3c
...
...
@@ -7,14 +7,14 @@ Creating a new Op: Python implementation
So suppose you have looked through the library documentation and you don't see
a function that does what you want.
If you can implement something in terms of
existing ``Op``s
, you should do that.
If you can implement something in terms of
an existing ``Op``
, you should do that.
Odds are your function that uses existing Aesara expressions is short,
has no bugs, and potentially profits from optimizations that have already been
implemented.
However, if you cannot implement an ``Op`` in terms of
existing ``Op``s
, you have to
write a new one. Don't worry, Aesara was designed to make it easy to add new
``Op``
s, Types, and Optimizations
.
However, if you cannot implement an ``Op`` in terms of
an existing ``Op``
, you have to
write a new one. Don't worry, Aesara was designed to make it easy to add
a
new
``Op``
, ``Type``, and ``Optimization``
.
.. These 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`.
...
...
@@ -46,7 +46,7 @@ As an illustration, this tutorial shows how to write a simple Python-based
Aesara Graphs refresher
-----------------------
.. image::
../hpcs2011_tutorial/pics/apply_node
.png
.. image::
apply
.png
:width: 500 px
Aesara represents symbolic mathematical computations as graphs. Those graphs
...
...
@@ -145,9 +145,9 @@ or :func:`make_thunk`.
It takes several arguments:
- ``node`` is a reference to an Apply node which was previously
obtained via the
``Op``'s
:func:`make_node` method. It is typically not
used in
simple ``Op``s
, but it contains symbolic information that
could be required
for complex ``Op``s
.
obtained via the :func:`make_node` method. It is typically not
used in
a simple ``Op``
, but it contains symbolic information that
could be required
by a complex ``Op``
.
- ``inputs`` is a list of references to data which can be operated on using
non-symbolic statements, (i.e., statements in Python, Numpy).
- ``output_storage`` is a list of storage cells where the output
...
...
doc/extending/extending_aesara_c.rst
浏览文件 @
91ebcb3c
...
...
@@ -1029,7 +1029,7 @@ an apply-specific function.
Using GDB to debug COp's C code
==============================
==============================
=
When debugging C code, it can be useful to use GDB for code compiled
by Aesara.
...
...
doc/extending/index.rst
浏览文件 @
91ebcb3c
...
...
@@ -51,3 +51,4 @@ with Aesara itself.
unittest
scan
extending_faq
jax_op
doc/extending/jax_op.rst
浏览文件 @
91ebcb3c
Tutorial on adding JAX Ops to Aesara
=============================
=============================
=======
A
core feature of Aesara, previously named Aesara, is the JAX
backend. To support the backend JAX ops need be added to Aesara once to
be supported. This tutorial will explain each step
.
A
esara is able to convert its graphs into JAX compiled functions. In order to do
this, each ``Op`` in the graph must have a JAX implementation. This tutorial
will explain how JAX implementations are created for an ``Op``
.
Step 1: Identify the Aesara Op you’d like to JAXify
===================================================
...
...
doc/extending/other_ops.rst
浏览文件 @
91ebcb3c
...
...
@@ -137,7 +137,7 @@ You can extract the 4 fields with
:func:`Aesara.sparse.basic.csm_shape` to extract the individual
fields.
You can look at the `AddSD`
_
sparse `Op` for an example with C code. It implements
You can look at the `AddSD` sparse `Op` for an example with C code. It implements
the addition of a sparse matrix with a dense matrix.
Sparse Tests
...
...
@@ -200,7 +200,7 @@ To allow consistent interface of Ops that support OpenMP, we have some
helper code. Doing this also allows to enable/disable OpenMP globally
or per op for fine-grained control.
Your Op needs to inherit from ``
A
esara.graph.op.OpenMPOp``. If it overrides
Your Op needs to inherit from ``
a
esara.graph.op.OpenMPOp``. If it overrides
the ``__init__()`` method, it must have an ``openmp=None`` parameter
and must call ``super(MyOpClass, self).__init__(openmp=openmp)``.
...
...
@@ -263,11 +263,11 @@ along with pointers to the relevant documentation.
can split a sparse variable into its parts as TensorVariables. Those
can then be used as inputs to an op with C code.
* :class:`Generic <
A
esara.graph.type.Generic>` : Aesara type that
* :class:`Generic <
a
esara.graph.type.Generic>` : Aesara type that
represents a simple Python Object. Variables of this Aesara type are
represented in C as objects of class `PyObject
<https://docs.python.org/2/c-api/structures.html#c.PyObject>`_.
* :class:`CDataType <
A
esara.graph.type.CDataType>` : Aesara type that
* :class:`CDataType <
a
esara.graph.type.CDataType>` : Aesara type that
represents a C data type. The C type associated with this Aesara type
depends on the data being represented.
doc/extending/unittest.rst
浏览文件 @
91ebcb3c
...
...
@@ -4,6 +4,9 @@
Unit Testing
============
.. warning::
This document is very outdated.
Aesara relies heavily on unit testing. Its importance cannot be
stressed enough!
...
...
@@ -45,20 +48,17 @@ Mostly `pytest aesara/`
Folder Layout
-------------
"tests" directories are scattered throughout aesara. Each tests
subfolder is meant to contain the unittests which validate the .py
files in the parent folder.
Files containing unittests should be prefixed with the word "test".
Optimally every python module should have a unittest file associated
with it, as shown below. Unittests testing functionality of module
<module>.py should therefore be stored in tests/test_<module>.py::
with it, as shown below. Unit tests that test functionality of module
``<module>.py`` should therefore be stored in
``tests/<sub-package>/test_<module>.py``::
Aesara/aesara/tensor/basic.py
Aesara/aesara/tensor/elemwise.py
Aesara/
aesara/tensor/tests
/test_basic.py
Aesara/
aesara/tensor/tests
/test_elemwise.py
Aesara/
tests/tensor
/test_basic.py
Aesara/
tests/tensor
/test_elemwise.py
How to Write a Unittest
...
...
@@ -67,16 +67,14 @@ How to Write a Unittest
Test Cases and Methods
----------------------
Unittests should be grouped "logically" into test cases, which are
meant to group all unittests operating on the same element and/or
concept. Test cases are implemented as Python classes which inherit
from unittest.TestCase
Unit tests should be grouped "logically" into test cases, which are
meant to group all unit tests operating on the same element and/or
concept.
Test cases contain multiple test methods. These should be prefixed
with the word "test".
Test cases should be functions or classes prefixed with the word "test".
Test methods should be as specific as possible and cover a particular
aspect of the problem. For example, when testing the
TensorDot Op
, one
aspect of the problem. For example, when testing the
``Dot`` ``Op``
, one
test method could check for validity, while another could verify that
the proper errors are raised when inputs have invalid dimensions.
...
...
@@ -84,224 +82,30 @@ Test method names should be as explicit as possible, so that users can
see at first glance, what functionality is being tested and what tests
need to be added.
Example:
.. code-block:: python
import unittest
class TestTensorDot(unittest.TestCase):
def test_validity(self):
# do stuff
...
def test_invalid_dims(self):
# do more stuff
...
Test cases can define a special setUp method, which will get called
before each test method is executed. This is a good place to put
functionality which is shared amongst all test methods in the test
case (i.e initializing data, parameters, seeding random number
generators -- more on this later)
.. testcode:: writeUnitest
import unittest
class TestTensorDot(unittest.TestCase):
def setUp(self):
# data which will be used in various test methods
self.avals = numpy.array([[1,5,3],[2,4,1]])
self.bvals = numpy.array([[2,3,1,8],[4,2,1,1],[1,4,8,5]])
Similarly, test cases can define a tearDown method, which will be
implicitely called at the end of each test method.
Checking for correctness
------------------------
When checking for correctness of mathematical expressions, the user
should preferably compare aesara's output to the equivalent
nump
y
should preferably compare aesara's output to the equivalent
NumP
y
implementation.
Example:
.. code-block:: python
class TestTensorDot(unittest.TestCase):
def setUp(self):
...
def test_validity(self):
a = T.dmatrix('a')
b = T.dmatrix('b')
c = T.dot(a, b)
def test_dot_validity():
a = aet.dmatrix('a')
b = aet.dmatrix('b')
c = aet.dot(a, b)
f = aesara.function([a, b], [c])
cmp = f(self.avals, self.bvals) == numpy.dot(self.avals, self.bvals)
self.assertTrue(numpy.all(cmp))
Avoid hard-coding variables, as in the following case:
.. code-block:: python
self.assertTrue(numpy.all(f(self.avals, self.bvals) == numpy.array([[25, 25, 30, 28], [21, 18, 14, 25]])))
This makes the test case less manageable and forces the user to update
the variables each time the input is changed or possibly when the
module being tested changes (after a bug fix for example). It also
constrains the test case to specific input/output data pairs. The
section on random values covers why this might not be such a good
idea.
Here is a list of useful functions, as defined by TestCase:
* checking the state of boolean variables: assert,
assertTrue, assertFalse
* checking for (in)equality constraints: assertEqual,
assertNotEqual
* checking for (in)equality constraints up to a given precision (very
useful in aesara): assertAlmostEqual,
assertNotAlmostEqual
Checking for errors
-------------------
On top of verifying that your code provides the correct output, it is
equally important to test that it fails in the appropriate manner,
raising the appropriate exceptions, etc. Silent failures are deadly,
as they can go unnoticed for a long time and a hard to detect
"after-the-fact".
Example:
.. code-block:: python
import unittest
class TestTensorDot(unittest.TestCase):
...
def test_3D_dot_fail(self):
def func():
a = TensorType('float64', (False,False,False)) # create 3d tensor
b = dmatrix()
c = dot(a,b) # we expect this to fail
# above should fail as dot operates on 2D tensors only
self.assertRaises(TypeError, func)
Useful function, as defined by TestCase:
* assertRaises
Test Cases and Aesara Modes
---------------------------
When compiling aesara functions or modules, a mode parameter can be
given to specify which linker and optimizer to use.
Example:
.. code-block:: python
from aesara import function
f = function([a,b],[c],mode='FAST_RUN')
Whenever possible, unit tests should omit this parameter. Leaving
out the mode will ensure that unit tests use the default mode.
This default mode is set to
the configuration variable :attr:`config.mode`, which defaults to
'FAST_RUN', and can be set by various mechanisms (see :mod:`config`).
In particular, the enviromnment variable :envvar:`AESARA_FLAGS`
allows the user to easily switch the mode in which unittests are
run. For example to run all tests in all modes from a BASH script,
type this:
.. code-block:: bash
AESARA_FLAGS='mode=FAST_COMPILE' pytest
AESARA_FLAGS='mode=FAST_RUN' pytest
AESARA_FLAGS='mode=DebugMode' pytest
.. _random_value_in_tests:
Using Random Values in Test Cases
---------------------------------
``numpy.random`` is often used in unit tests to initialize large data
structures, for use as inputs to the function or module being
tested. When doing this, it is imperative that the random number
generator be seeded at the be beginning of each unit test. This will
ensure that unittest behaviour is consistent from one execution to
another (i.e., always pass or always fail).
Instead of using ``numpy.random.seed`` to do this, we encourage users to
do the following:
.. testcode::
from tests import unittest_tools
class TestTensorDot(unittest.TestCase):
def setUp(self):
unittest_tools.seed_rng()
# OR ... call with an explicit seed
unittest_tools.seed_rng(234234) # use only if really necessary!
The behaviour of ``seed_rng`` is as follows:
* If an explicit seed is given, it will be used for seeding numpy's rng.
* If not, it will use ``config.unittests__rseed`` (its default value is ``666``).
* If ``config.unittests__rseed`` is set to ``"random"``, it will seed the rng with
None, which is equivalent to seeding with a random seed.
The main advantage of using ``unittest_tools.seed_rng`` is that it allows
us to change the seed used in the unitests, without having to manually
edit all the files. For example, this allows the nightly build to run
``pytest`` repeatedly, changing the seed on every run (hence achieving
a higher confidence that the variables are correct), while still
making sure unittests are deterministic.
Users who prefer their unittests to be random (when run on their local
machine) can simply set ``config.unittests__rseed`` to ``'random'`` (see
:mod:`config`).
Similarly, to provide a seed to ``numpy.random.RandomState``, simply use:
.. testcode::
import numpy
rng = numpy.random.RandomState(unittest_tools.fetch_seed())
# OR providing an explicit seed
rng = numpy.random.RandomState(unittest_tools.fetch_seed(1231)) # again not recommended
Note that the ability to change the seed from one test to another,
is incompatible with the method of hard-coding the baseline variables
(against which we compare the aesara outputs). These must then be
determined "algorithmically". Although this represents more work, the
test suite will be better because of it.
To help you check that the boundaries provided to ``numpy.random`` are
correct and your tests will pass those corner cases, you can check
``utt.MockRandomState``. Code using ``utt.MockRandomState`` should not
be committed, it is just a tool to help adjust the sampling range.
assert np.array_equal(f(self.avals, self.bvals), numpy.dot(self.avals, self.bvals))
Creating an Op UnitTest
Creating an Op Unit
Test
=======================
A few tools have been developed to help automate the development of
unitests for Aesara Ops.
unit
t
ests for Aesara Ops.
.. _validating_grad:
...
...
doc/index.rst
浏览文件 @
91ebcb3c
...
...
@@ -16,6 +16,11 @@ arrays efficiently. Aesara features:
Aesara is based on `Theano`_, which has been powering large-scale computationally
intensive scientific investigations since 2007.
.. warning::
Much of the documentation hasn't been updated and is simply the old Theano documentation.
Download
========
...
...
@@ -69,7 +74,6 @@ Roughly in order of what you'll want to check out:
:maxdepth: 1
:hidden:
NEWS
introduction
requirements
install
...
...
doc/install.rst
100755 → 100644
浏览文件 @
91ebcb3c
...
...
@@ -12,7 +12,6 @@ Supported platforms:
install_macos
install_windows
install_centos6
install_others
Once your setup is complete and if you installed the GPU libraries, head to :ref:`testing_the_gpu` to find how to verify
everything is working properly.
...
...
doc/internal/index.rst
浏览文件 @
91ebcb3c
...
...
@@ -8,8 +8,5 @@ Internal Documentation
.. toctree::
:maxdepth: 2
release
dev_start_guide
metadocumentation
python
how_to_release
doc/internal/metadocumentation.rst
浏览文件 @
91ebcb3c
...
...
@@ -85,31 +85,3 @@ It will not appear in the output generated.
.. TODO: Check it out, this won't appear.
.. Nor will this.
How documentation is built
----------------------------------------------
TBD
pylint
---------------------------------------
pylint output is not autogenerated anymore.
Pylint documentation is generated using pylintrc file: ``Aesara/doc/pylintrc``
.. _metadocumentation_nightly_build:
The nightly build/tests process
---------------------------------------
We use GitHub Actions to run daily builds and test for Aesara.
TO WRITE
---------------------------------------
*There is other stuff to document here, e.g.:*
* We also want examples of good documentation, to show people how to write ReST.
doc/introduction.rst
浏览文件 @
91ebcb3c
...
...
@@ -9,8 +9,7 @@ Aesara is a Python library that lets you define, optimize, and evaluate
mathematical expressions, especially ones with multi-dimensional arrays
(numpy.ndarray). Using Aesara it is
possible to attain speeds rivaling hand-crafted C implementations for problems
involving large amounts of data. It can also surpass C on a CPU by many orders
of magnitude by taking advantage of recent GPUs.
involving large amounts of data.
Aesara combines aspects of a computer algebra system (CAS) with aspects of an
optimizing compiler. It can also generate customized C code for many
...
...
@@ -25,7 +24,6 @@ Aesara's compiler applies many optimizations of varying complexity to
these symbolic expressions. These optimizations include, but are not
limited to:
* use of GPU for computations
* constant folding
* merging of similar subgraphs, to avoid redundant calculation
* arithmetic simplification (e.g. ``x*y/x -> y``, ``--x -> x``)
...
...
doc/library/scan.rst
浏览文件 @
91ebcb3c
...
...
@@ -682,4 +682,4 @@ reference
.. autofunction:: aesara.foldl
.. autofunction:: aesara.foldr
.. autofunction:: aesara.scan
.. autofunction:: aesara.scan_checkpoints
.. autofunction:: aesara.scan
.scan
_checkpoints
doc/library/tensor/basic.rst
浏览文件 @
91ebcb3c
...
...
@@ -465,7 +465,7 @@ TensorVariable
you'll want to call.
.. autoclass:: _tensor_py_operators
.. autoclass::
var.
_tensor_py_operators
:members:
This mix-in class adds convenient attributes, methods, and support
...
...
@@ -1749,7 +1749,7 @@ Linear Algebra
Gradient / Differentiation
==========================
.. automodule::
A
esara.gradient
.. automodule::
a
esara.gradient
:members: grad
:noindex:
...
...
doc/updating.rst
100755 → 100644
浏览文件 @
91ebcb3c
File mode changed from 100755 to 100644
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论