提交 c732789b authored 作者: Frédéric Bastien's avatar Frédéric Bastien

Merge pull request #3966 from nouiz/dnn

add flag dnn.enabled
...@@ -567,6 +567,20 @@ import theano and print the config variable, as in: ...@@ -567,6 +567,20 @@ import theano and print the config variable, as in:
A directory with bin/, lib/, include/ folders containing cuda utilities. A directory with bin/, lib/, include/ folders containing cuda utilities.
.. attribute:: dnn.enabled
String value: ``auto``, ``True``, ``False``
Default ``auto``
If ``auto``, auto detect if cudnn is there, if not, do not use it,
but do not raise an error.
If ``True``, if we can't use cudnn, raise an error.
If ``False``, do not test if cudnn is there and don't use it.
Useful to disable it completely when the auto detection crashes.
.. attribute:: config.dnn.conv.workmem .. attribute:: config.dnn.conv.workmem
Deprecated, use dnn.conv.algo_fwd. Deprecated, use dnn.conv.algo_fwd.
......
...@@ -38,7 +38,10 @@ By default, Theano will detect if it can use cuDNN. If so, it will use ...@@ -38,7 +38,10 @@ By default, Theano will detect if it can use cuDNN. If so, it will use
it. If not, Theano optimizations will not introduce cuDNN ops. So it. If not, Theano optimizations will not introduce cuDNN ops. So
Theano will still work if the user did not introduce them manually. Theano will still work if the user did not introduce them manually.
To get an error if Theano can not use cuDNN, use this Theano flag: The recently added Theano flag :attr:`dnn.enabled
<config.dnn.enabled>` allows to change the default behavior to force
it or disable it. Older Theano version do not support this flag. To
get an error when CuDNN can not be used with them, use this flag:
``optimizer_including=cudnn``. ``optimizer_including=cudnn``.
.. note:: .. note::
...@@ -63,6 +66,8 @@ To get an error if Theano can not use cuDNN, use this Theano flag: ...@@ -63,6 +66,8 @@ To get an error if Theano can not use cuDNN, use this Theano flag:
* ``large`` : use a sometimes faster implementation with large memory usage * ``large`` : use a sometimes faster implementation with large memory usage
* ``fft`` : use the Fast Fourrier Transform implementation of convolution * ``fft`` : use the Fast Fourrier Transform implementation of convolution
(very high memory usage) (very high memory usage)
* ``fft_tiling`` : use the Fast Fourrier Transform implementation of convolution
with tiling (high memory usage, but less then fft)
* ``guess_once`` : the first time a convolution is executed, the * ``guess_once`` : the first time a convolution is executed, the
implementation to use is chosen according to CuDNN's heuristics and reused implementation to use is chosen according to CuDNN's heuristics and reused
for every subsequent execution of the convolution. for every subsequent execution of the convolution.
...@@ -76,9 +81,10 @@ To get an error if Theano can not use cuDNN, use this Theano flag: ...@@ -76,9 +81,10 @@ To get an error if Theano can not use cuDNN, use this Theano flag:
implementation selected every time the shapes of the inputs and kernels implementation selected every time the shapes of the inputs and kernels
don't match the shapes from the last execution. don't match the shapes from the last execution.
The Theano flag ``dnn.conv.algo_bwd`` allows to specify the CuDNN The Theano flag ``dnn.conv.algo_bwd_filter`` and
convolution implementation that Theano should use for gradient convolutions. ``dnn.conv.algo_bwd_data`` allows to specify the CuDNN
Possible values include : convolution implementation that Theano should use for gradient
convolutions. Possible values include :
* ``none`` (default) : use the default non-deterministic convolution * ``none`` (default) : use the default non-deterministic convolution
implementation implementation
...@@ -98,6 +104,13 @@ To get an error if Theano can not use cuDNN, use this Theano flag: ...@@ -98,6 +104,13 @@ To get an error if Theano can not use cuDNN, use this Theano flag:
implementation selected every time the shapes of the inputs and kernels implementation selected every time the shapes of the inputs and kernels
don't match the shapes from the last execution. don't match the shapes from the last execution.
* (algo_bwd_data only) ``fft_tiling`` : use the Fast Fourrier
Transform implementation of convolution with tiling (high memory
usage, but less then fft)
* (algo_bwd_data only) ``small`` : use a convolution implementation
with small memory usage
``guess_*`` and ``time_*`` flag values take into account the amount of ``guess_*`` and ``time_*`` flag values take into account the amount of
available memory when selecting an implementation. This means that slower available memory when selecting an implementation. This means that slower
implementations might be selected if not enough memory is available for the implementations might be selected if not enough memory is available for the
......
...@@ -329,6 +329,14 @@ AddConfigVar('dnn.library_path', ...@@ -329,6 +329,14 @@ AddConfigVar('dnn.library_path',
"Location of the cudnn header (defaults to the cuda root)", "Location of the cudnn header (defaults to the cuda root)",
StrParam(default_dnn_path('lib64'))) StrParam(default_dnn_path('lib64')))
AddConfigVar('dnn.enabled',
"'auto', use CuDNN if available, but silently fall back"
" to not using it if not present."
" If True and CuDNN can not be used, raise an error."
" If False, disable cudnn",
StrParam("auto", "True", "False"),
in_c_key=False)
# This flag determines whether or not to raise error/warning message if # This flag determines whether or not to raise error/warning message if
# there is a CPU Op in the computational graph. # there is a CPU Op in the computational graph.
AddConfigVar( AddConfigVar(
......
...@@ -36,11 +36,13 @@ from theano.tensor.nnet.abstract_conv import (AbstractConv2d, ...@@ -36,11 +36,13 @@ from theano.tensor.nnet.abstract_conv import (AbstractConv2d,
def dnn_available(): def dnn_available():
if dnn_available.avail is None: if config.dnn.enabled == "False":
if not theano.sandbox.cuda.cuda_available: dnn_available.avail = False
dnn_available.msg = "disabled by dnn.enabled flag"
if dnn_available.avail is None and not theano.sandbox.cuda.cuda_available:
dnn_available.msg = "CUDA not available" dnn_available.msg = "CUDA not available"
dnn_available.avail = False dnn_available.avail = False
return False elif dnn_available.avail is None:
dev = theano.sandbox.cuda.active_device_number() dev = theano.sandbox.cuda.active_device_number()
if theano.sandbox.cuda.device_properties(dev)['major'] < 3: if theano.sandbox.cuda.device_properties(dev)['major'] < 3:
dnn_available.msg = "Device not supported by cuDNN" dnn_available.msg = "Device not supported by cuDNN"
...@@ -100,7 +102,11 @@ if ((err = cudnnCreate(&_handle)) != CUDNN_STATUS_SUCCESS) { ...@@ -100,7 +102,11 @@ if ((err = cudnnCreate(&_handle)) != CUDNN_STATUS_SUCCESS) {
"candidate) that isn't supported. Please update to " "candidate) that isn't supported. Please update to "
"at least v3 final version.") "at least v3 final version.")
raise RuntimeError(dnn_available.msg) raise RuntimeError(dnn_available.msg)
if config.dnn.enabled == "True":
if not dnn_available.avail:
raise RuntimeError(
"You enabled CuDNN, but we aren't able to use it: %s" %
dnn_available.msg)
return dnn_available.avail return dnn_available.avail
......
...@@ -86,6 +86,9 @@ def _dnn_check_version(): ...@@ -86,6 +86,9 @@ def _dnn_check_version():
def dnn_present(): def dnn_present():
if dnn_present.avail is not None: if dnn_present.avail is not None:
return dnn_present.avail return dnn_present.avail
if config.dnn.enabled == "False":
dnn_present.msg = "disabled by dnn.enabled flag"
dnn_present.avail = False
if pygpu is None: if pygpu is None:
dnn_present.msg = "PyGPU not available" dnn_present.msg = "PyGPU not available"
...@@ -98,6 +101,12 @@ def dnn_present(): ...@@ -98,6 +101,12 @@ def dnn_present():
if not dnn_present.avail: if not dnn_present.avail:
raise RuntimeError(dnn_present.msg) raise RuntimeError(dnn_present.msg)
if config.dnn.enabled == "True":
if not dnn_present.avail:
raise RuntimeError(
"You enabled CuDNN, but we aren't able to use it: %s" %
dnn_present.msg)
return dnn_present.avail return dnn_present.avail
dnn_present.avail = None dnn_present.avail = None
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论