Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
d4e7e4f1
提交
d4e7e4f1
authored
10月 03, 2014
作者:
Li
提交者:
Frederic
10月 21, 2014
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
support: no need to re-optmize when unpickling theano function. added a new…
support: no need to re-optmize when unpickling theano function. added a new option reoptimize_unpickled_function=False
上级
54bc8d12
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
132 行增加
和
105 行删除
+132
-105
function_module.py
theano/compile/function_module.py
+123
-103
configdefaults.py
theano/configdefaults.py
+7
-0
test_pickle.py
theano/tests/test_pickle.py
+2
-2
没有找到文件。
theano/compile/function_module.py
浏览文件 @
d4e7e4f1
...
@@ -703,6 +703,7 @@ class Function(object):
...
@@ -703,6 +703,7 @@ class Function(object):
# pickling/deepcopy support for Function
# pickling/deepcopy support for Function
def
_pickle_Function
(
f
):
def
_pickle_Function
(
f
):
print
'pickling Function..'
#copy of the input storage list
#copy of the input storage list
ins
=
list
(
f
.
input_storage
)
ins
=
list
(
f
.
input_storage
)
input_storage
=
[]
input_storage
=
[]
...
@@ -736,11 +737,11 @@ def _pickle_Function(f):
...
@@ -736,11 +737,11 @@ def _pickle_Function(f):
' operation'
)
%
(
str
(
d_i
),
str
(
d_j
)))
' operation'
)
%
(
str
(
d_i
),
str
(
d_j
)))
else
:
else
:
raise
AliasedMemoryError
(
d_i
,
d_j
)
raise
AliasedMemoryError
(
d_i
,
d_j
)
rval
=
(
_constructor_Function
,
(
f
.
maker
,
input_storage
,
inputs_data
))
rval
=
(
_constructor_Function
,
(
f
.
maker
,
input_storage
,
inputs_data
))
return
rval
return
rval
def
_constructor_Function
(
maker
,
input_storage
,
inputs_data
):
def
_constructor_Function
(
maker
,
input_storage
,
inputs_data
):
print
'unpickling Function...'
if
not
theano
.
config
.
unpickle_function
:
if
not
theano
.
config
.
unpickle_function
:
return
None
return
None
f
=
maker
.
create
(
input_storage
,
trustme
=
True
)
f
=
maker
.
create
(
input_storage
,
trustme
=
True
)
...
@@ -970,103 +971,9 @@ class FunctionMaker(object):
...
@@ -970,103 +971,9 @@ class FunctionMaker(object):
else
:
else
:
raise
TypeError
(
"Unknown output type:
%
s (
%
s)"
,
type
(
output
),
output
)
raise
TypeError
(
"Unknown output type:
%
s (
%
s)"
,
type
(
output
),
output
)
def
__init__
(
self
,
inputs
,
outputs
,
def
retrieve_fgraph_from_opt_cache
():
mode
=
None
,
accept_inplace
=
False
,
function_builder
=
Function
,
# This function is not finished
profile
=
None
,
on_unused_input
=
None
):
raise
NotImplementedError
(
'optimization cache is not finished! Should not be called.'
)
"""
:type inputs: a list of SymbolicInput instances
:type outputs: a list of SymbolicOutput instances
outputs may also be a single Variable (not a list), in which
case the functions produced by FunctionMaker will return
their output value directly
:param mode: a Mode instance telling FunctionMaker how to optimize and link. None
means to use the `config.mode`.
:param accept_inplace: True iff it is acceptable to have inplace operations
in the graph from the inputs to the outputs
:param on_unused_input: What to do if a variable in the 'inputs' list
is not used in the graph. Possible values are:
- 'raise': raise an error
- 'warn': log a warning
- 'ignore': do not do anything
- None: Use the value in the Theano flags on_unused_input
"""
mode
=
theano
.
compile
.
mode
.
get_mode
(
mode
)
# figure out which profile object to use (if any)
# to help with forward-porting ProfileMode,
# we allow ProfileMode to provide a ProfileStats object
# using this somewhat awkward mechanism.
mode_profile
=
getattr
(
mode
,
'profile'
,
None
)
if
(
profile
is
not
None
and
profile
is
not
False
and
mode_profile
is
not
None
):
raise
TypeError
(
'profile passed via both "mode" and "profile" arguments'
)
self
.
profile
=
profile
=
profile
or
mode_profile
if
profile
or
theano
.
config
.
cxx
:
# This is very important:
# 1) We preload the cache here to don't have its timming
# included in optimization that compile function.
# 2) If other repo that import Theano have Theano ops defined,
# we need to refresh the cache here. Otherwise, their is import
# order problems.
# When device=gpu, we compile during Theano import. This trigger
# the loading of the cache. But unpickling the cache ask that the
# other repos Ops are completly loaded, which isn't always the
# case!
# If a module isn't completly loaded and their unpickling fail,
# it mean it is safe for this function compilation to skip them,
# but not for futur compilation. So reloading the cache at each
# compilation fix this problem.
# 3) This help propagate knowledge of newly compiled module to
# concurrent process.
theano
.
gof
.
cc
.
get_module_cache
()
.
refresh
()
# Handle the case where inputs and/or outputs is a single Variable (not in a list)
self
.
orig_outputs
=
outputs
unpack_single
=
False
return_none
=
False
if
outputs
is
None
:
return_none
=
True
outputs
=
[]
if
not
isinstance
(
outputs
,
(
list
,
tuple
)):
unpack_single
=
True
outputs
=
[
outputs
]
if
not
isinstance
(
inputs
,
(
list
,
tuple
)):
inputs
=
[
inputs
]
# Wrap them in In or Out instances if needed.
#import pudb; pudb.set_trace()
inputs
,
outputs
=
map
(
self
.
wrap_in
,
inputs
),
map
(
self
.
wrap_out
,
outputs
)
_inputs
=
gof
.
graph
.
inputs
([
o
.
variable
for
o
in
outputs
]
+
[
i
.
update
for
i
in
inputs
if
getattr
(
i
,
'update'
,
False
)])
# Check if some input variables are unused
self
.
_check_unused_inputs
(
inputs
,
outputs
,
on_unused_input
)
# Make a list of (SymbolicInput|SymblicInputKits, indices, [SymbolicInput,...]), one
# tuple for each input. (See Function.indices for more details)
indices
=
[[
input
]
+
self
.
expand_in
(
input
,
_inputs
)
for
input
in
inputs
]
# make the fgraph (copies the graph, creates NEW INPUT AND OUTPUT VARIABLES)
fgraph
,
additional_outputs
=
std_fgraph
(
inputs
,
outputs
,
accept_inplace
)
fgraph
.
profile
=
profile
self
.
fgraph
=
fgraph
# Fetch the optimizer and linker
optimizer
,
linker
=
mode
.
optimizer
,
copy
.
copy
(
mode
.
linker
)
# optimize the fgraph
compute_test_value_orig
=
theano
.
config
.
compute_test_value
add_stack_trace_on_call
=
gof
.
Op
.
add_stack_trace_on_call
try
:
theano
.
config
.
compute_test_value
=
theano
.
config
.
compute_test_value_opt
gof
.
Op
.
add_stack_trace_on_call
=
False
from
theano.gof.compilelock
import
get_lock
,
release_lock
from
theano.gof.compilelock
import
get_lock
,
release_lock
import
os.path
import
os.path
graph_db_file
=
os
.
path
.
join
(
theano
.
config
.
compiledir
,
'optimized_graphs.pkl'
)
graph_db_file
=
os
.
path
.
join
(
theano
.
config
.
compiledir
,
'optimized_graphs.pkl'
)
...
@@ -1203,8 +1110,6 @@ class FunctionMaker(object):
...
@@ -1203,8 +1110,6 @@ class FunctionMaker(object):
need_optimize
=
False
need_optimize
=
False
key
=
graph_old
key
=
graph_old
break
break
# now optimize or not
if
need_optimize
:
if
need_optimize
:
# this is a brand new graph, optimize it, save it to graph_db
# this is a brand new graph, optimize it, save it to graph_db
print
'optimizing the graph'
print
'optimizing the graph'
...
@@ -1235,15 +1140,119 @@ class FunctionMaker(object):
...
@@ -1235,15 +1140,119 @@ class FunctionMaker(object):
# release stuff
# release stuff
release_lock
()
release_lock
()
#end of cache optimization
#else containing the old code
def
__init__
(
self
,
inputs
,
outputs
,
mode
=
None
,
accept_inplace
=
False
,
function_builder
=
Function
,
profile
=
None
,
on_unused_input
=
None
,
fgraph
=
None
):
"""
:type inputs: a list of SymbolicInput instances
:type outputs: a list of SymbolicOutput instances
outputs may also be a single Variable (not a list), in which
case the functions produced by FunctionMaker will return
their output value directly
:param mode: a Mode instance telling FunctionMaker how to optimize and link. None
means to use the `config.mode`.
:param accept_inplace: True iff it is acceptable to have inplace operations
in the graph from the inputs to the outputs
:param on_unused_input: What to do if a variable in the 'inputs' list
is not used in the graph. Possible values are:
- 'raise': raise an error
- 'warn': log a warning
- 'ignore': do not do anything
- None: Use the value in the Theano flags on_unused_input
"""
mode
=
theano
.
compile
.
mode
.
get_mode
(
mode
)
# figure out which profile object to use (if any)
# to help with forward-porting ProfileMode,
# we allow ProfileMode to provide a ProfileStats object
# using this somewhat awkward mechanism.
mode_profile
=
getattr
(
mode
,
'profile'
,
None
)
if
(
profile
is
not
None
and
profile
is
not
False
and
mode_profile
is
not
None
):
raise
TypeError
(
'profile passed via both "mode" and "profile" arguments'
)
self
.
profile
=
profile
=
profile
or
mode_profile
if
profile
or
theano
.
config
.
cxx
:
# This is very important:
# 1) We preload the cache here to don't have its timming
# included in optimization that compile function.
# 2) If other repo that import Theano have Theano ops defined,
# we need to refresh the cache here. Otherwise, their is import
# order problems.
# When device=gpu, we compile during Theano import. This trigger
# the loading of the cache. But unpickling the cache ask that the
# other repos Ops are completly loaded, which isn't always the
# case!
# If a module isn't completly loaded and their unpickling fail,
# it mean it is safe for this function compilation to skip them,
# but not for futur compilation. So reloading the cache at each
# compilation fix this problem.
# 3) This help propagate knowledge of newly compiled module to
# concurrent process.
theano
.
gof
.
cc
.
get_module_cache
()
.
refresh
()
# Handle the case where inputs and/or outputs is a single Variable (not in a list)
self
.
orig_outputs
=
outputs
unpack_single
=
False
return_none
=
False
if
outputs
is
None
:
return_none
=
True
outputs
=
[]
if
not
isinstance
(
outputs
,
(
list
,
tuple
)):
unpack_single
=
True
outputs
=
[
outputs
]
if
not
isinstance
(
inputs
,
(
list
,
tuple
)):
inputs
=
[
inputs
]
# Wrap them in In or Out instances if needed.
inputs
,
outputs
=
map
(
self
.
wrap_in
,
inputs
),
map
(
self
.
wrap_out
,
outputs
)
_inputs
=
gof
.
graph
.
inputs
([
o
.
variable
for
o
in
outputs
]
+
[
i
.
update
for
i
in
inputs
if
getattr
(
i
,
'update'
,
False
)])
# Check if some input variables are unused
self
.
_check_unused_inputs
(
inputs
,
outputs
,
on_unused_input
)
# Make a list of (SymbolicInput|SymblicInputKits, indices, [SymbolicInput,...]), one
# tuple for each input. (See Function.indices for more details)
indices
=
[[
input
]
+
self
.
expand_in
(
input
,
_inputs
)
for
input
in
inputs
]
if
fgraph
is
None
:
need_opt
=
True
else
:
need_opt
=
False
if
fgraph
is
None
:
# make the fgraph (copies the graph, creates NEW INPUT AND OUTPUT VARIABLES)
fgraph
,
additional_outputs
=
std_fgraph
(
inputs
,
outputs
,
accept_inplace
)
fgraph
.
profile
=
profile
else
:
else
:
# fgraph is already an optimized one
_
,
additional_outputs
=
std_fgraph
(
inputs
,
outputs
,
accept_inplace
)
pass
self
.
fgraph
=
fgraph
# Fetch the optimizer and linker
optimizer
,
linker
=
mode
.
optimizer
,
copy
.
copy
(
mode
.
linker
)
compute_test_value_orig
=
theano
.
config
.
compute_test_value
add_stack_trace_on_call
=
gof
.
Op
.
add_stack_trace_on_call
if
need_opt
:
# optimize the fgraph
print
'fgraph is optimized'
try
:
theano
.
config
.
compute_test_value
=
theano
.
config
.
compute_test_value_opt
gof
.
Op
.
add_stack_trace_on_call
=
False
start_optimizer
=
time
.
time
()
start_optimizer
=
time
.
time
()
optimizer_profile
=
optimizer
(
fgraph
)
optimizer_profile
=
optimizer
(
fgraph
)
end_optimizer
=
time
.
time
()
end_optimizer
=
time
.
time
()
opt_time
=
end_optimizer
-
start_optimizer
opt_time
=
end_optimizer
-
start_optimizer
#print 'opt took %s' % opt_time
if
profile
:
if
profile
:
profile
.
optimizer_time
+=
opt_time
profile
.
optimizer_time
+=
opt_time
if
theano
.
config
.
profile_optimizer
:
if
theano
.
config
.
profile_optimizer
:
...
@@ -1256,6 +1265,12 @@ class FunctionMaker(object):
...
@@ -1256,6 +1265,12 @@ class FunctionMaker(object):
theano
.
config
.
compute_test_value
=
compute_test_value_orig
theano
.
config
.
compute_test_value
=
compute_test_value_orig
gof
.
Op
.
add_stack_trace_on_call
=
add_stack_trace_on_call
gof
.
Op
.
add_stack_trace_on_call
=
add_stack_trace_on_call
else
:
# fgraph is already optimized
print
'fgraph is not optimized'
theano
.
config
.
compute_test_value
=
compute_test_value_orig
gof
.
Op
.
add_stack_trace_on_call
=
add_stack_trace_on_call
# initialize the linker
# initialize the linker
if
not
hasattr
(
linker
,
'accept'
):
if
not
hasattr
(
linker
,
'accept'
):
raise
ValueError
(
"'linker' parameter of FunctionMaker should be a Linker with an accept method "
\
raise
ValueError
(
"'linker' parameter of FunctionMaker should be a Linker with an accept method "
\
...
@@ -1415,9 +1430,11 @@ class FunctionMaker(object):
...
@@ -1415,9 +1430,11 @@ class FunctionMaker(object):
def
_pickle_FunctionMaker
(
self
):
def
_pickle_FunctionMaker
(
self
):
'picking FunctionMaker'
kwargs
=
dict
(
kwargs
=
dict
(
inputs
=
self
.
inputs
,
inputs
=
self
.
inputs
,
outputs
=
self
.
orig_outputs
,
outputs
=
self
.
orig_outputs
,
fgraph
=
self
.
fgraph
,
mode
=
self
.
mode
,
mode
=
self
.
mode
,
accept_inplace
=
self
.
accept_inplace
,
accept_inplace
=
self
.
accept_inplace
,
function_builder
=
self
.
function_builder
,
function_builder
=
self
.
function_builder
,
...
@@ -1428,7 +1445,10 @@ def _pickle_FunctionMaker(self):
...
@@ -1428,7 +1445,10 @@ def _pickle_FunctionMaker(self):
def
_constructor_FunctionMaker
(
kwargs
):
def
_constructor_FunctionMaker
(
kwargs
):
print
'unpickling FunctionMaker...'
if
theano
.
config
.
unpickle_function
:
if
theano
.
config
.
unpickle_function
:
if
theano
.
config
.
reoptimize_unpickled_function
:
del
kwargs
[
'fgraph'
]
return
FunctionMaker
(
**
kwargs
)
return
FunctionMaker
(
**
kwargs
)
else
:
else
:
return
None
return
None
...
...
theano/configdefaults.py
浏览文件 @
d4e7e4f1
...
@@ -118,6 +118,7 @@ AddConfigVar('print_active_device',
...
@@ -118,6 +118,7 @@ AddConfigVar('print_active_device',
BoolParam
(
True
,
allow_override
=
False
),
BoolParam
(
True
,
allow_override
=
False
),
in_c_key
=
False
)
in_c_key
=
False
)
# Do not add FAST_RUN_NOGC to this list (nor any other ALL CAPS shortcut).
# Do not add FAST_RUN_NOGC to this list (nor any other ALL CAPS shortcut).
# The way to get FAST_RUN_NOGC is with the flag 'linker=c|py_nogc'.
# The way to get FAST_RUN_NOGC is with the flag 'linker=c|py_nogc'.
# The old all capital letter way of working is deprecated as it is not
# The old all capital letter way of working is deprecated as it is not
...
@@ -465,6 +466,12 @@ AddConfigVar('unpickle_function',
...
@@ -465,6 +466,12 @@ AddConfigVar('unpickle_function',
BoolParam
(
True
),
BoolParam
(
True
),
in_c_key
=
False
)
in_c_key
=
False
)
AddConfigVar
(
'reoptimize_unpickled_function'
,
"Re-optimize the graph when a theano function is unpickled from the disk."
,
BoolParam
(
False
,
allow_override
=
False
),
in_c_key
=
False
)
"""Note to developers:
"""Note to developers:
Generally your exceptions should use an apply node's __str__
Generally your exceptions should use an apply node's __str__
method when exception_verbosity == 'low'. When exception_verbosity
method when exception_verbosity == 'low'. When exception_verbosity
...
...
theano/tests/test_pickle.py
浏览文件 @
d4e7e4f1
...
@@ -8,7 +8,7 @@ floatX = 'float32'
...
@@ -8,7 +8,7 @@ floatX = 'float32'
def
test_pickle_unpickle
():
def
test_pickle_unpickle
():
# Test if pick and unpickling a theano function with
# Test if pick and unpickling a theano function with
# shared variables
work
# shared variables
should be pickled properly
x1
=
T
.
fmatrix
(
'x1'
)
x1
=
T
.
fmatrix
(
'x1'
)
x2
=
T
.
fmatrix
(
'x2'
)
x2
=
T
.
fmatrix
(
'x2'
)
x3
=
theano
.
shared
(
numpy
.
ones
((
10
,
10
),
dtype
=
floatX
))
x3
=
theano
.
shared
(
numpy
.
ones
((
10
,
10
),
dtype
=
floatX
))
...
@@ -24,7 +24,7 @@ def test_pickle_unpickle():
...
@@ -24,7 +24,7 @@ def test_pickle_unpickle():
cPickle
.
dump
(
f
,
pkl_path
,
-
1
)
cPickle
.
dump
(
f
,
pkl_path
,
-
1
)
pkl_path
=
open
(
'thean_fn.pkl'
,
'r'
)
pkl_path
=
open
(
'thean_fn.pkl'
,
'r'
)
f_
=
cPickle
.
load
(
pkl_path
)
f_
=
cPickle
.
load
(
pkl_path
)
import
ipdb
;
ipdb
.
set_trace
()
in1
=
numpy
.
ones
((
10
,
10
),
dtype
=
floatX
)
in1
=
numpy
.
ones
((
10
,
10
),
dtype
=
floatX
)
in2
=
numpy
.
ones
((
10
,
10
),
dtype
=
floatX
)
in2
=
numpy
.
ones
((
10
,
10
),
dtype
=
floatX
)
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论