提交 c85d1953 authored 作者: abergeron's avatar abergeron

Merge pull request #2067 from nouiz/mixed

Mixed
...@@ -169,7 +169,7 @@ Here is the state of that vision as of December 3th, 2013 (after Theano release ...@@ -169,7 +169,7 @@ Here is the state of that vision as of December 3th, 2013 (after Theano release
0.6): 0.6):
* We support tensors using the `numpy.ndarray` object and we support many operations on them. * We support tensors using the `numpy.ndarray` object and we support many operations on them.
* We support sparse types by using the `scipy.{csc,csr}_matrix` object and support some operations on them. * We support sparse types by using the `scipy.{csc,csr,bsr}_matrix` object and support some operations on them.
* We have started implementing/wrapping more advanced linear algebra operations. * We have started implementing/wrapping more advanced linear algebra operations.
* We have many graph transformations that cover the 4 categories listed above. * We have many graph transformations that cover the 4 categories listed above.
* We can improve the graph transformation with better storage optimization * We can improve the graph transformation with better storage optimization
...@@ -184,10 +184,10 @@ Here is the state of that vision as of December 3th, 2013 (after Theano release ...@@ -184,10 +184,10 @@ Here is the state of that vision as of December 3th, 2013 (after Theano release
* We have a CUDA backend for tensors of type `float32` only. * We have a CUDA backend for tensors of type `float32` only.
* Efforts have begun towards a generic GPU ndarray (GPU tensor) (started in the * Efforts have begun towards a generic GPU ndarray (GPU tensor) (started in the
`libgpuarray <https://github.com/abergeron/libgpuarray>`_ project) `libgpuarray <https://github.com/Theano/libgpuarray>`_ project)
* Move GPU backend outside of Theano (on top of PyCUDA/PyOpenCL) * Move GPU backend outside of Theano.
* Will provide better support for GPU on Windows and use an OpenCL backend on CPU. * Will provide better support for GPU on Windows and support an OpenCL backend on CPU.
* Loops work, but not all related optimizations are currently done. * Loops work, but not all related optimizations are currently done.
* The cvm linker allows lazy evaluation. It is the current default linker. * The cvm linker allows lazy evaluation. It is the current default linker.
......
...@@ -195,8 +195,12 @@ def function(inputs, outputs=None, mode=None, updates=None, givens=None, ...@@ -195,8 +195,12 @@ def function(inputs, outputs=None, mode=None, updates=None, givens=None,
last_frame = stack[idx] last_frame = stack[idx]
if (last_frame[0] == source_file or last_frame[0] == compiled_file): if (last_frame[0] == source_file or last_frame[0] == compiled_file):
func_frame = stack[idx - 1] func_frame = stack[idx - 1]
while "theano/gof" in func_frame[0] and idx > 0:
idx -= 1
# This can hapen if we call var.eval()
func_frame = stack[idx - 1]
name = func_frame[0] + ':' + str(func_frame[1]) name = func_frame[0] + ':' + str(func_frame[1])
if updates is None: if updates is None:
updates = [] updates = []
......
...@@ -79,6 +79,7 @@ class SymbolicInput(object): ...@@ -79,6 +79,7 @@ class SymbolicInput(object):
return str(self) return str(self)
# TODO: FB: I think this isn't used, confirm this and remove.
class SymbolicInputKit(object): class SymbolicInputKit(object):
""" """
Represents a group ("kit") of SymbolicInputs. If fed into function or Represents a group ("kit") of SymbolicInputs. If fed into function or
......
...@@ -10,7 +10,7 @@ from theano import tensor ...@@ -10,7 +10,7 @@ from theano import tensor
import theano.tests.unittest_tools as utt import theano.tests.unittest_tools as utt
import theano.sandbox.cuda as cuda_ndarray import theano.sandbox.cuda as cuda_ndarray
if cuda_ndarray.cuda_available == False: if not cuda_ndarray.cuda_available:
raise SkipTest('Optional package cuda disabled') raise SkipTest('Optional package cuda disabled')
from theano.sandbox.cuda.basic_ops import (GpuDimShuffle, from theano.sandbox.cuda.basic_ops import (GpuDimShuffle,
...@@ -31,6 +31,7 @@ else: ...@@ -31,6 +31,7 @@ else:
def setup(): def setup():
utt.seed_rng() utt.seed_rng()
def blocksparse_data(): def blocksparse_data():
nInputBlock = 128 nInputBlock = 128
nOutputBlock = 64 nOutputBlock = 64
...@@ -41,13 +42,18 @@ def blocksparse_data(): ...@@ -41,13 +42,18 @@ def blocksparse_data():
batchSize = 2 batchSize = 2
input = randn(batchSize, inputWindowSize, inputSize).astype('float32') input = randn(batchSize, inputWindowSize, inputSize).astype('float32')
inputIndice = numpy.vstack(numpy.random.permutation(nInputBlock)[:inputWindowSize] for _ in range(batchSize)) permutation = numpy.random.permutation
outputIndice = numpy.vstack(numpy.random.permutation(nOutputBlock)[:outputWindowSize] for _ in range(batchSize)) inputIndice = numpy.vstack(permutation(nInputBlock)[:inputWindowSize]
weight = randn(nInputBlock, nOutputBlock, inputSize, outputSize).astype('float32') for _ in range(batchSize))
outputIndice = numpy.vstack(permutation(nOutputBlock)[:outputWindowSize]
for _ in range(batchSize))
weight = randn(nInputBlock, nOutputBlock,
inputSize, outputSize).astype('float32')
bias = randn(nOutputBlock, outputSize).astype('float32') bias = randn(nOutputBlock, outputSize).astype('float32')
return weight, input, inputIndice, bias, outputIndice return weight, input, inputIndice, bias, outputIndice
def blocksparse(W, h, iIdx, b, oIdx): def blocksparse(W, h, iIdx, b, oIdx):
o = b.take(oIdx, axis=0) o = b.take(oIdx, axis=0)
...@@ -72,7 +78,7 @@ def test_blocksparse(): ...@@ -72,7 +78,7 @@ def test_blocksparse():
o = sparse_block_dot_SS(W, h, iIdx, b, oIdx) o = sparse_block_dot_SS(W, h, iIdx, b, oIdx)
f = theano.function([W, h, iIdx, b, oIdx], o) f = theano.function([W, h, iIdx, b, oIdx], o, mode=mode_with_gpu)
W_val, h_val, iIdx_val, b_val, oIdx_val = blocksparse_data() W_val, h_val, iIdx_val, b_val, oIdx_val = blocksparse_data()
...@@ -94,10 +100,10 @@ def test_blocksparseF(): ...@@ -94,10 +100,10 @@ def test_blocksparseF():
o = sparse_block_dot_SS(GpuDimShuffle((False, False, False, False), o = sparse_block_dot_SS(GpuDimShuffle((False, False, False, False),
(0, 1, 3, 2))( (0, 1, 3, 2))(
as_cuda_ndarray_variable(W)), as_cuda_ndarray_variable(W)),
h, iIdx, b, oIdx) h, iIdx, b, oIdx)
f = theano.function([W, h, iIdx, b, oIdx], o) f = theano.function([W, h, iIdx, b, oIdx], o, mode=mode_with_gpu)
W_val, h_val, iIdx_val, b_val, oIdx_val = blocksparse_data() W_val, h_val, iIdx_val, b_val, oIdx_val = blocksparse_data()
...@@ -120,7 +126,8 @@ def test_blocksparse_grad(): ...@@ -120,7 +126,8 @@ def test_blocksparse_grad():
def f(b, h, W): def f(b, h, W):
return sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx) return sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx)
utt.verify_grad(f, [b_val, h_val, W_val]) utt.verify_grad(f, [b_val, h_val, W_val], mode=mode_with_gpu)
def test_blocksparse_grad_1(): def test_blocksparse_grad_1():
# This tests that we correctly handle cases where dimensions are 1. # This tests that we correctly handle cases where dimensions are 1.
...@@ -136,7 +143,7 @@ def test_blocksparse_grad_1(): ...@@ -136,7 +143,7 @@ def test_blocksparse_grad_1():
def f(b, h, W): def f(b, h, W):
return sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx) return sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx)
utt.verify_grad(f, [b_val, h_val, W_val]) utt.verify_grad(f, [b_val, h_val, W_val], mode=mode_with_gpu)
def test_blocksparse_grad_shape(): def test_blocksparse_grad_shape():
...@@ -180,7 +187,11 @@ def test_blocksparse_grad_merge(): ...@@ -180,7 +187,11 @@ def test_blocksparse_grad_merge():
f1 = theano.function([h, iIdx, b, oIdx], updates=[(W, upd)], f1 = theano.function([h, iIdx, b, oIdx], updates=[(W, upd)],
mode=mode_with_gpu) mode=mode_with_gpu)
# not running with mode=gpu ensures that the elemwise is not merged in # not running with mode=gpu ensures that the elemwise is not merged in
f2 = theano.function([h, iIdx, b, oIdx], updates=[(W, upd)]) mode = None
if theano.config.mode == 'FAST_COMPILE':
mode = theano.compile.mode.get_mode('FAST_RUN')
f2 = theano.function([h, iIdx, b, oIdx], updates=[(W, upd)], mode=mode)
f2(h_val, iIdx_val, b_val, oIdx_val) f2(h_val, iIdx_val, b_val, oIdx_val)
W_ref = W.get_value() W_ref = W.get_value()
......
...@@ -554,7 +554,12 @@ class GPU_mrg_uniform(mrg_uniform_base, GpuOp): ...@@ -554,7 +554,12 @@ class GPU_mrg_uniform(mrg_uniform_base, GpuOp):
otype = 'double' otype = 'double'
NORM = '4.656612873077392578125e-10' NORM = '4.656612873077392578125e-10'
return """ return """
static int %(nodename)s_printed_warning = 0; // FB: I disable the printing of the warning, as we
//receive too much email about this and this don't help
//people. I'm not even sure if the "fix" to give the info about
//the shape statically give a speed up. So I consider this
//warning as useless until proved it can speed the user code.
static int %(nodename)s_printed_warning = 1;
static __global__ void %(nodename)s_mrg_uniform( static __global__ void %(nodename)s_mrg_uniform(
%(otype)s*sample_data, %(otype)s*sample_data,
......
...@@ -19,7 +19,7 @@ from theano.gof.python25 import all, any, product ...@@ -19,7 +19,7 @@ from theano.gof.python25 import all, any, product
from theano.tensor.basic import _allclose from theano.tensor.basic import _allclose
if not enable_sparse: if not enable_sparse:
raise SkipTest('Optional package sparse disabled') raise SkipTest('Optional package SciPy not installed')
from theano.sparse.basic import _is_dense, _is_sparse, _mtypes from theano.sparse.basic import _is_dense, _is_sparse, _mtypes
from theano.sparse.basic import _is_dense_variable, _is_sparse_variable from theano.sparse.basic import _is_dense_variable, _is_sparse_variable
......
"""Define RModule, a Module providing random number streams in Theano graphs."""
__docformat__ = "restructuredtext en"
import sys
if sys.version_info[:2] >= (2,5):
from functools import partial
else:
from theano.gof.python25 import partial
import numpy
from copy import copy
from theano.compile import (SymbolicInputKit, SymbolicInput,
Module, module, Method, Member, In, Component)
from theano.gof import Container
from theano.gof.python25 import deque
from theano.tensor import raw_random
class KitComponent(Component):
"""
Represents a SymbolicInputKit (see io.py).
"""
def __init__(self, kit):
super(KitComponent, self).__init__()
self.kit = kit
def allocate(self, memo):
"""
Allocates a Container for each input in the kit. Sets a key in
the memo that maps the SymbolicInputKit to the list of
Containers.
"""
for input in self.kit.sinputs:
r = input.variable
if r not in memo:
input = copy(input)
input.value = Container(r, storage = [None])
memo[r] = input
def build(self, mode, memo):
return [memo[i.variable].value for i in self.kit.sinputs]
class RandomKit(SymbolicInputKit):
def __init__(self, name, value = None):
super(RandomKit, self).__init__(name)
self.value = value
def gen(self, op, *args, **kwargs):
random_state_variable = raw_random.random_state_type()
new_r, out = op(random_state_variable, *args, **kwargs)
self.add_input(SymbolicInput(random_state_variable, update = new_r))
out.rng = new_r
out.auto = self
return out
def distribute(self, value, indices, containers):
rg = partial(numpy.random.RandomState(int(value)).randint, 2**30)
elems = deque(zip(indices, containers))
i = 0
while elems:
index, container = elems.popleft()
while i <= index:
curr = rg()
i += 1
rs = numpy.random.RandomState(int(curr))
container.data = rs
def binomial(self, *args, **kwargs):
return self.gen(raw_random.binomial, *args, **kwargs)
def uniform(self, *args, **kwargs):
return self.gen(raw_random.uniform, *args, **kwargs)
def normal(self, *args, **kwargs):
return self.gen(raw_random.normal, *args, **kwargs)
def random_integers(self, *args, **kwargs):
return self.gen(raw_random.random_integers, *args, **kwargs)
rk = RandomKit('rk', 0xBAD5EED)
class RModule(Module):
"""Module providing random number streams in Theano graphs."""
def __init__(self, components=None, **kwcomponents):
if components is None:
components = {}
super(RModule, self).__init__(components, **kwcomponents)
self.random = RandomKit('rkit')
self._rkit = KitComponent(self.random)
def __wrapper__(self, x):
x = module.wrap(x)
if isinstance(x, Method):
x.kits += [self.random]
return x
def _instance_seed(self, inst, seed, recursive = True):
seedgen = numpy.random.RandomState(seed)
if recursive:
#Here, we recurse through all the components (inst2) contained in (inst)
#and seeds each subcomponent that is an RModule
for path, c in self.flat_components_map(True):
if isinstance(c, RModule):
inst2 = inst
for name in path:
inst2 = inst2[name]
# A Kit (c._rkit.kit) contains a list of io.SymbolicIn instances
# and the distribute method takes a value (seed), a list of indices
# and a list of corresponding Container instances. In this
# situation it will reseed all the rngs using the containers
# associated to them.
c._rkit.kit.distribute(seedgen.random_integers(2**30),
xrange(len(inst2._rkit)), inst2._rkit)
else:
self._rkit.kit.distribute(seedgen.random_integers(2**30), xrange(len(inst._rkit)), inst._rkit)
__docformat__ = "restructuredtext en"
import sys
import unittest
import numpy as N
from theano.tensor.deprecated.rmodule import *
from theano import tensor
from theano import compile, gof
if 0:
class T_test_module(unittest.TestCase):
def test_state_propagation(self):
if 1:
print >> sys.stderr, "RModule deprecated"
else:
x = tensor.vector()
rk = RandomKit('rk', 1000)
f = compile.function([x, (rk, [gof.Container(r = gof.generic, storage = [123], name='bla')])], rk.binomial(tensor.shape(x)))
print "RK", rk.value
f['rk'] = 9873456
print "RK", rk.value
rvals = [f([1,2,3,4,6, 7, 8]) for i in xrange(5)]
print rvals
for i in xrange(5-1):
for j in xrange(i+1, 5):
assert not N.all(rvals[i] == rvals[j])
def test_B(self):
"""Test that random numbers change from call to call!
Also, make sure that the seeding strategy doesn't change without failing a test.
Random numbers can't be too random or experiments aren't repeatable. Email theano-dev
before updating the `rvals` in this test.
"""
class B(RModule):
def __init__(self):
super(B, self).__init__()
self.x = compile.Member(tensor.dvector())
self.r = self.random.uniform(tensor.shape(self.x))
self.f = compile.Method([self.x], self.r)
class E(RModule):
def __init__(self):
super(E, self).__init__()
self.b = B()
self.f = compile.Method([self.b.x], self.b.r)
b = E()
m = b.make()
m.seed(1000)
#print m.f(N.ones(5))
#print m.f(N.ones(5))
#print m.f(N.ones(5))
rvals = ["0.74802375876 0.872308123517 0.294830748897 0.803123780003 0.6321109955",
"0.00168744844365 0.278638315678 0.725436793755 0.7788480779 0.629885140994",
"0.545561221664 0.0992011009108 0.847112593242 0.188015424144 0.158046201298",
"0.054382248842 0.563459168529 0.192757276954 0.360455221883 0.174805216702",
"0.961942907777 0.49657319422 0.0316111492826 0.0915054717012 0.195877184515"]
for i in xrange(5):
s = " ".join([str(n) for n in m.f(N.ones(5))])
print s
assert s == rvals[i]
if __name__ == '__main__':
from theano.tests import main
main("test_rmodule")
...@@ -695,6 +695,12 @@ class ConvOp(OpenMPOp): ...@@ -695,6 +695,12 @@ class ConvOp(OpenMPOp):
kshp_logical = self.kshp_logical kshp_logical = self.kshp_logical
if kshp_logical is None: if kshp_logical is None:
kshp_logical = kshp kshp_logical = kshp
else:
if kshp_logical[0] is None:
kshp_logical = (kshp[0], kshp_logical[1])
if kshp_logical[1] is None:
kshp_logical = (kshp_logical[0], kshp[1])
if numpy.any([x is None for x in kshp_logical]): if numpy.any([x is None for x in kshp_logical]):
kshp = tuple(filtersflipped.shape[2:]) kshp = tuple(filtersflipped.shape[2:])
......
import unittest import unittest
from nose.plugins.skip import SkipTest
import numpy import numpy
import theano import theano
...@@ -12,7 +13,12 @@ from theano.typed_list.basic import (GetItem, Insert, ...@@ -12,7 +13,12 @@ from theano.typed_list.basic import (GetItem, Insert,
Index, Count, Length) Index, Count, Length)
from theano import sparse from theano import sparse
from theano.tests import unittest_tools as utt from theano.tests import unittest_tools as utt
import scipy.sparse as sp # TODO, handle the case where scipy isn't installed.
try:
import scipy.sparse as sp
scipy_imported = True
except ImportError:
scipy_imported = False
#took from tensors/tests/test_basic.py #took from tensors/tests/test_basic.py
...@@ -435,6 +441,8 @@ class test_index(unittest.TestCase): ...@@ -435,6 +441,8 @@ class test_index(unittest.TestCase):
self.assertTrue(f([[x, y], [x, y, y]], [x, y]) == 0) self.assertTrue(f([[x, y], [x, y, y]], [x, y]) == 0)
def test_sparse(self): def test_sparse(self):
if not scipy_imported:
raise SkipTest('Optional package SciPy not installed')
mySymbolicSparseList = TypedListType(sparse.SparseType('csr', mySymbolicSparseList = TypedListType(sparse.SparseType('csr',
theano.config.floatX))() theano.config.floatX))()
mySymbolicSparse = sparse.csr_matrix() mySymbolicSparse = sparse.csr_matrix()
...@@ -499,6 +507,8 @@ class test_count(unittest.TestCase): ...@@ -499,6 +507,8 @@ class test_count(unittest.TestCase):
self.assertTrue(f([[x, y], [x, y, y]], [x, y]) == 1) self.assertTrue(f([[x, y], [x, y, y]], [x, y]) == 1)
def test_sparse(self): def test_sparse(self):
if not scipy_imported:
raise SkipTest('Optional package SciPy not installed')
mySymbolicSparseList = TypedListType(sparse.SparseType('csr', mySymbolicSparseList = TypedListType(sparse.SparseType('csr',
theano.config.floatX))() theano.config.floatX))()
mySymbolicSparse = sparse.csr_matrix() mySymbolicSparse = sparse.csr_matrix()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论