Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
07832d35
提交
07832d35
authored
7月 29, 2021
作者:
Brandon T. Willard
提交者:
Brandon T. Willard
7月 29, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make VM an abstract class and fix its docstrings
上级
83e5f3ef
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
69 行增加
和
76 行删除
+69
-76
vm.py
aesara/link/vm.py
+69
-76
没有找到文件。
aesara/link/vm.py
浏览文件 @
07832d35
...
...
@@ -10,6 +10,7 @@ import platform
import
sys
import
time
import
warnings
from
abc
import
ABC
,
abstractmethod
from
collections
import
defaultdict
from
aesara.configdefaults
import
config
...
...
@@ -121,17 +122,18 @@ def calculate_reallocate_info(order, fgraph, storage_map, compute_map_re, depend
return
reallocated_info
class
VM
:
"""
A VM object's __call__ method evaluates an Aesara program.
class
VM
(
ABC
):
r"""An abstract class for evaluating Aesara programs.
The `VM.__call__` method evaluates an Aesara program.
The Stack should be considered the reference VM/Linker
implementation.
It can correctly evaluate all graphs and is the easiest to read. The
CVM
is a port of
Stack,
and should have the same behavior, but run faster.
The
CVM
's code is harder to read though.
`Stack` should be considered the reference `VM`/`Linker`
implementation.
It can correctly evaluate all graphs and is the easiest to read. The
`CVM`
is a port of
`Stack`
and should have the same behavior, but run faster.
The
`CVM`
's code is harder to read though.
The other python
VMs are maybe
not necessary anymore, and don't take
advantage of lazy computation, though they still produce the correct
The other python
`VM`\s are perhaps
not necessary anymore, and don't take
advantage of lazy computation,
al
though they still produce the correct
output for lazy nodes.
Parameters
...
...
@@ -148,18 +150,18 @@ class VM:
Attributes
----------
call_counts
List of integers, one for each thunk.
call_count[i] is the number of
times thunks[i] was called in the course of computations performed by
call_with_timers()
.
List of integers, one for each thunk.
``call_count[i]`` is the number
of times ``thunks[i]`` was called in the course of computations
performed by `call_with_timers`
.
call_times
List of floats, one for each thunk.
call_times[i]
is the amount of
runtime spent on
thunks[i] in the course of computations performed by
call_with_timers()
.
List of floats, one for each thunk.
``call_times[i]``
is the amount of
runtime spent on
``thunks[i]`` in the course of computations performed
by `call_with_timers`
.
need_update_inputs : bool
True indicates that Function.__call__ must implement the feedback from
output storage to input storage. False means it *must not* repeat that
feedback.
``True`` indicates that `Function.__call__` must implement the feedback
from output storage to input storage. ``False`` means it *must not*
repeat that
feedback.
"""
...
...
@@ -181,31 +183,24 @@ class VM:
# defaults to 0 (aka False).
self
.
need_update_inputs
=
True
@abstractmethod
def
__call__
(
self
):
"""
Run the machine.
Postcondition - all output variables have been computed. VMs vary in
what exactly this means and how it is done.
r"""Run the virtual machine.
After this is executed, all the output variables will have been
computed. `VM`\s may vary regarding what exactly this means and how it
is done.
"""
raise
NotImplementedError
()
def
clear_storage
(
self
):
"""
Free any internal references to temporary variables.
Free internal variables and outputs. Essentially, free as much memory
as possible without intefering with the ability to evaluate subsequent
calls.
"""Free any internal references to temporary variables.
Essentially, free as much memory as possible without interfering with
the ability to evaluate subsequent calls.
"""
raise
NotImplementedError
()
def
update_profile
(
self
,
profile
):
"""
Accumulate into the profile object
"""
"""Update a profile object."""
for
node
,
thunk
,
t
,
c
in
zip
(
self
.
nodes
,
self
.
thunks
,
self
.
call_times
,
self
.
call_counts
):
...
...
@@ -244,7 +239,6 @@ class Loop(VM):
"""
# Some other part of Aesara query that information
allow_gc
=
False
def
__call__
(
self
):
...
...
@@ -271,10 +265,9 @@ class Loop(VM):
class
LoopGC
(
VM
):
"""
Unconditional start-to-finish program execution in Python.
Garbage collection is possible on intermediate results.
"""Unconditional start-to-finish program execution in Python.
Garbage collection is possible on intermediate results.
"""
def
__init__
(
self
,
fgraph
,
nodes
,
thunks
,
pre_call_clear
,
post_thunk_clear
):
...
...
@@ -321,28 +314,30 @@ class LoopGC(VM):
class
Stack
(
VM
):
"""
Finish-to-start evaluation order of thunks.
"""Finish-to-start evaluation order of thunks.
This supports lazy evaluation of subtrees and partial computations of
graphs when only some inputs have changed.
This supports lazy evaluation of subtrees and partial
computations of graphs when only some inputs have changed.
At a pseudo-code level, the basic idea is as follows:
At a pseudo-code level, the basic idea is the following:
.. code-block:: python
def recursively_evaluate(var):
if var is up to date:
return
if var.owner.inputs are up to date:
update var
return
for input in var.owner.u
nputs:
recursively_evaluate(var)
def recursively_evaluate(var):
if var is up to date:
return
if var.owner.inputs are up to date:
update var
return
for input in var.owner.i
nputs:
recursively_evaluate(var)
for output in outputs:
recursively_evaluate(output)
for output in outputs:
recursively_evaluate(output)
The actual logic is more complex to support intermediate
garbage collection, lazily-evaluated nodes, and better speed.
The actual logic is more complex to support intermediate garbage
collection, lazily-evaluated nodes, and better speed.
"""
...
...
@@ -695,38 +690,36 @@ class Stack(VM):
class
VMLinker
(
LocalLinker
):
"""
Class that satisfies the Linker interface by acting as a VM factory.
"""Class that satisfies the `Linker` interface by acting as a `VM` factory.
Parameters
----------
allow_gc
Force the virtual machine to clean up unnecessary
references, in order to allow garbage collection
on
intermediate values during computation of a function.
If None use as default the value of the Aesara flag allow_gc
.
Force the virtual machine to clean up unnecessary
references, in order
to allow garbage collection on intermediate values during computati
on
of a function. If ``None``, use as default the value of the Aesara
flag `allow_gc`
.
use_cloop
Use the C-based virtual machine if possible
callback
A callable object to call after each call to a thunk within
the virtual machine. It will be called with four arguments called
'node', 'thunk', 'storage_map', and 'compute_map'
.
A callable object to call after each call to a thunk within
the virtual
machine. It will be called with four arguments: ``node``, ``thunk``,
``storage_map``, and ``compute_map``
.
callback_input
A callable object to call on each input to the graph
(variables with no owner). This includes constants and shared
variables values. It will be called with two arguments:
'var', 'value'.
A callable object to call on each input to the graph (variables with no
owner). This includes constants and shared variables values. It will
be called with two arguments: ``var``, ``value``.
lazy
Useful only when
use_cloop is False. When lazy is None
, use the
aesara flag vm__lazy value. Then if we have a None (default) we auto
detect if lazy evaluation is needed and use the appropriate
version. If
lazy is True or False
, we force the version used
between
Loop/LoopGC and Stack
.
Useful only when
`use_cloop` is False. When `lazy` is ``None``
, use the
Aesara flag ``vm__lazy`` value. Then if we have a ``None`` (default) we
auto
detect if lazy evaluation is needed and use the appropriate
version. If
`lazy` is ``True`` or ``False``
, we force the version used
between
`Loop`/`LoopGC` and `Stack`
.
c_thunks
If
None or True, don't change the default. If False,
don't compile c
code for the thunks.
If
``None`` or ``True``, don't change the default. If ``False``, don't
compile C
code for the thunks.
allow_partial_eval
If
True, enforces usage of Stack or CVM
, to allow for partial
If
``True``, enforces usage of `Stack` or `CVM`
, to allow for partial
evaluation of functions (calculating a subset of outputs).
"""
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论