Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
36b147ea
提交
36b147ea
authored
8月 16, 2010
作者:
James Bergstra
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
test_pfunc - added unit tests regarding the aliasing of memory
上级
6978e564
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
165 行增加
和
19 行删除
+165
-19
test_pfunc.py
theano/compile/tests/test_pfunc.py
+165
-19
没有找到文件。
theano/compile/tests/test_pfunc.py
浏览文件 @
36b147ea
...
...
@@ -474,10 +474,56 @@ class Test_pfunc(unittest.TestCase):
assert
f
()
==
21
assert
f
()
==
34
def
aliasing_test
(
self
):
A
=
shared
(
numpy
.
zeros
((
2
,
2
)))
B
=
shared
(
numpy
.
zeros
((
2
,
2
)))
def
data_of
(
s
):
"""Return the raw value of a shared variable"""
return
s
.
container
.
storage
[
0
]
class
Test_aliasing_rules
(
unittest
.
TestCase
):
"""
1. Theano manages its own memory space, which typically does not overlap with the memory of
normal python variables that the user uses.
2. shared variables are allocated in this memory space, as are the temporaries used for
Function evalution.
3. Physically, this managed memory space may be spread across the host, on a GPU device(s),
or even on a remote machine.
4. Theano assumes that shared variables are never aliased to one another, and tries to make
it impossible to accidentally alias them.
5. Theano's managed data is constant while Theano Functions are not running and theano
library code is not running.
6. The default behaviour of Function is to return user-space values for outputs, but this
can be overridden (borrow=True) for better performance, in which case the returned value
may be aliased to managed memory, and potentially invalidated by the next Theano Function
call or call to theano library code.
"""
def
shared
(
self
,
x
):
return
tensor
.
shared
(
x
)
def
test_shared_constructor_copies
(
self
):
# shared constructor makes copy
# (rule #2)
orig_a
=
numpy
.
zeros
((
2
,
2
))
A
=
self
.
shared
(
orig_a
)
assert
not
numpy
.
may_share_memory
(
orig_a
,
data_of
(
A
))
# rule #2 reading back from theano-managed memory
assert
not
numpy
.
may_share_memory
(
A
.
value
,
data_of
(
A
))
def
test_potential_output_aliasing_induced_by_updates
(
self
):
A
=
self
.
shared
(
numpy
.
zeros
((
2
,
2
)))
B
=
self
.
shared
(
numpy
.
zeros
((
2
,
2
)))
C
=
numpy
.
zeros
((
2
,
2
))
D
=
tensor
.
dmatrix
()
DD
=
D
+
5
...
...
@@ -485,41 +531,141 @@ class Test_pfunc(unittest.TestCase):
f
=
pfunc
([
D
],
[],
updates
=
[
(
A
,
D
),
(
B
,
D
)
])
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
f
=
pfunc
([
D
],
[],
updates
=
[
(
A
,
D
[:]),
(
B
,
D
)
])
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
f
=
pfunc
([
D
],
[],
updates
=
[
(
A
,
D
+
5
),
(
B
,
D
[:])
])
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
f
=
pfunc
([
D
],
[],
updates
=
[
(
A
,
D
+
5
),
(
B
,
D
)
])
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
f
=
pfunc
([
D
],
DD
,
updates
=
[
(
A
,
DD
[:
1
]),
(
B
,
DD
)
])
R
=
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
A
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
B
)
)
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
A
)
)
f
=
pfunc
([
D
],
DD
,
updates
=
[
(
A
,
DD
[:
1
]),
(
B
,
DD
[:
1
]
*
2
)
])
R
=
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
A
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
B
)
)
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
A
)
)
f
=
pfunc
([
D
],
DD
*
4
,
updates
=
[
(
A
,
DD
[:
1
]
*
3
),
(
B
,
DD
[:
1
]
*
2
)
])
R
=
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
A
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
)
)
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
B
)
)
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
A
)
)
f
=
pfunc
([
D
],
DD
*
4
,
updates
=
[
(
A
,
DD
[:
1
]
*
3
),
(
B
,
DD
[:
1
]
*
3
)
])
R
=
f
(
C
)
assert
not
numpy
.
may_share_memory
(
A
.
value
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
B
.
value
)
assert
not
numpy
.
may_share_memory
(
R
,
A
.
value
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
))
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
B
))
assert
not
numpy
.
may_share_memory
(
R
,
data_of
(
A
))
def
test_no_aliasing_0
(
self
):
# B is a shared variable, A is updated with B's contents
# we need A to be copied to avoid aliasing
A
=
self
.
shared
(
numpy
.
zeros
((
2
,
2
))
+.
5
)
B
=
self
.
shared
(
numpy
.
zeros
((
2
,
2
))
-.
5
)
f
=
pfunc
([],
[],
updates
=
[(
A
,
B
)])
f
()
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
))
def
test_no_aliasing_1
(
self
):
# B is a shared variable, A is updated with B's contents
# since B is being updated as well, we don't need to copy anything to avoid aliasing
# shared variables.
A
=
self
.
shared
(
numpy
.
zeros
((
2
,
2
))
+.
5
)
B
=
self
.
shared
(
numpy
.
zeros
((
2
,
2
))
-.
5
)
C
=
tensor
.
dmatrix
()
f
=
pfunc
([
C
],
[],
updates
=
[
(
A
,
B
),
(
B
,
C
)
])
z
=
numpy
.
zeros
((
2
,
2
))
f
(
z
)
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
))
assert
not
numpy
.
may_share_memory
(
z
,
data_of
(
B
))
# Theano tries to maintain its own memory space.
assert
numpy
.
all
(
data_of
(
B
)
==
z
)
def
test_no_aliasing_2
(
self
):
# B and A take one another's values
# no copying is necessary since each one is updated.
orig_a
=
numpy
.
zeros
((
2
,
2
))
+.
5
orig_b
=
numpy
.
zeros
((
2
,
2
))
-.
5
A
=
self
.
shared
(
orig_a
)
B
=
self
.
shared
(
orig_b
)
C
=
tensor
.
dmatrix
()
z
=
numpy
.
zeros
((
2
,
2
))
data_of_a
=
data_of
(
A
)
data_of_b
=
data_of
(
B
)
f
=
pfunc
([
C
],
[],
updates
=
[(
A
,
B
),(
B
,
A
)])
f
(
z
)
# correctness
assert
numpy
.
all
(
data_of
(
A
)
==
-.
5
)
assert
numpy
.
all
(
data_of
(
B
)
==
+.
5
)
# shared vars may not be aliased
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
))
# theano should have been smart enough to not make copies
assert
numpy
.
may_share_memory
(
data_of
(
A
),
data_of_b
)
assert
numpy
.
may_share_memory
(
data_of
(
B
),
data_of_a
)
def
test_no_aliasing_2b
(
self
):
# B and A take one another's values
# no copying is necessary since each one is updated.
# The twist one `test_no_aliasing_2` is that each shared var is updated with a view of
# the other one.
orig_a
=
numpy
.
zeros
((
2
,
2
))
+.
5
orig_b
=
numpy
.
zeros
((
2
,
2
))
-.
5
A
=
self
.
shared
(
orig_a
)
B
=
self
.
shared
(
orig_b
)
C
=
tensor
.
dmatrix
()
z
=
numpy
.
zeros
((
2
,
2
))
data_of_a
=
data_of
(
A
)
data_of_b
=
data_of
(
B
)
f
=
pfunc
([
C
],
[],
updates
=
[(
A
,
B
[:,::
-
1
]),(
B
,
A
.
T
)])
theano
.
printing
.
debugprint
(
f
)
f
(
z
)
# correctness (doesn't actually test the view...)
assert
numpy
.
all
(
data_of
(
A
)
==
-.
5
)
assert
numpy
.
all
(
data_of
(
B
)
==
+.
5
)
# shared vars may not be aliased
assert
not
numpy
.
may_share_memory
(
data_of
(
A
),
data_of
(
B
))
# theano should have been smart enough to not make copies
assert
numpy
.
all
(
data_of
(
A
)
<
5
)
data_of_b
+=
10
assert
numpy
.
all
(
data_of
(
A
)
>
5
)
data_of_b
-=
10
assert
numpy
.
all
(
data_of
(
B
)
<
5
)
data_of_a
+=
10
print
data_of
(
B
)
assert
numpy
.
all
(
data_of
(
B
)
>
5
)
data_of_a
-=
10
# N.B. may_share_memory is what we mean, but does it work?
assert
numpy
.
may_share_memory
(
data_of
(
A
),
data_of_b
)
assert
numpy
.
may_share_memory
(
data_of
(
B
),
data_of_a
)
# N.B. This pattern could form a memory leak - each shared variable always points to a
# view, and that view gets further and further from the (e.g. data_of_a) with each
# call. The memory leak is in the increasing number of view objects forming a chain to
# the underlying data.
if
__name__
==
'__main__'
:
theano
.
config
.
mode
=
'FAST_COMPILE'
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论