Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
8016537c
提交
8016537c
authored
3月 23, 2009
作者:
James Bergstra
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
added check_py_code option to DebugMode, c tests for erroneous destroy_map and view_map
上级
571c92bb
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
151 行增加
和
23 行删除
+151
-23
debugmode.py
theano/compile/debugmode.py
+39
-23
test_debugmode.py
theano/compile/tests/test_debugmode.py
+112
-0
没有找到文件。
theano/compile/debugmode.py
浏览文件 @
8016537c
...
@@ -620,13 +620,16 @@ class _Linker(gof.link.LocalLinker):
...
@@ -620,13 +620,16 @@ class _Linker(gof.link.LocalLinker):
except
(
NotImplementedError
,
utils
.
MethodNotDefined
):
except
(
NotImplementedError
,
utils
.
MethodNotDefined
):
thunks_c
.
append
(
None
)
thunks_c
.
append
(
None
)
p
=
node
.
op
.
perform
if
self
.
maker
.
mode
.
check_py_code
:
thunk
=
(
lambda
p
=
p
,
i
=
node_input_storage
,
o
=
node_output_storage
,
n
=
p
=
node
.
op
.
perform
node
:
p
(
n
,
[
x
[
0
]
for
x
in
i
],
o
))
thunk
=
(
lambda
p
=
p
,
i
=
node_input_storage
,
o
=
node_output_storage
,
n
=
thunk
.
inputs
=
node_input_storage
node
:
p
(
n
,
[
x
[
0
]
for
x
in
i
],
o
))
thunk
.
outputs
=
node_output_storage
thunk
.
inputs
=
node_input_storage
thunk
.
perform
=
p
thunk
.
outputs
=
node_output_storage
thunks_py
.
append
(
thunk
)
thunk
.
perform
=
p
thunks_py
.
append
(
thunk
)
else
:
thunks_py
.
append
(
None
)
if
no_recycling
is
True
:
if
no_recycling
is
True
:
no_recycling
=
storage_map
.
values
()
no_recycling
=
storage_map
.
values
()
...
@@ -675,6 +678,7 @@ class _Linker(gof.link.LocalLinker):
...
@@ -675,6 +678,7 @@ class _Linker(gof.link.LocalLinker):
this_node_destroyed_variables
=
set
()
this_node_destroyed_variables
=
set
()
# put a copy of each input into the storage_map
# put a copy of each input into the storage_map
# also, check that inputs have valid values
for
r
in
node
.
inputs
:
for
r
in
node
.
inputs
:
assert
isinstance
(
r
,
gof
.
Variable
)
assert
isinstance
(
r
,
gof
.
Variable
)
assert
r
in
r_vals
assert
r
in
r_vals
...
@@ -682,20 +686,22 @@ class _Linker(gof.link.LocalLinker):
...
@@ -682,20 +686,22 @@ class _Linker(gof.link.LocalLinker):
if
not
r
.
type
.
is_valid_value
(
storage_map
[
r
][
0
]):
if
not
r
.
type
.
is_valid_value
(
storage_map
[
r
][
0
]):
raise
InvalidValueError
(
r
,
storage_map
[
r
][
0
])
raise
InvalidValueError
(
r
,
storage_map
[
r
][
0
])
thunk_py
()
if
thunk_py
:
thunk_py
()
_check_inputs
(
node
,
storage_map
,
r_vals
,
dr_vals
,
active_order_set
,
_check_inputs
(
node
,
storage_map
,
r_vals
,
dr_vals
,
active_order_set
,
clobber_dr_vals
=
True
)
clobber_dr_vals
=
True
)
#retrieve each output from the storage_map
# check output values for type-correctness
for
r
in
node
.
outputs
:
#retrieve each output from the storage_map
if
not
r
.
type
.
is_valid_value
(
storage_map
[
r
][
0
]):
for
r
in
node
.
outputs
:
raise
InvalidValueError
(
r
,
storage_map
[
r
][
0
])
if
not
r
.
type
.
is_valid_value
(
storage_map
[
r
][
0
]):
if
r
in
r_vals
:
raise
InvalidValueError
(
r
,
storage_map
[
r
][
0
])
print
>>
sys
.
stderr
,
'OUTPUT'
,
r
,
'ALREADY HAS_VALUE!'
,
r_vals
[
r
],
'WHAT ABOUT'
,
storage_map
[
r
][
0
]
#if r in r_vals:
assert
r
not
in
r_vals
#print >> sys.stderr, 'OUTPUT', r, 'ALREADY HAS_VALUE!', r_vals[r], 'WHAT ABOUT', storage_map[r][0]
r_vals
[
r
]
=
storage_map
[
r
][
0
]
assert
r
not
in
r_vals
storage_map
[
r
][
0
]
=
None
#clear the storage_map for the thunk_c
r_vals
[
r
]
=
storage_map
[
r
][
0
]
storage_map
[
r
][
0
]
=
None
#clear the storage_map of outputs for the thunk_c
if
thunk_c
:
if
thunk_c
:
...
@@ -709,12 +715,18 @@ class _Linker(gof.link.LocalLinker):
...
@@ -709,12 +715,18 @@ class _Linker(gof.link.LocalLinker):
clobber_dr_vals
=
False
)
clobber_dr_vals
=
False
)
for
r
in
node
.
outputs
:
for
r
in
node
.
outputs
:
# check output values for type-correctness
if
not
r
.
type
.
is_valid_value
(
storage_map
[
r
][
0
]):
if
not
r
.
type
.
is_valid_value
(
storage_map
[
r
][
0
]):
raise
InvalidValueError
(
r
,
storage_map
[
r
][
0
])
raise
InvalidValueError
(
r
,
storage_map
[
r
][
0
])
# compares the version from thunk_py (in r_vals)
# to the version produced by thunk_c (in storage_map)
if
r
in
r_vals
:
if
not
r
.
type
.
values_eq_approx
(
r_vals
[
r
],
storage_map
[
r
][
0
]):
# compares the version from thunk_py (in r_vals)
raise
BadClinkerOutput
(
r
,
val_py
=
r_vals
[
r
],
val_c
=
storage_map
[
r
][
0
])
# to the version produced by thunk_c (in storage_map)
if
not
r
.
type
.
values_eq_approx
(
r_vals
[
r
],
storage_map
[
r
][
0
]):
raise
BadClinkerOutput
(
r
,
val_py
=
r_vals
[
r
],
val_c
=
storage_map
[
r
][
0
])
else
:
#retrieve each output from the storage_map
r_vals
[
r
]
=
storage_map
[
r
][
0
]
storage_map
[
r
][
0
]
=
None
#clear the storage_map for the thunk_c
storage_map
[
r
][
0
]
=
None
#clear the storage_map for the thunk_c
# we're done with this thunk
# we're done with this thunk
...
@@ -1013,14 +1025,18 @@ class DebugMode(Mode):
...
@@ -1013,14 +1025,18 @@ class DebugMode(Mode):
optimizer
=
'fast_run'
,
optimizer
=
'fast_run'
,
stability_patience
=
10
,
stability_patience
=
10
,
check_c_code
=
True
,
check_c_code
=
True
,
check_py_code
=
True
,
diagnostic
=
sys
.
stderr
):
diagnostic
=
sys
.
stderr
):
"""Initialize member variables
"""Initialize member variables
"""
"""
if
not
(
check_c_code
or
check_py_code
):
raise
ValueError
(
'DebugMode has to check at least one of c and py code'
)
super
(
DebugMode
,
self
)
.
__init__
(
super
(
DebugMode
,
self
)
.
__init__
(
optimizer
=
optimizer
,
optimizer
=
optimizer
,
linker
=
_Linker
)
linker
=
_Linker
)
self
.
stability_patience
=
stability_patience
self
.
stability_patience
=
stability_patience
self
.
check_c_code
=
check_c_code
self
.
check_c_code
=
check_c_code
self
.
check_py_code
=
check_py_code
self
.
diagnostic
=
diagnostic
self
.
diagnostic
=
diagnostic
register_mode
(
'DEBUG_MODE'
,
DebugMode
(
optimizer
=
'fast_run'
))
register_mode
(
'DEBUG_MODE'
,
DebugMode
(
optimizer
=
'fast_run'
))
theano/compile/tests/test_debugmode.py
浏览文件 @
8016537c
...
@@ -149,6 +149,95 @@ inconsistent = BROKEN_ON_PURPOSE_StructuredDotCSC(False)
...
@@ -149,6 +149,95 @@ inconsistent = BROKEN_ON_PURPOSE_StructuredDotCSC(False)
# off_by_half is a good op, that is different from theano.sparse.sd_csc
# off_by_half is a good op, that is different from theano.sparse.sd_csc
off_by_half
=
BROKEN_ON_PURPOSE_StructuredDotCSC
(
True
)
off_by_half
=
BROKEN_ON_PURPOSE_StructuredDotCSC
(
True
)
class
WeirdBrokenOp
(
gof
.
Op
):
"""
This op can be inplace if behaviour is times1_inplace
This op can be destructive if behaviour is times2_inplace
In both cases, it does not set the destroy_map or view_map correctly so it should raise an
error in DebugMode.
"""
def
__init__
(
self
,
behaviour
):
gof
.
Op
.
__init__
(
self
)
self
.
behaviour
=
behaviour
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
and
(
self
.
behaviour
==
other
.
behaviour
)
def
__hash__
(
self
):
return
hash
(
type
(
self
))
^
hash
(
self
.
behaviour
)
def
make_node
(
self
,
a
):
a_
=
theano
.
tensor
.
as_tensor_variable
(
a
)
r
=
gof
.
Apply
(
self
,
[
a_
],
[
a_
.
type
()])
return
r
def
dontuse_perform
(
self
,
node
,
(
a
,),
(
out
,)):
if
self
.
behaviour
==
'times2'
:
out
[
0
]
=
a
*
2
elif
self
.
behaviour
==
'times2_inplace'
:
out
[
0
]
=
a
out
[
0
]
*=
2
elif
self
.
behaviour
==
'times1'
:
out
[
0
]
=
a
*
1
elif
self
.
behaviour
==
'times1_inplace'
:
out
[
0
]
=
a
else
:
raise
ValueError
(
self
.
behaviour
)
def
c_code
(
self
,
node
,
name
,
(
a
,),
(
z
,),
sub
):
if
"inplace"
in
self
.
behaviour
:
z_code
=
"""
if (
%(z)
s) Py_DECREF(
%(z)
s);
Py_INCREF(
%(a)
s);
%(z)
s =
%(a)
s;
"""
else
:
z_code
=
"""
if (
%(z)
s) Py_DECREF(
%(z)
s);
%(z)
s = (PyArrayObject*) PyArray_SimpleNew(1,
%(a)
s->dimensions,
%(a)
s->descr->type_num);
"""
prep_vars
=
"""
//the output array has size M x N
npy_intp M =
%(a)
s->dimensions[0];
npy_intp Sa =
%(a)
s->strides[0] /
%(a)
s->descr->elsize;
npy_intp Sz =
%(z)
s->strides[0] /
%(z)
s->descr->elsize;
npy_double * Da = (npy_double*)
%(a)
s->data;
npy_double * Dz = (npy_double*)
%(z)
s->data;
//clear the output array
for (npy_intp m = 0; m < M; ++m)
{
"""
if
self
.
behaviour
==
'times2'
:
behaviour
=
" Dz[m * Sz] = 2 * Da[m * Sa]; "
#out[0] = a * 2
elif
self
.
behaviour
==
'times2_inplace'
:
#out[0] = a
#out[0] *= 2
behaviour
=
" Dz[m * Sz] = 2 * Da[m * Sa]; "
elif
self
.
behaviour
==
'times1'
:
#out[0] = a * 1
behaviour
=
" Dz[m * Sz] = Da[m * Sa]; "
elif
self
.
behaviour
==
'times1_inplace'
:
#out[0] = a
behaviour
=
""
else
:
raise
ValueError
(
self
.
behaviour
)
prep_vars2
=
"""
}
"""
total
=
(
z_code
+
prep_vars
+
behaviour
+
prep_vars2
)
%
dict
(
locals
(),
**
sub
)
return
total
wb2i
=
WeirdBrokenOp
(
'times2_inplace'
)
wb2
=
WeirdBrokenOp
(
'times2'
)
wb1i
=
WeirdBrokenOp
(
'times1_inplace'
)
wb1
=
WeirdBrokenOp
(
'times1'
)
def
test_badclinkeroutput
():
def
test_badclinkeroutput
():
...
@@ -219,6 +308,10 @@ def test_badoptimization():
...
@@ -219,6 +308,10 @@ def test_badoptimization():
assert
False
assert
False
def
test_just_c_code
():
x
=
theano
.
tensor
.
dvector
()
f
=
theano
.
function
([
x
],
wb2
(
x
),
mode
=
debugmode
.
DebugMode
(
check_py_code
=
False
))
assert
numpy
.
all
(
f
([
1
,
2
])
==
[
2
,
4
])
def
test_baddestroymap
():
def
test_baddestroymap
():
class
BadAdd
(
gof
.
Op
):
class
BadAdd
(
gof
.
Op
):
...
@@ -239,6 +332,16 @@ def test_baddestroymap():
...
@@ -239,6 +332,16 @@ def test_baddestroymap():
except
debugmode
.
BadDestroyMap
:
except
debugmode
.
BadDestroyMap
:
return
return
def
test_baddestroymap_c
():
x
=
theano
.
tensor
.
dvector
()
f
=
theano
.
function
([
x
],
wb2i
(
x
),
mode
=
debugmode
.
DebugMode
(
check_py_code
=
False
))
try
:
assert
numpy
.
all
(
f
([
1
,
2
])
==
[
2
,
4
])
assert
False
#failed to raise error
except
debugmode
.
BadDestroyMap
:
pass
def
test_badviewmap
():
def
test_badviewmap
():
class
BadAdd
(
gof
.
Op
):
class
BadAdd
(
gof
.
Op
):
def
make_node
(
self
,
a
,
b
):
def
make_node
(
self
,
a
,
b
):
...
@@ -256,3 +359,12 @@ def test_badviewmap():
...
@@ -256,3 +359,12 @@ def test_badviewmap():
assert
False
#failed to raise error
assert
False
#failed to raise error
except
debugmode
.
BadViewMap
:
except
debugmode
.
BadViewMap
:
return
return
def
test_badviewmap_c
():
x
=
theano
.
tensor
.
dvector
()
f
=
theano
.
function
([
x
],
wb1i
(
x
),
mode
=
debugmode
.
DebugMode
(
check_py_code
=
False
))
try
:
f
([
1
,
2
])
assert
False
#failed to raise error
except
debugmode
.
BadDestroyMap
:
pass
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论