提交 ed9143d0 authored 作者: James Bergstra's avatar James Bergstra

merge

...@@ -219,17 +219,17 @@ class BadDestroyMap(DebugModeError): ...@@ -219,17 +219,17 @@ class BadDestroyMap(DebugModeError):
self.new_val = new_val self.new_val = new_val
def __str__(self): def __str__(self):
npy_old_val = numpy.asarray(self.old_val) sio = StringIO()
npy_new_val = numpy.asarray(self.new_val) print >> sio, " node:", self.node
print >> sio, " node.inputs:", [(str(i), id(i)) for i in self.node.inputs]
print >> sio, " destroy_map:", getattr(self.node.op, 'destroy_map', {})
print >> sio, " changed input idx:", self.idx
print >> sio, " changed input type:", self.node.inputs[self.idx].type
print >> sio, " repr (old val):", repr(self.old_val)
print >> sio, " repr (new val):", repr(self.new_val)
try: try:
sio = StringIO() npy_old_val = numpy.asarray(self.old_val)
print >> sio, " node:", self.node npy_new_val = numpy.asarray(self.new_val)
print >> sio, " node.inputs:", [(str(i), id(i)) for i in self.node.inputs]
print >> sio, " destroy_map:", getattr(self.node.op, 'destroy_map', {})
print >> sio, " changed input idx:", self.idx
print >> sio, " changed input type:", self.node.inputs[self.idx].type
print >> sio, " repr (old val):", repr(self.old_val)
print >> sio, " repr (new val):", repr(self.new_val)
print >> sio, " value dtype (new <space> old):", npy_new_val.dtype, npy_old_val.dtype print >> sio, " value dtype (new <space> old):", npy_new_val.dtype, npy_old_val.dtype
print >> sio, " value shape (new <space> old):", npy_new_val.shape, npy_old_val.shape print >> sio, " value shape (new <space> old):", npy_new_val.shape, npy_old_val.shape
print >> sio, " value min (new <space> old):", npy_new_val.min(), npy_old_val.min() print >> sio, " value min (new <space> old):", npy_new_val.min(), npy_old_val.min()
...@@ -237,10 +237,10 @@ class BadDestroyMap(DebugModeError): ...@@ -237,10 +237,10 @@ class BadDestroyMap(DebugModeError):
print >> sio, " value min (new-old):", (npy_new_val-npy_old_val).min() print >> sio, " value min (new-old):", (npy_new_val-npy_old_val).min()
print >> sio, " value max (new-old):", (npy_new_val-npy_old_val).max() print >> sio, " value max (new-old):", (npy_new_val-npy_old_val).max()
print >> sio, "" print >> sio, ""
print >> sio, " Hint: this can also be caused by a deficient values_eq_approx() or __eq__() implementation [which compared input values]"
return sio.getvalue()
except Exception, e: except Exception, e:
return str(e) print >> sio, "(Numpy-hints failed with: %s)" %str(e)
print >> sio, " Hint: this can also be caused by a deficient values_eq_approx() or __eq__() implementation [which compared input values]"
return sio.getvalue()
class BadViewMap(DebugModeError): class BadViewMap(DebugModeError):
"""Exception: Some perform() or c_code() created a memory alias that wasn't in the view_map""" """Exception: Some perform() or c_code() created a memory alias that wasn't in the view_map"""
...@@ -868,6 +868,11 @@ class _Linker(gof.link.LocalLinker): ...@@ -868,6 +868,11 @@ class _Linker(gof.link.LocalLinker):
return self return self
def make_all(self, profiler = None, input_storage = None, output_storage = None): def make_all(self, profiler = None, input_storage = None, output_storage = None):
if 1:
#can't import at toplevel because of circular import
# TODO: don't do this ugly hacky way of setting the filter_checks_isfinite
from theano.tensor import TensorType #to set filter_check_isfinite
env = self.env env = self.env
input_storage_ = input_storage input_storage_ = input_storage
output_storage_ = output_storage output_storage_ = output_storage
...@@ -932,7 +937,7 @@ class _Linker(gof.link.LocalLinker): ...@@ -932,7 +937,7 @@ class _Linker(gof.link.LocalLinker):
# This is the function that runs when you evaluate the graph # This is the function that runs when you evaluate the graph
##### #####
def f(): def f():
debug("starting f") debug("starting a DebugMode call")
for x in no_recycling: for x in no_recycling:
x[0] = None x[0] = None
...@@ -1027,7 +1032,10 @@ class _Linker(gof.link.LocalLinker): ...@@ -1027,7 +1032,10 @@ class _Linker(gof.link.LocalLinker):
storage_map[r][0] = _lessbroken_deepcopy(r_vals[r]) storage_map[r][0] = _lessbroken_deepcopy(r_vals[r])
debug(i, "DEBUGMODE running thunk_c") debug(i, "DEBUGMODE running thunk_c")
thunk_c() try:
thunk_c()
except:
raise_with_op(node)
for r in node.outputs: for r in node.outputs:
# check output values for type-correctness # check output values for type-correctness
...@@ -1075,9 +1083,6 @@ class _Linker(gof.link.LocalLinker): ...@@ -1075,9 +1083,6 @@ class _Linker(gof.link.LocalLinker):
if True: if True:
gc.collect() gc.collect()
#except:
# raise_with_op(node)
_find_bad_optimizations(order, env.equivalence_tracker.reasons, r_vals) _find_bad_optimizations(order, env.equivalence_tracker.reasons, r_vals)
##### #####
...@@ -1132,10 +1137,27 @@ class _Linker(gof.link.LocalLinker): ...@@ -1132,10 +1137,27 @@ class _Linker(gof.link.LocalLinker):
if (r.owner is None): if (r.owner is None):
assert storage_map[r][0] is not None assert storage_map[r][0] is not None
############### ###############
# Done f # Done debugmode function call 'f'
############## ##############
def run_with_tensortype_filter_check(f):
def deco():
# WARNING: this is a global mechanism...
# so it will screw up if we are trying to use
# multiple modes at once.
old_filter_checks_isfinite = TensorType.filter_checks_isfinite
TensorType.filter_checks_isfinite = self.maker.mode.check_isfinite
try:
return f()
finally:
# put back the filter_checks_isfinite
TensorType.filter_checks_isfinite = old_filter_checks_isfinite
return deco
f = run_with_tensortype_filter_check(f)
f.allow_gc = True f.allow_gc = True
assert len(env.inputs) == len(input_storage) assert len(env.inputs) == len(input_storage)
assert len(env.outputs) == len(output_storage) assert len(env.outputs) == len(output_storage)
...@@ -1170,11 +1192,6 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions ...@@ -1170,11 +1192,6 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions
""" """
# WARNING: this is a global mechanism... so it will screw up if we are trying to use
# multiple modes at once.
from theano.tensor import TensorType #to set filter_check_isfinite
TensorType.filter_checks_isfinite = mode.check_isfinite
# Handle the case where inputs and/or outputs is a single Variable (not in a list) # Handle the case where inputs and/or outputs is a single Variable (not in a list)
unpack_single = False unpack_single = False
return_none = False return_none = False
......
...@@ -8,7 +8,6 @@ To read about different sparse formats, see U{http://www-users.cs.umn.edu/~saad/ ...@@ -8,7 +8,6 @@ To read about different sparse formats, see U{http://www-users.cs.umn.edu/~saad/
import sys, operator import sys, operator
import numpy, theano import numpy, theano
from scipy import sparse
import scipy.sparse import scipy.sparse
from theano.printing import Print from theano.printing import Print
...@@ -16,6 +15,7 @@ from theano import gof ...@@ -16,6 +15,7 @@ from theano import gof
from theano import tensor from theano import tensor
from theano import compile from theano import compile
from theano import scalar from theano import scalar
from theano import config
#TODO: move this decorator to the compile submodule #TODO: move this decorator to the compile submodule
def register_specialize(lopt, *tags, **kwargs): def register_specialize(lopt, *tags, **kwargs):
...@@ -23,11 +23,11 @@ def register_specialize(lopt, *tags, **kwargs): ...@@ -23,11 +23,11 @@ def register_specialize(lopt, *tags, **kwargs):
""" Types of sparse matrices to use for testing """ """ Types of sparse matrices to use for testing """
_mtypes = [sparse.csc_matrix, sparse.csr_matrix] _mtypes = [scipy.sparse.csc_matrix, scipy.sparse.csr_matrix]
#_mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix, sparse.lil_matrix, sparse.coo_matrix] #_mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix, sparse.lil_matrix, sparse.coo_matrix]
#* new class ``dia_matrix`` : the sparse DIAgonal format #* new class ``dia_matrix`` : the sparse DIAgonal format
#* new class ``bsr_matrix`` : the Block CSR format #* new class ``bsr_matrix`` : the Block CSR format
_mtype_to_str = {sparse.csc_matrix: "csc", sparse.csr_matrix: "csr"} _mtype_to_str = {scipy.sparse.csc_matrix: "csc", scipy.sparse.csr_matrix: "csr"}
def _is_sparse_variable(x): def _is_sparse_variable(x):
""" """
...@@ -51,15 +51,15 @@ def _is_sparse(x): ...@@ -51,15 +51,15 @@ def _is_sparse(x):
@rtype: boolean @rtype: boolean
@return: True iff x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray}) @return: True iff x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
""" """
if not isinstance(x, sparse.spmatrix) and not isinstance(x, numpy.ndarray): if not isinstance(x, scipy.sparse.spmatrix) and not isinstance(x, numpy.ndarray):
raise NotImplementedError("this function should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,", x) raise NotImplementedError("this function should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,", x)
return isinstance(x, sparse.spmatrix) return isinstance(x, scipy.sparse.spmatrix)
def _is_dense(x): def _is_dense(x):
""" """
@rtype: boolean @rtype: boolean
@return: True unless x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray}) @return: True unless x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
""" """
if not isinstance(x, sparse.spmatrix) and not isinstance(x, numpy.ndarray): if not isinstance(x, scipy.sparse.spmatrix) and not isinstance(x, numpy.ndarray):
raise NotImplementedError("this function should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,", x) raise NotImplementedError("this function should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,", x)
return isinstance(x, numpy.ndarray) return isinstance(x, numpy.ndarray)
...@@ -101,22 +101,23 @@ def as_sparse_variable(x): ...@@ -101,22 +101,23 @@ def as_sparse_variable(x):
as_sparse = as_sparse_variable as_sparse = as_sparse_variable
def constant(x): def constant(x):
if not isinstance(x, sparse.spmatrix): if not isinstance(x, scipy.sparse.spmatrix):
raise TypeError("sparse.constant must be called on a scipy.sparse.spmatrix") raise TypeError("sparse.constant must be called on a scipy.sparse.spmatrix")
try: try:
return SparseConstant(SparseType(format = x.format, return SparseConstant(SparseType(format = x.format,
dtype = x.dtype), x) dtype = x.dtype), x.copy())
except TypeError: except TypeError:
raise TypeError("Could not convert %s to SparseType" % x, type(x)) raise TypeError("Could not convert %s to SparseType" % x, type(x))
def value(x): if 0:
if not isinstance(x, sparse.spmatrix): def value(x):
raise TypeError("sparse.value must be called on a scipy.sparse.spmatrix") if not isinstance(x, scipy.sparse.spmatrix):
try: raise TypeError("sparse.value must be called on a scipy.sparse.spmatrix")
return SparseValue(SparseType(format = x.format, try:
dtype = x.dtype), x) return SparseValue(SparseType(format = x.format,
except TypeError: dtype = x.dtype), x)
raise TypeError("Could not convert %s to SparseType" % x, type(x)) except TypeError:
raise TypeError("Could not convert %s to SparseType" % x, type(x))
def sp_ones_like(x): def sp_ones_like(x):
data, indices, indptr, shape = csm_properties(x) #TODO: don't restrict to CSM formats data, indices, indptr, shape = csm_properties(x) #TODO: don't restrict to CSM formats
...@@ -132,13 +133,13 @@ class SparseType(gof.Type): ...@@ -132,13 +133,13 @@ class SparseType(gof.Type):
@note As far as I can tell, L{scipy.sparse} objects must be matrices, i.e. have dimension 2. @note As far as I can tell, L{scipy.sparse} objects must be matrices, i.e. have dimension 2.
""" """
format_cls = { format_cls = {
'csr' : sparse.csr_matrix, 'csr' : scipy.sparse.csr_matrix,
'csc' : sparse.csc_matrix 'csc' : scipy.sparse.csc_matrix
} }
dtype_set = set(['int', 'int8', 'int16','int32', 'int64', 'float32', 'float64', 'complex64','complex128']) dtype_set = set(['int', 'int8', 'int16','int32', 'int64', 'float32', 'float64', 'complex64','complex128'])
ndim = 2 ndim = 2
def __init__(self, format, dtype = 'float64'): def __init__(self, format, dtype):
""" """
Fundamental way to create a sparse node. Fundamental way to create a sparse node.
@param dtype: Type of numbers in the matrix. @param dtype: Type of numbers in the matrix.
...@@ -187,16 +188,31 @@ class SparseType(gof.Type): ...@@ -187,16 +188,31 @@ class SparseType(gof.Type):
return "Sparse[%s, %s]" % (str(self.dtype), str(self.format)) return "Sparse[%s, %s]" % (str(self.dtype), str(self.format))
def values_eq_approx(self, a, b, eps=1e-6): def values_eq_approx(self, a, b, eps=1e-6):
# print "VEA", a, b, scipy.sparse.issparse(a), scipy.sparse.issparse(b), abs(a-b).sum(), abs(a-b).sum() < (1e-6 * a.nnz) #WARNING: equality comparison of sparse matrices is not fast or easy
# we definitely do not want to be doing this un-necessarily during
# a FAST_RUN computation..
return scipy.sparse.issparse(a) \ return scipy.sparse.issparse(a) \
and scipy.sparse.issparse(b) \ and scipy.sparse.issparse(b) \
and abs(a-b).sum() < (1e-6 * a.nnz) and abs(a-b).sum() < (1e-6 * a.nnz)
def values_eq(self, a, b):
#WARNING: equality comparison of sparse matrices is not fast or easy
# we definitely do not want to be doing this un-necessarily during
# a FAST_RUN computation..
return scipy.sparse.issparse(a) \
and scipy.sparse.issparse(b) \
and abs(a-b).sum() == 0.0
def is_valid_value(self, a): def is_valid_value(self, a):
return scipy.sparse.issparse(a) and (a.format == self.format) return scipy.sparse.issparse(a) and (a.format == self.format)
csc_matrix = SparseType(format='csc') # for more dtypes, call SparseType(format, dtype)
csr_matrix = SparseType(format='csr') csc_matrix = SparseType(format='csc', dtype=config.floatX)
csr_matrix = SparseType(format='csr', dtype=config.floatX)
csc_dmatrix = SparseType(format='csc', dtype='float64')
csr_dmatrix = SparseType(format='csr', dtype='float64')
csc_fmatrix = SparseType(format='csc', dtype='float32')
csr_fmatrix = SparseType(format='csr', dtype='float32')
class _sparse_py_operators: class _sparse_py_operators:
T = property(lambda self: transpose(self), doc = "Return aliased transpose of self (read-only)") T = property(lambda self: transpose(self), doc = "Return aliased transpose of self (read-only)")
...@@ -270,9 +286,11 @@ class CSMProperties(gof.Op): ...@@ -270,9 +286,11 @@ class CSMProperties(gof.Op):
def perform(self, node, (csm,), out): def perform(self, node, (csm,), out):
if self.kmap is None: if self.kmap is None:
out[0][0] = csm.data out[0][0] = csm.data
else: else:
out[0][0] = csm.data[self.kmap] out[0][0] = csm.data[self.kmap]
if str(csm.data.dtype) == 'int32':
out[0][0] = theano._asarray(out[0][0], dtype='int32')
#backport #backport
#out[0][0] = csm.data if self.kmap is None else csm.data[self.kmap] #out[0][0] = csm.data if self.kmap is None else csm.data[self.kmap]
out[1][0] = theano._asarray(csm.indices, dtype='int32') out[1][0] = theano._asarray(csm.indices, dtype='int32')
...@@ -377,13 +395,13 @@ class CSM(gof.Op): ...@@ -377,13 +395,13 @@ class CSM(gof.Op):
'as indices (shape'+`indices.shape`+') or elements as kmap ('+`numpy.size(self.kmap)`+')' 'as indices (shape'+`indices.shape`+') or elements as kmap ('+`numpy.size(self.kmap)`+')'
raise ValueError(errmsg) raise ValueError(errmsg)
if self.format == 'csc': if self.format == 'csc':
out[0] = sparse.csc_matrix((data, indices.copy(), indptr.copy()), out[0] = scipy.sparse.csc_matrix((data, indices.copy(), indptr.copy()),
numpy.asarray(shape), numpy.asarray(shape),
copy = False #1000*len(data.flatten()) copy = False #1000*len(data.flatten())
) )
else: else:
assert self.format == 'csr' assert self.format == 'csr'
out[0] = sparse.csr_matrix((data, indices.copy(), indptr.copy()), out[0] = scipy.sparse.csr_matrix((data, indices.copy(), indptr.copy()),
shape.copy(), shape.copy(),
copy = False #1000*len(data.flatten()) copy = False #1000*len(data.flatten())
) )
...@@ -546,7 +564,6 @@ class AddSS(gof.op.Op): ...@@ -546,7 +564,6 @@ class AddSS(gof.op.Op):
if x.type.dtype != y.type.dtype: if x.type.dtype != y.type.dtype:
raise NotImplementedError() raise NotImplementedError()
if x.type.format != y.type.format: if x.type.format != y.type.format:
print x.type.format, y.type.format
raise NotImplementedError() raise NotImplementedError()
return gof.Apply(self, return gof.Apply(self,
[x, y], [x, y],
...@@ -795,11 +812,11 @@ class StructuredDotCSC(gof.Op): ...@@ -795,11 +812,11 @@ class StructuredDotCSC(gof.Op):
return r return r
def perform(self, node, (a_val, a_ind, a_ptr, a_nrows, b), (out,)): def perform(self, node, (a_val, a_ind, a_ptr, a_nrows, b), (out,)):
a = sparse.csc_matrix((a_val, a_ind, a_ptr), a = scipy.sparse.csc_matrix((a_val, a_ind, a_ptr),
(a_nrows, b.shape[0]), (a_nrows, b.shape[0]),
copy = False) copy = False)
#out[0] = a.dot(b) #out[0] = a.dot(b)
out[0] = a * b out[0] = theano._asarray(a * b, dtype=node.outputs[0].type.dtype)
assert _is_dense(out[0]) # scipy 0.7 automatically converts to dense assert _is_dense(out[0]) # scipy 0.7 automatically converts to dense
def c_code(self, node, name, (a_val, a_ind, a_ptr, a_nrows, b), (z,), sub): def c_code(self, node, name, (a_val, a_ind, a_ptr, a_nrows, b), (z,), sub):
...@@ -952,7 +969,7 @@ class StructuredDotCSR(gof.Op): ...@@ -952,7 +969,7 @@ class StructuredDotCSR(gof.Op):
return r return r
def perform(self, node, (a_val, a_ind, a_ptr, b), (out,)): def perform(self, node, (a_val, a_ind, a_ptr, b), (out,)):
a = sparse.csr_matrix((a_val, a_ind, a_ptr), a = scipy.sparse.csr_matrix((a_val, a_ind, a_ptr),
(len(a_ptr)-1, b.shape[0]), (len(a_ptr)-1, b.shape[0]),
copy = True) #use view_map before setting this to False copy = True) #use view_map before setting this to False
#out[0] = a.dot(b) #out[0] = a.dot(b)
......
...@@ -237,7 +237,7 @@ def constant_or_value(x, rtype, name=None, ndim=None, dtype=None): ...@@ -237,7 +237,7 @@ def constant_or_value(x, rtype, name=None, ndim=None, dtype=None):
x_shape = None x_shape = None
return rtype( return rtype(
TensorType(dtype = x_.dtype, broadcastable = bcastable, shape=x_shape), TensorType(dtype = x_.dtype, broadcastable = bcastable, shape=x_shape),
x_, name=name) x_.copy(), name=name)
else: else:
# leave the shape out of the type # leave the shape out of the type
return rtype(TensorType(dtype = x_.dtype, broadcastable = bcastable), x_, name=name) return rtype(TensorType(dtype = x_.dtype, broadcastable = bcastable), x_, name=name)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论