提交 38e2f502 authored 作者: abergeron's avatar abergeron

Merge pull request #1946 from nouiz/scan

Small scan speed up on the GPU.
...@@ -21,6 +21,8 @@ Montreal). ...@@ -21,6 +21,8 @@ Montreal).
News News
==== ====
* Colin Raffel `tutorial on Theano <http://nbviewer.ipython.org/github/craffel/theano-tutorial/blob/master/Theano%20Tutorial.ipynb>`_.
* Ian Goodfellow did a `12h class with exercises on Theano <https://github.com/goodfeli/theano_exercises>`_. * Ian Goodfellow did a `12h class with exercises on Theano <https://github.com/goodfeli/theano_exercises>`_.
* Theano 0.6 was released. Everybody is encouraged to update. * Theano 0.6 was released. Everybody is encouraged to update.
......
...@@ -120,8 +120,18 @@ enum = EnumStr("g++", "") ...@@ -120,8 +120,18 @@ enum = EnumStr("g++", "")
try: try:
rc = call_subprocess_Popen(['g++', '-v']) rc = call_subprocess_Popen(['g++', '-v'])
except OSError: except OSError:
enum = EnumStr("")
rc = 1 rc = 1
if rc == 0: AddConfigVar('cxx',
"The C++ compiler to use. Currently only g++ is"
" supported, but supporting additional compilers should not be "
"too difficult. "
"If it is empty, no C++ code is compiled.",
enum,
in_c_key=False)
del enum
if rc == 0 and config.cxx != "":
# Keep the default linker the same as the one for the mode FAST_RUN # Keep the default linker the same as the one for the mode FAST_RUN
AddConfigVar('linker', AddConfigVar('linker',
("Default linker used if the theano flags mode is Mode " ("Default linker used if the theano flags mode is Mode "
...@@ -140,16 +150,6 @@ else: ...@@ -140,16 +150,6 @@ else:
'optimized C-implementations (for both CPU and GPU) and will ' 'optimized C-implementations (for both CPU and GPU) and will '
'default to Python implementations. Performance will be severely ' 'default to Python implementations. Performance will be severely '
'degraded.') 'degraded.')
enum = EnumStr("")
AddConfigVar('cxx',
"The C++ compiler to use. Currently only g++ is"
" supported, but supporting additional compilers should not be "
"too difficult. "
"If it is empty, no C++ code is compiled.",
enum,
in_c_key=False)
del enum
#Keep the default value the same as the one for the mode FAST_RUN #Keep the default value the same as the one for the mode FAST_RUN
......
...@@ -12,7 +12,8 @@ import warnings ...@@ -12,7 +12,8 @@ import warnings
from theano.gof.python25 import all from theano.gof.python25 import all
from theano.configparser import config, AddConfigVar, BoolParam, ConfigParam from theano.configparser import (config, AddConfigVar,
BoolParam, ConfigParam, _config_var_list)
import theano.gof.cmodule import theano.gof.cmodule
...@@ -560,7 +561,7 @@ except (OSError, theano.gof.cmodule.MissingGXX), e: ...@@ -560,7 +561,7 @@ except (OSError, theano.gof.cmodule.MissingGXX), e:
# already changed the default linker to something else then CVM. # already changed the default linker to something else then CVM.
# Currently this is the py linker. # Currently this is the py linker.
# Here we assert that the default linker is not cvm. # Here we assert that the default linker is not cvm.
assert not [x for x in theano.configparser._config_var_list assert not [x for x in _config_var_list
if x.fullname == 'linker'][0].default.startswith('cvm'), e if x.fullname == 'linker'][0].default.startswith('cvm'), e
pass pass
......
...@@ -1411,9 +1411,10 @@ def norm(x,ord): ...@@ -1411,9 +1411,10 @@ def norm(x,ord):
elif ndim > 2: elif ndim > 2:
raise NotImplementedError("We don't support norm witn ndim > 2") raise NotImplementedError("We don't support norm witn ndim > 2")
class lstsq(theano.Op): class lstsq(theano.Op):
def __eq__(self, other): def __eq__(self, other):
pass return type(self) == type(other)
def __hash__(self): def __hash__(self):
return hash(type(self)) return hash(type(self))
......
...@@ -422,11 +422,19 @@ class Scan(PureOp): ...@@ -422,11 +422,19 @@ class Scan(PureOp):
raise ValueError('For output %s you need to provide a ' raise ValueError('For output %s you need to provide a '
'scalar int !', str(outer_nitsot)) 'scalar int !', str(outer_nitsot))
assert len(new_inputs) == len(inputs) assert len(new_inputs) == len(inputs)
self.vector_seqs = [seq.ndim == 1 for seq in
new_inputs[1:1 + self.n_seqs]] # The vector_seqs and vector_outs are just a workaround
self.vector_outs = [arg.ndim == 1 for arg in # strange NumPy behavior: vector_ndarray[int] return a NumPy
new_inputs[1 + self.n_seqs: (1 + self.n_seqs + # scalar and not a NumPy ndarray of 0 dimensions.
self.n_outs)]] self.vector_seqs = [isinstance(seq, (tensor.TensorVariable,
tensor.TensorConstant)) and
seq.ndim == 1 for seq in
new_inputs[1:1 + self.n_seqs]]
self.vector_outs = [isinstance(arg, (tensor.TensorVariable,
tensor.TensorConstant)) and
arg.ndim == 1 for arg in
new_inputs[1 + self.n_seqs: (1 + self.n_seqs +
self.n_outs)]]
self.vector_outs += [False] * self.n_nit_sot self.vector_outs += [False] * self.n_nit_sot
apply_node = Apply(self, apply_node = Apply(self,
...@@ -598,12 +606,6 @@ class Scan(PureOp): ...@@ -598,12 +606,6 @@ class Scan(PureOp):
for _d1 in range(cython_mit_mot_out_nslices[_d0]): for _d1 in range(cython_mit_mot_out_nslices[_d0]):
cython_mit_mot_out_slices[_d0, _d1] = \ cython_mit_mot_out_slices[_d0, _d1] = \
self.mit_mot_out_slices[_d0][_d1] self.mit_mot_out_slices[_d0][_d1]
vector_seqs = [seq.ndim == 1 for seq in
node.inputs[1:1 + self.n_seqs]]
vector_outs = [arg.ndim == 1 for arg in
node.inputs[1 + self.n_seqs:
(1 + self.n_seqs + self.n_outs)]]
vector_outs += [False] * self.n_nit_sot
cython_vector_seqs = numpy.asarray(self.vector_seqs, cython_vector_seqs = numpy.asarray(self.vector_seqs,
dtype='int32') dtype='int32')
......
import os, logging, sys import logging
import os
import sys
import numpy
import theano import theano
from theano import config from theano import config
...@@ -60,6 +64,28 @@ except ImportError: ...@@ -60,6 +64,28 @@ except ImportError:
os.mkdir(loc) os.mkdir(loc)
preargs = ['-fwrapv', '-O2', '-fno-strict-aliasing'] preargs = ['-fwrapv', '-O2', '-fno-strict-aliasing']
preargs += cmodule.GCC_compiler.compile_args() preargs += cmodule.GCC_compiler.compile_args()
# Cython 19.1 always use the old NumPy interface. So we
# need to manually modify the .c file to get it compiled
# by Theano. As by default, we tell NumPy to don't import
# the old interface.
if False:
#During scan cython development, it is helpful to keep the old interface, to don't manually edit the c file each time.
preargs.remove('-D NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION')
else:
numpy_ver = [int(n) for n in numpy.__version__.split('.')[:2]]
# Add add some macro to lower the number of edit
# needed to the c file.
if bool(numpy_ver >= [1, 7]):
# Needed when we disable the old API, as cython
# use the old interface
preargs.append("-D NPY_ENSUREARRAY=NPY_ARRAY_ENSUREARRAY")
preargs.append("-D NPY_ENSURECOPY=NPY_ARRAY_ENSURECOPY")
preargs.append("-D NPY_ALIGNED=NPY_ARRAY_ALIGNED")
preargs.append("-D NPY_WRITEABLE=NPY_ARRAY_WRITEABLE")
preargs.append("-D NPY_UPDATE_ALL=NPY_ARRAY_UPDATE_ALL")
preargs.append("-D NPY_C_CONTIGUOUS=NPY_ARRAY_C_CONTIGUOUS")
preargs.append("-D NPY_F_CONTIGUOUS=NPY_ARRAY_F_CONTIGUOUS")
cmodule.GCC_compiler.compile_str(dirname, code, location=loc, cmodule.GCC_compiler.compile_str(dirname, code, location=loc,
preargs=preargs) preargs=preargs)
# Save version into the __init__.py file. # Save version into the __init__.py file.
......
...@@ -5033,10 +5033,10 @@ def power(x, y): ...@@ -5033,10 +5033,10 @@ def power(x, y):
return x**y return x**y
def swapaxes(y,axis1,axis2): def swapaxes(y, axis1, axis2):
"swap axes of inputted tensor" "swap axes of inputted tensor"
y = as_tensor_variable(y) y = as_tensor_variable(y)
ndim = y.ndim ndim = y.ndim
li = range(0, ndim) li = range(0, ndim)
li[axis1], li[axis2] = li[axis2], li[axis1] li[axis1], li[axis2] = li[axis2], li[axis1]
return y.dimshuffle(li) return y.dimshuffle(li)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论