提交 b8e79c60 authored 作者: nouiz's avatar nouiz

Merge pull request #989 from pascanur/c_viewop

C version of view op
import ops
from ops import (
DeepCopyOp, deep_copy_op, register_deep_copy_op_c_code,
ViewOp, view_op, register_view_op_c_code)
import function_module
from function_module import *
......
......@@ -27,6 +27,7 @@ from theano.compile.function_module import (FunctionMaker,
Supervisor,
std_fgraph)
from theano.compile.mode import Mode, register_mode
from theano.compile.ops import OutputGuard
AddConfigVar('DebugMode.patience',
"Optimize graph this many times to detect inconsistency",
......@@ -715,7 +716,7 @@ def _check_inputs(node, storage_map, r_vals, dr_vals, active_nodes,
actually_inplace_outputs.append(node.outputs[oo])
if warn_input_not_reused and destroyed_res_list:
if isinstance(node.op, theano.compile.mode.OutputGuard):
if isinstance(node.op, OutputGuard):
# The point of OutputGuard is to be declared as destructive
# while not destroying anything
continue
......@@ -738,7 +739,7 @@ def _check_inputs(node, storage_map, r_vals, dr_vals, active_nodes,
# the version of numpy!
if getattr(out_var, 'size', 2) <= 1:
continue
if isinstance(node.op, theano.compile.mode.OutputGuard):
if isinstance(node.op, OutputGuard):
# This class is not in the final graph.
continue
if not _may_share_memory(out_var, in_var):
......
......@@ -17,6 +17,7 @@ from theano import gof
from theano.gof.python25 import partial
import mode as mode_module
from io import In, SymbolicInput, SymbolicInputKit, SymbolicOutput
from theano.compile.ops import deep_copy_op, view_op
import logging
_logger = logging.getLogger('theano.compile.function_module')
......@@ -159,101 +160,6 @@ class AliasedMemoryError(Exception):
### Function
###
def register_DeepCopyOp_c_code(typ, code):
""" Tell DeepCopyOp how to generate C code for a Theano Type
:param typ: A Theano type. It must be the Theano class itself and not an
instance of the class.
:param code: C code that deep copies the Theano type 'typ'.
Use %(iname)s and %(oname)s for the input and output C
variable names respectively.
"""
DeepCopyOp.c_codes[typ] = code
class DeepCopyOp(theano.gof.Op):
c_codes = {} # Theano Type, code
def __init__(self):
pass
def __str__(self):
return self.__class__.__name__
def __hash__(self):
return hash(type(self))
def __eq__(self, other):
return type(self) == type(other)
def make_node(self, x):
return theano.gof.Apply(self, [x], [x.type()])
def perform( self, node, args, outs):
if hasattr(args[0],'copy'):
#when args[0] is a an ndarray of 0 dimensions,
#this return a numpy.dtype and not an ndarray
#So when the args have a copy attribute we use it
#as this don't have this problem
outs[0][0] = args[0].copy()
else:
outs[0][0] = copy.deepcopy(args[0])
def c_code_cache_version(self):
return (1)
def c_code(self, node, name, inames, onames, sub):
iname = inames[0]
oname = onames[0]
fail = sub['fail']
if isinstance(node.inputs[0].type, theano.tensor.TensorType):
return """
Py_XDECREF(%(oname)s);
%(oname)s = (PyArrayObject*)PyArray_NewCopy(%(iname)s,NPY_ANYORDER);
if (!%(oname)s)
{
PyErr_SetString(PyExc_ValueError, "DeepCopyOp: the copy failed!");
%(fail)s;
}
"""%locals()
elif node.inputs[0].type.__class__ in self.c_codes:
return self.c_codes[node.inputs[0].type.__class__] % locals()
else:
super(DeepCopyOp, self).c_code(node, name, inames, onames, sub)
class ViewOp(theano.gof.Op):
def __init__(self):
self.view_map={0:[0]}
def __str__(self):
return self.__class__.__name__
def __hash__(self):
return hash(type(self))
def __eq__(self, other):
return type(self) == type(other)
def make_node(self, x):
return theano.gof.Apply(self, [x], [x.type()])
def perform( self, node, args, outs):
outs[0][0] = args[0]
def infer_shape(self, node, input_shapes):
return input_shapes
def grad(self, args, g_outs):
return g_outs
deep_copy_op = DeepCopyOp()
view_op = ViewOp()
DUPLICATE = ['DUPLICATE'] # unique id object used as a placeholder for duplicate entries
class Function(object):
......
"""WRITEME
"""
import logging
import warnings
from textwrap import dedent
import numpy
......@@ -8,6 +10,7 @@ import theano
from theano import gof
import theano.gof.vm
from theano.configparser import config, AddConfigVar, StrParam
from theano.compile.ops import register_view_op_c_code, _output_guard
_logger = logging.getLogger('theano.compile.mode')
......@@ -114,74 +117,6 @@ def register_optimizer(name, opt):
predefined_optimizers[name] = opt
def register_OutputGuard_c_code(type):
OutputGuard.c_code_types.append(type)
class OutputGuard(gof.Op):
"""
This op is used only internally by Theano.
Only the AddDestroyHandler optimizer tries to insert them in the graph.
This Op is declared as destructive while it is not destroying
anything. It returns a view. This is used to prevent destruction of
the output variables of a Theano function.
There is a mechanism in Theano that should prevent this, but the use
of OutputGuard adds a safeguard: it may be possible for some optimization
run before the add_destroy_handler phase to bypass this mechanism, by
making in-place optimizations.
TODO: find a current full explanation.
"""
destroy_map = {0: [0]}
view_map = {0: [0]}
c_code_types = []
def make_node(self, x):
return gof.Apply(self, [x], [x.type()])
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def perform(self, node, inp, out):
x, = inp
z, = out
z[0] = x
def __str__(self):
return '%s' % self.__class__.__name__
def c_code(self, node, nodename, inp, out, sub):
x, = inp
z, = out
if isinstance(node.inputs[0].type, theano.scalar.Scalar):
# Scalars are C objects on the stack,
# and should not be inc/decrefed
return """
%(z)s = %(x)s;
""" % locals()
elif (isinstance(node.inputs[0].type, tuple(self.c_code_types))):
# These are Python object types
return """
Py_XDECREF(%(z)s);
%(z)s = %(x)s;
Py_XINCREF(%(z)s);
""" % locals()
# Else, no C code for you
return super(OutputGuard, self).c_code(node, nodename, inp, out, sub)
def c_code_cache_version(self):
return (2,)
_output_guard = OutputGuard()
class AddDestroyHandler(gof.Optimizer):
"""This optimizer performs two important functions:
......@@ -448,3 +383,17 @@ def register_mode(name, mode):
if name in predefined_modes:
raise ValueError('Mode name already taken: %s' % name)
predefined_modes[name] = mode
def register_OutputGuard_c_code(type):
"""Deprecated function calling register_view_op_c_code"""
warnings.warn("register_OutputGuard_c_code(type) is deprecated, "
"theano.compile.register_view_op_c_code(type, code) instead.",
stacklevel=2)
register_view_op_c_code(
type,
dedent("""
Py_XDECREF(%(oname)s);
%(oname)s = %(iname)s;
Py_XINCREF(%(oname)s);
"""))
"""This file contain auxiliary Ops, used during the compilation phase."""
import copy
import warnings
#import theano
from theano import gof
def register_view_op_c_code(type, code, version=()):
""" Tell ViewOp how to generate C code for a Theano Type
:param typ: A Theano type. It must be the Theano class itself and not an
instance of the class.
:param code: C code that deep copies the Theano type 'typ'.
Use %(iname)s and %(oname)s for the input and output C
variable names respectively.
:param version: A number indicating the version of the code, for cache.
"""
ViewOp.c_code_and_version[type] = (code, version)
class ViewOp(gof.Op):
"""
Returns an inplace view of the input. Used internally by Theano.
"""
view_map = {0: [0]}
# Mapping from Type to C code (and version) to use.
# In the C code, the name of the input variable is %(iname)s,
# the output variable is %(oname)s.
c_code_and_version = {}
def make_node(self, x):
return gof.Apply(self, [x], [x.type()])
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def perform(self, node, inp, out):
x, = inp
z, = out
z[0] = x
def __str__(self):
return '%s' % self.__class__.__name__
def c_code(self, node, nodename, inp, out, sub):
iname, = inp
oname, = out
fail = sub['fail']
itype = node.inputs[0].type.__class__
if itype in self.c_code_and_version:
code, version = self.c_code_and_version[itype]
return code % locals()
# Else, no C code
return super(ViewOp, self).c_code(node, nodename, inp, out, sub)
def c_code_cache_version(self):
version = []
# If any of the c code is unversionned, we have to return ()
# Else, we will return a list of (type name, version) pairs.
for t, (c, v) in sorted(self.c_code_and_version.items()):
if not v:
warnings.warn("Type %s has C code for ViewOp, but it has "
"no version. You should add a 'version' keyword arg "
"when calling register_deep_copy_op_c_code." % t,
stacklevel=2)
return ()
version.append((str(t), v))
return tuple(version)
def infer_shape(self, node, input_shapes):
return input_shapes
def grad(self, args, g_outs):
return g_outs
view_op = ViewOp()
class OutputGuard(ViewOp):
"""
This op is used only internally by Theano.
Only the AddDestroyHandler optimizer tries to insert them in the graph.
This Op is declared as destructive while it is not destroying
anything. It returns a view. This is used to prevent destruction of
the output variables of a Theano function.
There is a mechanism in Theano that should prevent this, but the use
of OutputGuard adds a safeguard: it may be possible for some optimization
run before the add_destroy_handler phase to bypass this mechanism, by
making in-place optimizations.
TODO: find a current full explanation.
"""
destroy_map = {0: [0]}
_output_guard = OutputGuard()
def register_deep_copy_op_c_code(typ, code, version=()):
""" Tell DeepCopyOp how to generate C code for a Theano Type
:param typ: A Theano type. It must be the Theano class itself and not an
instance of the class.
:param code: C code that deep copies the Theano type 'typ'.
Use %(iname)s and %(oname)s for the input and output C
variable names respectively.
:param version: A number indicating the version of the code, for cache.
"""
DeepCopyOp.c_code_and_version[typ] = (code, version)
class DeepCopyOp(gof.Op):
# Mapping from Type to C code (and version) to use.
# In the C code, the name of the input variable is %(iname)s,
# the output variable is %(oname)s.
c_code_and_version = {}
def __init__(self):
pass
def __str__(self):
return self.__class__.__name__
def __hash__(self):
return hash(type(self))
def __eq__(self, other):
return type(self) == type(other)
def make_node(self, x):
return gof.Apply(self, [x], [x.type()])
def perform(self, node, args, outs):
if hasattr(args[0], 'copy'):
#when args[0] is a an ndarray of 0 dimensions,
#this return a numpy.dtype and not an ndarray
#So when the args have a copy attribute we use it
#as this don't have this problem
outs[0][0] = args[0].copy()
else:
outs[0][0] = copy.deepcopy(args[0])
def c_code_cache_version(self):
version = []
# If any of the c code is unversionned, we have to return ()
# Else, we will return a list of (type name, version) pairs.
for t, (c, v) in sorted(self.c_code_and_version.items()):
if not v:
warnings.warn("Type %s has C code for OutputGuard, but it has "
"no version. You should add a 'version' keyword arg "
"when calling register_OutputGuard_c_code." % t,
stacklevel=2)
return ()
version.append((str(t), v))
return tuple(version)
def c_code(self, node, name, inames, onames, sub):
iname, = inames
oname, = onames
fail = sub['fail']
itype = node.inputs[0].type.__class__
if itype in self.c_code_and_version:
code, version = self.c_code_and_version[itype]
return code % locals()
# Else, no C code
return super(DeepCopyOp, self).c_code(node, name, inames, onames, sub)
deep_copy_op = DeepCopyOp()
import numpy
import unittest
from nose.plugins.skip import SkipTest
import theano
mode_with_opt = theano.compile.mode.get_default_mode()
mode_with_gpu = theano.compile.mode.get_default_mode().including('gpu')
def test_viewop_gpu():
from theano.sandbox import cuda
if cuda.cuda_available == False:
raise SkipTest('Optional package cuda disabled')
_x = theano.tensor.fvector('x')
x = cuda.gpu_from_host(_x)
_out = theano.compile.ViewOp()(x)
out = cuda.host_from_gpu(_out)
f = theano.function([x],
out,
mode=mode_with_gpu)
data = numpy.array([1, 2, 3], dtype='float32')
assert numpy.allclose(f(data), data)
......@@ -412,12 +412,20 @@ class CudaNdarrayType(Type):
return []
# Register CudaNdarrayType to the OutputGuard list of known types
# to have OutputGuard generate C code for this type.
theano.compile.mode.register_OutputGuard_c_code(CudaNdarrayType)
# Register C code for ViewOp on CudaNdarrayType
theano.compile.register_view_op_c_code(
CudaNdarrayType,
"""
Py_XDECREF(%(oname)s);
%(oname)s = %(iname)s;
Py_XINCREF(%(oname)s);
""",
version=1)
# Register CudaNdarrayType to the DeepCopyOp list of types with c code.
theano.compile.function_module.register_DeepCopyOp_c_code(CudaNdarrayType, """
theano.compile.register_deep_copy_op_c_code(
CudaNdarrayType,
"""
Py_XDECREF(%(oname)s);
%(oname)s = (CudaNdarray*)CudaNdarray_Copy(%(iname)s);
......@@ -427,7 +435,8 @@ theano.compile.function_module.register_DeepCopyOp_c_code(CudaNdarrayType, """
PyErr_SetString(PyExc_ValueError, "DeepCopyOp: the copy failed!");
%(fail)s;
}
""")
""",
version=1)
# THIS WORKS But CudaNdarray instances don't compare equal to one
......
......@@ -421,6 +421,14 @@ class Scalar(Type):
return (4,) # explicit T given in specialization of operator=
# lines. This makes it compile with open64
# Register C code for ViewOp on Scalars.
theano.compile.register_view_op_c_code(
Scalar,
"""
%(oname)s = %(iname)s;
""",
1)
int8 = Scalar('int8')
int16 = Scalar('int16')
......
......@@ -23,8 +23,7 @@ from theano import gof
from theano.gof.python25 import maxsize
from theano.gof.opt import Optimizer
from theano.gof import toolbox, DestroyHandler, InconsistencyError
from theano.compile import optdb
from theano.compile.function_module import deep_copy_op
from theano.compile import deep_copy_op, optdb
import scan_op
import scan_utils
......
......@@ -147,6 +147,12 @@ class SparseType(gof.Type):
def is_valid_value(self, a):
return scipy.sparse.issparse(a) and (a.format == self.format)
# Register CudaNdarrayType to the OutputGuard list of known types
# to have OutputGuard generate C code for this type.
theano.compile.mode.register_OutputGuard_c_code(SparseType)
# Register SparseType's C code for ViewOp.
theano.compile.register_view_op_c_code(
SparseType,
"""
Py_XDECREF(%(oname)s);
%(oname)s = %(iname)s;
Py_XINCREF(%(oname)s);
""",
1)
......@@ -1054,9 +1054,31 @@ class TensorType(Type):
return numpy.zeros(shape, dtype=self.dtype)
# Register CudaNdarrayType to the OutputGuard list of known types
# to have OutputGuard generate C code for this type.
theano.compile.mode.register_OutputGuard_c_code(TensorType)
# Register TensorType C code for ViewOp.
theano.compile.register_view_op_c_code(
TensorType,
"""
Py_XDECREF(%(oname)s);
%(oname)s = %(iname)s;
Py_XINCREF(%(oname)s);
""",
version=1)
# Register TensorType C code for DeepCopyOp
theano.compile.register_deep_copy_op_c_code(
TensorType,
"""
Py_XDECREF(%(oname)s);
%(oname)s = (PyArrayObject*)PyArray_NewCopy(%(iname)s,NPY_ANYORDER);
if (!%(oname)s)
{
PyErr_SetString(PyExc_ValueError, "DeepCopyOp: the copy failed!");
%(fail)s;
}
""",
version=1)
# Easy constructors
......
......@@ -56,9 +56,15 @@ class RandomStateType(gof.Type):
return False
return True
# Register CudaNdarrayType to the OutputGuard list of known types
# to have OutputGuard generate C code for this type.
theano.compile.mode.register_OutputGuard_c_code(RandomStateType)
# Register RandomStateType's C code for ViewOp.
theano.compile.register_view_op_c_code(
RandomStateType,
"""
Py_XDECREF(%(oname)s);
%(oname)s = %(iname)s;
Py_XINCREF(%(oname)s);
""",
1)
random_state_type = RandomStateType()
......
......@@ -19,6 +19,7 @@ from numpy.testing.noseclasses import KnownFailureTest
import theano
from theano import compile, config, function, gof, tensor, shared
from theano.compile import DeepCopyOp
from theano.compile.mode import get_default_mode
from theano.gof.python25 import any, all, combinations
from theano.tensor import (_shared, wvector, bvector, autocast_float_as,
......@@ -1747,8 +1748,7 @@ class TestAlloc(unittest.TestCase):
topo = f.maker.fgraph.toposort()
assert numpy.sum([isinstance(node.op, alloc)
for node in topo]) == 1
assert not isinstance(topo[0].op,
theano.compile.function_module.DeepCopyOp)
assert not isinstance(topo[0].op, DeepCopyOp)
def test_eye():
......@@ -1794,8 +1794,7 @@ def test_identity():
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
if theano.config.mode != 'FAST_COMPILE':
assert isinstance(topo[0].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(topo[0].op, DeepCopyOp)
for dtype in ALL_DTYPES:
yield check, dtype
......@@ -2502,7 +2501,7 @@ class T_subtensor(unittest.TestCase, utt.TestOptimizationMixin):
adv_incsub1=tensor.AdvancedIncSubtensor1,
mode=None,
dtype=theano.config.floatX,
ignore_topo=(theano.compile.function_module.DeepCopyOp)):
ignore_topo=DeepCopyOp):
self.shared = shared
self.sub = sub
self.inc_sub = inc_sub
......@@ -3551,7 +3550,7 @@ class T_Join_and_Split(unittest.TestCase):
mode=self.mode.including('local_join_1'))
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert isinstance(topo[0].op, theano.compile.DeepCopyOp)
assert isinstance(topo[0].op, DeepCopyOp)
def test_join_vector(self):
a = self.shared(numpy.array([1, 2, 3], dtype=self.floatX))
......
......@@ -14,6 +14,7 @@ from numpy.testing.noseclasses import KnownFailureTest
import theano
import theano.scalar as scal
from theano import compile
from theano.compile import deep_copy_op, DeepCopyOp
from theano import config
from theano import function
from theano import gof
......@@ -476,7 +477,7 @@ class test_canonize(unittest.TestCase):
print "ID TOPO", id, topo, sym_inputs
for r, t in f.maker.fgraph.shape_feature.shape_of.items():
print ' ', r, t
if topo and not(len(topo)==1 and topo[0].op==theano.compile.function_module.deep_copy_op):
if topo and not(len(topo)==1 and topo[0].op==deep_copy_op):
for node in topo[:-1]:
assert isinstance(node.op, Shape_i)
assert isinstance(topo[-1].op, tensor.Alloc)
......@@ -576,7 +577,7 @@ class test_canonize(unittest.TestCase):
assert numpy.allclose(out, val_inputs[0])
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
topo[0].op == theano.compile.function_module.deep_copy_op
topo[0].op == deep_copy_op
assert(out_dtype == out.dtype)
#test x / abs(x) -> sign(x)
......@@ -1589,8 +1590,7 @@ class test_local_subtensor_lift(unittest.TestCase):
prog = f.maker.fgraph.toposort()
assert prog[0].op == tensor.exp
assert isinstance(prog[1].op, tensor.Subtensor) # first subtensor
assert isinstance(prog[2].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(prog[2].op, DeepCopyOp)
assert len(prog) == 3
f([[0, 1], [2, 3]]) # let debugmode test something
......@@ -1760,8 +1760,7 @@ class test_local_subtensor_merge(unittest.TestCase):
topo = f.maker.fgraph.toposort()
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1789,8 +1788,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1817,8 +1815,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1845,8 +1842,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1869,8 +1865,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1888,8 +1883,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1909,8 +1903,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1929,8 +1922,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo
if isinstance(t.op, tensor.Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op,
theano.compile.function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -1974,8 +1966,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo if isinstance(t.op, tensor.
Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
b1r = self.rng.permutation(range(-8, 8))[:2]
e1r = self.rng.permutation(range(-8, 8))[:2]
......@@ -2058,8 +2049,7 @@ class test_local_subtensor_merge(unittest.TestCase):
assert len([t for t in topo if isinstance(t.op, tensor.
Subtensor)]) == 1
#print topo[-1].op
assert isinstance(topo[-1].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
b_r = self.rng.permutation(range(-4, 4))[:3]
e_r = self.rng.permutation(range(-4, 4))[:3]
......@@ -2146,8 +2136,7 @@ class test_local_subtensor_merge(unittest.TestCase):
#print [t for t in topo if isinstance(t.op, tensor.Subtensor)]
assert len([t for t in topo if isinstance(t.op,
tensor.Subtensor)]) <= 1
assert isinstance(topo[-1].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -2204,8 +2193,7 @@ class test_local_subtensor_merge(unittest.TestCase):
#print [t for t in topo if isinstance(t.op, tensor.Subtensor)]
assert len([t for t in topo if isinstance(t.op,
tensor.Subtensor)]) <= 1
assert isinstance(topo[-1].op, theano.compile.
function_module.DeepCopyOp)
assert isinstance(topo[-1].op, DeepCopyOp)
for x_s in self.x_shapes:
x_val = self.rng.uniform(size=x_s).astype(config.floatX)
......@@ -2438,7 +2426,7 @@ class Test_local_useless_alloc(unittest.TestCase):
f = function([], a, mode=mode_opt)
# The optimization should then be applied, and remove Alloc
assert ([node.op for node in f.maker.fgraph.toposort()]
== [compile.deep_copy_op])
== [deep_copy_op])
# In DebugMode, the shape mismatch should be detected
if isinstance(mode_opt, compile.DebugMode):
......@@ -2481,7 +2469,7 @@ class test_shapeoptimizer(unittest.TestCase):
f = function([v], v.dimshuffle('x', 'x', 0).shape[1], mode=mode)
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert topo[0].op == theano.compile.function_module.deep_copy_op
assert topo[0].op == deep_copy_op
def test_local_track_shape_i(self):
class IdentityNoShape(gof.Op):
......@@ -2595,7 +2583,7 @@ class test_assert(utt.InferShapeTester):
assert f(5) == 5
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert topo[0].op == theano.compile.function_module.deep_copy_op
assert topo[0].op == deep_copy_op
def test2(self):
#remove assert condition that are always true
......@@ -2613,7 +2601,7 @@ class test_assert(utt.InferShapeTester):
topo = f.maker.fgraph.toposort()
assert len(topo) == 2
assert len(topo[0].inputs) == 2
assert topo[1].op == theano.compile.function_module.deep_copy_op
assert topo[1].op == deep_copy_op
def test3(self):
#don't remove assert condition that are always false
......@@ -2630,7 +2618,7 @@ class test_assert(utt.InferShapeTester):
topo = f.maker.fgraph.toposort()
assert len(topo) == 2
assert len(topo[0].inputs) == 3
assert topo[1].op == theano.compile.function_module.deep_copy_op
assert topo[1].op == deep_copy_op
def test_infer_shape(self):
......@@ -2663,7 +2651,7 @@ def test_local_mul_specialize():
f = function([v], v * 1, mode=mode)
nodes = [node.op for node in f.maker.fgraph.toposort()]
print nodes
nodes == [theano.compile.function_module.deep_copy_op]
nodes == [deep_copy_op]
f = function([v], v * 0, mode=mode)
nodes = [node.op for node in f.maker.fgraph.toposort()]
......@@ -2743,7 +2731,7 @@ def test_local_pow_specialize():
f = function([v], v ** 1, mode=mode)
nodes = [node.op for node in f.maker.fgraph.toposort()]
nodes == [theano.compile.function_module.deep_copy_op]
nodes == [deep_copy_op]
assert numpy.allclose(f(val), val ** 1)
f = function([v], v ** (-1), mode=mode)
......@@ -2893,7 +2881,7 @@ class T_useless_elemwise(unittest.TestCase):
f(vx)
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert topo[0].op == theano.compile.function_module.deep_copy_op
assert topo[0].op == deep_copy_op
f2 = theano.function([x, y], T.mul(x, y), mode=self.mode)
assert numpy.all(f2(vx, vy) == vx * vy)
topo2 = f2.maker.fgraph.toposort()
......@@ -2911,7 +2899,7 @@ class T_useless_elemwise(unittest.TestCase):
f(vx)
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert topo[0].op == theano.compile.function_module.deep_copy_op
assert topo[0].op == deep_copy_op
f2 = theano.function([x, y], T.add(x, y), mode=self.mode)
assert numpy.all(f2(vx, vy) == vx + vy)
topo2 = f2.maker.fgraph.toposort()
......@@ -2929,7 +2917,7 @@ class T_useless_elemwise(unittest.TestCase):
f(vx)
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert topo[0].op == theano.compile.function_module.deep_copy_op
assert topo[0].op == deep_copy_op
def test_constant_get_stabilized():
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论