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

Merge pull request #1875 from Hengjean/TypedListC

Added C interface for TypedListType, GetItem, insert, append and extend
from type import TypedListType
from basic import *
import opt
from type import TypedListType
import theano
from theano.gof import Apply, Constant, Op, Variable
from theano.tensor.type_other import SliceType
from theano import tensor as T
......@@ -10,13 +11,29 @@ import numpy
class _typed_list_py_operators:
def __getitem__(self, index):
return GetItem()(self, index)
return getitem(self, index)
def append(self, toAppend):
return Append()(self, toAppend)
return append(self, toAppend)
def extend(self, toAppend):
return Extend()(self, toAppend)
return extend(self, toAppend)
def insert(self, index, toInsert):
return insert(self, index, toInsert)
def remove(self, toRemove):
return remove(self, toRemove)
def reverse(self):
return reverse(self)
def count(self, elem):
return count(self, elem)
#name "index" is already used by an attribute
def ind(self, elem):
return index_(self, elem)
ttype = property(lambda self: self.type.ttype)
......@@ -46,11 +63,12 @@ class GetItem(Op):
index = Constant(SliceType(), index)
return Apply(self, [x, index], [x.type()])
else:
index = T.constant(index, ndim=0)
index = T.constant(index, ndim=0, dtype='int64')
return Apply(self, [x, index], [x.ttype()])
if isinstance(index.type, SliceType):
return Apply(self, [x, index], [x.type()])
elif isinstance(index, T.TensorVariable) and index.ndim == 0:
assert index.dtype == 'int64'
return Apply(self, [x, index], [x.ttype()])
else:
raise TypeError('Expected scalar or slice as index.')
......@@ -63,6 +81,23 @@ class GetItem(Op):
def __str__(self):
return self.__class__.__name__
def c_code(self, node, name, inp, out, sub):
x_name, index = inp[0], inp[1]
output_name = out[0]
fail = sub['fail']
return """
%(output_name)s = (typeof %(output_name)s) PyList_GetItem( (PyObject*) %(x_name)s, *((npy_int64 *) PyArray_DATA(%(index)s)));
if(%(output_name)s == NULL){
%(fail)s
}
Py_INCREF(%(output_name)s);
""" % locals()
def c_code_cache_version(self):
return (1,)
getitem = GetItem()
class Append(Op):
"""
......@@ -75,10 +110,10 @@ class Append(Op):
self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other)
return type(self) == type(other) and self.inplace == other.inplace
def __hash__(self):
return hash(type(self))
return hash(type(self)) ^ hash(self.inplace)
def make_node(self, x, toAppend):
assert isinstance(x.type, TypedListType)
......@@ -95,6 +130,33 @@ class Append(Op):
def __str__(self):
return self.__class__.__name__
def c_code(self, node, name, inp, out, sub):
x_name, toAppend = inp[0], inp[1]
output_name = out[0]
fail = sub['fail']
if not self.inplace:
init = """
%(output_name)s = (PyListObject*) PyList_GetSlice((PyObject*) %(x_name)s, 0, PyList_GET_SIZE((PyObject*) %(x_name)s)) ;
""" % locals()
else:
init = """
%(output_name)s = %(x_name)s;
""" % locals()
return init + """
if(%(output_name)s==NULL){
%(fail)s
};
if(PyList_Append( (PyObject*) %(output_name)s,(PyObject*) %(toAppend)s)){
%(fail)s
};
Py_INCREF(%(output_name)s);
""" % locals()
def c_code_cache_version(self):
return (1,)
append = Append()
class Extend(Op):
"""
......@@ -107,10 +169,10 @@ class Extend(Op):
self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other)
return type(self) == type(other) and self.inplace == other.inplace
def __hash__(self):
return hash(type(self))
return hash(type(self)) ^ hash(self.inplace)
def make_node(self, x, toAppend):
assert isinstance(x.type, TypedListType)
......@@ -127,6 +189,37 @@ class Extend(Op):
def __str__(self):
return self.__class__.__name__
def c_code(self, node, name, inp, out, sub):
x_name, toAppend = inp[0], inp[1]
output_name = out[0]
fail = sub['fail']
if not self.inplace:
init = """
%(output_name)s = (PyListObject*) PyList_GetSlice((PyObject*) %(x_name)s, 0, PyList_GET_SIZE((PyObject*) %(x_name)s)) ;
""" % locals()
else:
init = """
%(output_name)s = %(x_name)s;
""" % locals()
return init + """
int i =0;
int length = PyList_GET_SIZE((PyObject*) %(toAppend)s);
if(%(output_name)s==NULL){
%(fail)s
};
for(i; i < length; i++){
if(PyList_Append( (PyObject*) %(output_name)s,(PyObject*) PyList_GetItem((PyObject*) %(toAppend)s,i))==-1){
%(fail)s
};
}
Py_INCREF(%(output_name)s);
""" % locals()
def c_code_cache_version(self):
return (1,)
extend = Extend()
class Insert(Op):
......@@ -136,17 +229,18 @@ class Insert(Op):
self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other)
return type(self) == type(other) and self.inplace == other.inplace
def __hash__(self):
return hash(type(self))
return hash(type(self)) ^ hash(self.inplace)
def make_node(self, x, index, toInsert):
assert isinstance(x.type, TypedListType)
assert x.ttype == toInsert.type
if not isinstance(index, Variable):
index = T.constant(index, ndim=0)
index = T.constant(index, ndim=0, dtype='int64')
else:
assert index.dtype == 'int64'
assert isinstance(index, T.TensorVariable) and index.ndim == 0
return Apply(self, [x, index, toInsert], [x.type()])
......@@ -160,6 +254,33 @@ class Insert(Op):
def __str__(self):
return self.__class__.__name__
def c_code(self, node, name, inp, out, sub):
x_name, index, toInsert = inp[0], inp[1], inp[2]
output_name = out[0]
fail = sub['fail']
if not self.inplace:
init = """
%(output_name)s = (PyListObject*) PyList_GetSlice((PyObject*) %(x_name)s, 0, PyList_GET_SIZE((PyObject*) %(x_name)s)) ;
""" % locals()
else:
init = """
%(output_name)s = %(x_name)s;
""" % locals()
return init + """
if(%(output_name)s==NULL){
%(fail)s
};
if(PyList_Insert((PyObject*) %(output_name)s, *((npy_int64 *) PyArray_DATA(%(index)s)), (PyObject*) %(toInsert)s)==-1){
%(fail)s
};
Py_INCREF(%(output_name)s);
""" % locals()
def c_code_cache_version(self):
return (1,)
insert = Insert()
class Remove(Op):
......@@ -169,10 +290,10 @@ class Remove(Op):
self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other)
return type(self) == type(other) and self.inplace == other.inplace
def __hash__(self):
return hash(type(self))
return hash(type(self)) ^ hash(self.inplace)
def make_node(self, x, toRemove):
assert isinstance(x.type, TypedListType)
......@@ -191,13 +312,129 @@ class Remove(Op):
array with more than one element is ambiguous. Use a.any() or a.all()
being thrown when trying to remove a matrix from a matrices list
"""
if isinstance(toRemove, numpy.ndarray):
for y in range(out[0].__len__()):
if numpy.array_equal(out[0][y], toRemove):
for y in range(out[0].__len__()):
if node.inputs[0].ttype.values_eq(out[0][y], toRemove):
del out[0][y]
break
def __str__(self):
return self.__class__.__name__
remove = Remove()
class Reverse(Op):
def __init__(self, inplace=False):
self.inplace = inplace
if self.inplace:
self.destroy_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other) and self.inplace == other.inplace
def __hash__(self):
return hash(type(self)) ^ hash(self.inplace)
def make_node(self, x):
assert isinstance(x.type, TypedListType)
return Apply(self, [x], [x.type()])
def perform(self, node, inp, (out, )):
if not self.inplace:
out[0] = list(inp[0])
else:
out[0].remove(toRemove)
out[0] = inp[0]
out[0].reverse()
def __str__(self):
return self.__class__.__name__
def c_code(self, node, name, inp, out, sub):
x_name = inp[0]
output_name = out[0]
fail = sub['fail']
if not self.inplace:
init = """
%(output_name)s = (PyListObject*) PyList_GetSlice((PyObject*) %(x_name)s, 0, PyList_GET_SIZE((PyObject*) %(x_name)s)) ;
""" % locals()
else:
init = """
%(output_name)s = %(x_name)s;
""" % locals()
return init + """
if(%(output_name)s==NULL){
%(fail)s
};
if(PyList_Reverse((PyObject*) %(output_name)s)==-1){
%(fail)s
};
Py_INCREF(%(output_name)s);
""" % locals()
def c_code_cache_version(self):
return (1,)
reverse = Reverse()
class Index(Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x, elem):
assert isinstance(x.type, TypedListType)
assert x.ttype == elem.type
return Apply(self, [x, elem], [T.scalar()])
def perform(self, node, (x, elem), (out, )):
"""
inelegant workaround for ValueError: The truth value of an
array with more than one element is ambiguous. Use a.any() or a.all()
being thrown when trying to remove a matrix from a matrices list
"""
for y in range(len(x)):
if node.inputs[0].ttype.values_eq(x[y], elem):
out[0] = numpy.asarray(y, dtype=theano.config.floatX)
break
def __str__(self):
return self.__class__.__name__
index_ = Index()
class Count(Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x, elem):
assert isinstance(x.type, TypedListType)
assert x.ttype == elem.type
return Apply(self, [x, elem], [T.scalar()])
def perform(self, node, (x, elem), (out, )):
"""
inelegant workaround for ValueError: The truth value of an
array with more than one element is ambiguous. Use a.any() or a.all()
being thrown when trying to remove a matrix from a matrices list
"""
out[0] = 0
for y in range(len(x)):
if node.inputs[0].ttype.values_eq(x[y], elem):
out[0] += 1
out[0] = numpy.asarray(out[0], dtype=theano.config.floatX)
def __str__(self):
return self.__class__.__name__
count = Count()
from theano import gof
from theano import compile
from theano.gof import TopoOptimizer
from theano.typed_list.basic import (Reverse,
Append, Extend, Insert, Remove)
@gof.local_optimizer([Append, Extend, Insert, Reverse, Remove], inplace=True)
def typed_list_inplace_opt(node):
if isinstance(node.op, (Append, Extend, Insert, Reverse, Remove)) \
and not node.op.inplace:
new_op = node.op.__class__(
inplace=True)
new_node = new_op(*node.inputs)
return [new_node]
return False
compile.optdb.register('typed_list_inplace_opt',
TopoOptimizer(typed_list_inplace_opt,
failure_callback=TopoOptimizer.warn_inplace), 60,
'fast_run', 'inplace')
......@@ -8,8 +8,11 @@ from theano import tensor as T
from theano.tensor.type_other import SliceType
from theano.typed_list.type import TypedListType
from theano.typed_list.basic import (GetItem, Insert,
Append, Extend, Remove)
Append, Extend, Remove, Reverse,
Index, Count)
from theano import sparse
from theano.tests import unittest_tools as utt
import scipy.sparse as sp
#took from tensors/tests/test_basic.py
......@@ -18,6 +21,25 @@ def rand_ranged_matrix(minimum, maximum, shape):
+ minimum, dtype=theano.config.floatX)
#took from sparse/tests/test_basic.py
def random_lil(shape, dtype, nnz):
rval = sp.lil_matrix(shape, dtype=dtype)
huge = 2 ** 30
for k in range(nnz):
# set non-zeros in random locations (row x, col y)
idx = numpy.random.random_integers(huge, size=2) % shape
value = numpy.random.rand()
#if dtype *int*, value will always be zeros!
if "int" in dtype:
value = int(value * 100)
# The call to tuple is needed as scipy 0.13.1 do not support
# ndarray with lenght 2 as idx tuple.
rval.__setitem__(
tuple(idx),
value)
return rval
class test_get_item(unittest.TestCase):
def setUp(self):
......@@ -46,7 +68,7 @@ class test_get_item(unittest.TestCase):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
mySymbolicScalar = T.scalar()
mySymbolicScalar = T.scalar(dtype='int64')
z = GetItem()(mySymbolicMatricesList, mySymbolicScalar)
......@@ -54,13 +76,15 @@ class test_get_item(unittest.TestCase):
z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(0)), x))
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(0,
dtype='int64')), x))
def test_interface(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
mySymbolicScalar = T.scalar()
mySymbolicScalar = T.scalar(dtype='int64')
z = mySymbolicMatricesList[mySymbolicScalar]
......@@ -69,14 +93,15 @@ class test_get_item(unittest.TestCase):
x = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(0)), x))
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(0,
dtype='int64')), x))
z = mySymbolicMatricesList[0: 1: 1]
z = mySymbolicMatricesList[0]
f = theano.function([mySymbolicMatricesList],
z)
self.assertTrue(numpy.array_equal(f([x]), [x]))
self.assertTrue(numpy.array_equal(f([x]), x))
def test_wrong_input(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
......@@ -216,7 +241,7 @@ class test_insert(unittest.TestCase):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
myScalar = T.scalar()
myScalar = T.scalar(dtype='int64')
z = Insert(True)(mySymbolicMatricesList, myScalar, myMatrix)
......@@ -227,13 +252,14 @@ class test_insert(unittest.TestCase):
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(1), y), [x, y]))
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(1,
dtype='int64'), y), [x, y]))
def test_sanity_check(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
myScalar = T.scalar()
myScalar = T.scalar(dtype='int64')
z = Insert()(mySymbolicMatricesList, myScalar, myMatrix)
......@@ -243,7 +269,25 @@ class test_insert(unittest.TestCase):
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(1), y), [x, y]))
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(1,
dtype='int64'), y), [x, y]))
def test_interface(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
myScalar = T.scalar(dtype='int64')
z = mySymbolicMatricesList.insert(myScalar, myMatrix)
f = theano.function([mySymbolicMatricesList, myScalar, myMatrix], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(1,
dtype='int64'), y), [x, y]))
class test_remove(unittest.TestCase):
......@@ -278,3 +322,192 @@ class test_remove(unittest.TestCase):
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y], y), [x]))
def test_interface(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
z = mySymbolicMatricesList.remove(myMatrix)
f = theano.function([mySymbolicMatricesList, myMatrix], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y], y), [x]))
class test_reverse(unittest.TestCase):
def test_inplace(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = Reverse(True)(mySymbolicMatricesList)
f = theano.function([mySymbolicMatricesList], z,
accept_inplace=True)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y]), [y, x]))
def test_sanity_check(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = Reverse()(mySymbolicMatricesList)
f = theano.function([mySymbolicMatricesList], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y]), [y, x]))
def test_interface(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = mySymbolicMatricesList.reverse()
f = theano.function([mySymbolicMatricesList], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y]), [y, x]))
class test_index(unittest.TestCase):
def test_sanity_check(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
z = Index()(mySymbolicMatricesList, myMatrix)
f = theano.function([mySymbolicMatricesList, myMatrix], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(f([x, y], y) == 1)
def test_interface(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
z = mySymbolicMatricesList.ind(myMatrix)
f = theano.function([mySymbolicMatricesList, myMatrix], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(f([x, y], y) == 1)
def test_non_tensor_type(self):
mySymbolicNestedMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)), 1)()
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = Index()(mySymbolicNestedMatricesList, mySymbolicMatricesList)
f = theano.function([mySymbolicNestedMatricesList,
mySymbolicMatricesList], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(f([[x, y], [x, y, y]], [x, y]) == 0)
def test_sparse(self):
mySymbolicSparseList = TypedListType(sparse.SparseType('csr',
theano.config.floatX))()
mySymbolicSparse = sparse.csr_matrix()
z = Index()(mySymbolicSparseList, mySymbolicSparse)
f = theano.function([mySymbolicSparseList, mySymbolicSparse], z)
x = sp.csr_matrix(random_lil((10, 40), theano.config.floatX, 3))
y = sp.csr_matrix(random_lil((10, 40), theano.config.floatX, 3))
self.assertTrue(f([x, y], y) == 1)
class test_count(unittest.TestCase):
def test_sanity_check(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
z = Count()(mySymbolicMatricesList, myMatrix)
f = theano.function([mySymbolicMatricesList, myMatrix], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(f([y, y, x, y], y) == 3)
def test_interface(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
myMatrix = T.matrix()
z = mySymbolicMatricesList.count(myMatrix)
f = theano.function([mySymbolicMatricesList, myMatrix], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(f([x, y], y) == 1)
def test_non_tensor_type(self):
mySymbolicNestedMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)), 1)()
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = Count()(mySymbolicNestedMatricesList, mySymbolicMatricesList)
f = theano.function([mySymbolicNestedMatricesList,
mySymbolicMatricesList], z)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(f([[x, y], [x, y, y]], [x, y]) == 1)
def test_sparse(self):
mySymbolicSparseList = TypedListType(sparse.SparseType('csr',
theano.config.floatX))()
mySymbolicSparse = sparse.csr_matrix()
z = Count()(mySymbolicSparseList, mySymbolicSparse)
f = theano.function([mySymbolicSparseList, mySymbolicSparse], z)
x = sp.csr_matrix(random_lil((10, 40), theano.config.floatX, 3))
y = sp.csr_matrix(random_lil((10, 40), theano.config.floatX, 3))
self.assertTrue(f([x, y, y], y) == 2)
import unittest
import numpy
import theano
import theano.typed_list
from theano import tensor as T
from theano.tensor.type_other import SliceType
from theano.typed_list.type import TypedListType
from theano.typed_list.basic import (GetItem, Insert,
Append, Extend, Remove, Reverse,
Index, Count)
from theano import In
#took from tensors/tests/test_basic.py
def rand_ranged_matrix(minimum, maximum, shape):
return numpy.asarray(numpy.random.rand(*shape) * (maximum - minimum)
+ minimum, dtype=theano.config.floatX)
class test_inplace(unittest.TestCase):
def test_reverse_inplace(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = Reverse()(mySymbolicMatricesList)
m = theano.compile.mode.get_default_mode().including("typed_list_inplace_opt")
f = theano.function([In(mySymbolicMatricesList, borrow=True,
mutable=True)], z, accept_inplace=True, mode=m)
self.assertTrue(f.maker.fgraph.toposort()[0].op.inplace)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y]), [y, x]))
def test_append_inplace(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
mySymbolicMatrix = T.matrix()
z = Append()(mySymbolicMatricesList, mySymbolicMatrix)
m = theano.compile.mode.get_default_mode().including("typed_list_inplace_opt")
f = theano.function([In(mySymbolicMatricesList, borrow=True,
mutable=True), In(mySymbolicMatrix, borrow=True,
mutable=True)], z, accept_inplace=True, mode=m)
self.assertTrue(f.maker.fgraph.toposort()[0].op.inplace)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], y), [x, y]))
def test_extend_inplace(self):
mySymbolicMatricesList1 = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
mySymbolicMatricesList2 = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
z = Extend()(mySymbolicMatricesList1, mySymbolicMatricesList2)
m = theano.compile.mode.get_default_mode().including("typed_list_inplace_opt")
f = theano.function([In(mySymbolicMatricesList1, borrow=True,
mutable=True), mySymbolicMatricesList2],
z, mode=m)
self.assertTrue(f.maker.fgraph.toposort()[0].op.inplace)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], [y]), [x, y]))
def test_insert_inplace(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
mySymbolicIndex = T.scalar(dtype='int64')
mySymbolicMatrix = T.matrix()
z = Insert()(mySymbolicMatricesList, mySymbolicIndex, mySymbolicMatrix)
m = theano.compile.mode.get_default_mode().including("typed_list_inplace_opt")
f = theano.function([In(mySymbolicMatricesList, borrow=True,
mutable=True), mySymbolicIndex, mySymbolicMatrix],
z, accept_inplace=True, mode=m)
self.assertTrue(f.maker.fgraph.toposort()[0].op.inplace)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x], numpy.asarray(1,
dtype='int64'), y), [x, y]))
def test_remove_inplace(self):
mySymbolicMatricesList = TypedListType(T.TensorType(
theano.config.floatX, (False, False)))()
mySymbolicMatrix = T.matrix()
z = Remove()(mySymbolicMatricesList, mySymbolicMatrix)
m = theano.compile.mode.get_default_mode().including("typed_list_inplace_opt")
f = theano.function([In(mySymbolicMatricesList, borrow=True,
mutable=True), In(mySymbolicMatrix, borrow=True,
mutable=True)], z, accept_inplace=True, mode=m)
self.assertTrue(f.maker.fgraph.toposort()[0].op.inplace)
x = rand_ranged_matrix(-1000, 1000, [100, 101])
y = rand_ranged_matrix(-1000, 1000, [100, 101])
self.assertTrue(numpy.array_equal(f([x, y], y), [x]))
......@@ -65,3 +65,46 @@ class TypedListType(gof.Type):
return self.ttype.get_depth() + 1
else:
return 0
def values_eq(self, a, b):
if not len(a) == len(b):
return False
for x in range(len(a)):
if not self.ttype.values_eq(a[x], b[x]):
return False
return True
def c_declare(self, name, sub):
return """
PyListObject* %(name)s;
""" % dict(name=name)
def c_init(self, name, sub):
return """
%(name)s = NULL;
""" % dict(name=name)
def c_extract(self, name, sub):
return """
if (!PyList_Check(py_%(name)s)) {
PyErr_SetString(PyExc_TypeError, "expected a list");
%(fail)s
}
%(name)s = (PyListObject*) (py_%(name)s);
""" % dict(name=name, fail=sub['fail'])
def c_sync(self, name, sub):
return """
Py_XDECREF(py_%(name)s);
py_%(name)s = (PyObject*)(%(name)s);
Py_INCREF(py_%(name)s);
""" % dict(name=name)
def c_cleanup(self, name, sub):
return ""
def c_code_cache_version(self):
return (1,)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论