提交 8da054b7 authored 作者: abergeron's avatar abergeron

Merge pull request #1994 from nouiz/lazy

[CRASH] fix tutorial example related to lazy evaluation.
......@@ -211,18 +211,18 @@ version that it produces in the code I gave above.
return self.ccode % locals()
add = BinaryDoubleOp(name = 'add',
fn = lambda x, y: x + y,
ccode = "%(z)s = %(x)s + %(y)s;")
add = BinaryDoubleOp(name='add',
fn=lambda x, y: x + y,
ccode="%(z)s = %(x)s + %(y)s;")
sub = BinaryDoubleOp(name = 'sub',
fn = lambda x, y: x - y,
ccode = "%(z)s = %(x)s - %(y)s;")
sub = BinaryDoubleOp(name='sub',
fn=lambda x, y: x - y,
ccode="%(z)s = %(x)s - %(y)s;")
mul = BinaryDoubleOp(name = 'mul',
fn = lambda x, y: x * y,
ccode = "%(z)s = %(x)s * %(y)s;")
mul = BinaryDoubleOp(name='mul',
fn=lambda x, y: x * y,
ccode="%(z)s = %(x)s * %(y)s;")
div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y,
ccode = "%(z)s = %(x)s / %(y)s;")
div = BinaryDoubleOp(name='div',
fn=lambda x, y: x / y,
ccode="%(z)s = %(x)s / %(y)s;")
......@@ -633,17 +633,17 @@ arithmetic operators:
def __str__(self):
return self.name
add = BinaryDoubleOp(name = 'add',
fn = lambda x, y: x + y)
add = BinaryDoubleOp(name='add',
fn=lambda x, y: x + y)
sub = BinaryDoubleOp(name = 'sub',
fn = lambda x, y: x - y)
sub = BinaryDoubleOp(name='sub',
fn=lambda x, y: x - y)
mul = BinaryDoubleOp(name = 'mul',
fn = lambda x, y: x * y)
mul = BinaryDoubleOp(name='mul',
fn=lambda x, y: x * y)
div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y)
div = BinaryDoubleOp(name='div',
fn=lambda x, y: x / y)
Instead of working directly on an instance of Op, we create a subclass of
Op that we can parametrize. All the operations we define are binary. They
......
......@@ -685,15 +685,19 @@ Modify and execute to work for a matrix of shape (20, 10).
class PyCUDADoubleOp(theano.Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, inp):
inp = cuda.basic_ops.gpu_contiguous(
cuda.basic_ops.as_cuda_ndarray_variable(inp))
assert inp.dtype == "float32"
return theano.Apply(self, [inp], [inp.type()])
def make_thunk(self, node, storage_map, _, _2):
mod = SourceModule("""
__global__ void my_fct(float * i0, float * o0, int size) {
......@@ -703,15 +707,16 @@ Modify and execute to work for a matrix of shape (20, 10).
}
}""")
pycuda_fct = mod.get_function("my_fct")
inputs = [ storage_map[v] for v in node.inputs]
outputs = [ storage_map[v] for v in node.outputs]
inputs = [storage_map[v] for v in node.inputs]
outputs = [storage_map[v] for v in node.outputs]
def thunk():
z = outputs[0]
if z[0] is None or z[0].shape!=inputs[0][0].shape:
if z[0] is None or z[0].shape != inputs[0][0].shape:
z[0] = cuda.CudaNdarray.zeros(inputs[0][0].shape)
grid = (int(numpy.ceil(inputs[0][0].size / 512.)),1)
grid = (int(numpy.ceil(inputs[0][0].size / 512.)), 1)
pycuda_fct(inputs[0][0], z[0], numpy.intc(inputs[0][0].size),
block=(512,1,1), grid=grid)
block=(512, 1, 1), grid=grid)
return thunk
......@@ -719,7 +724,7 @@ Use this code to test it:
>>> x = theano.tensor.fmatrix()
>>> f = theano.function([x], PyCUDADoubleOp()(x))
>>> xv=numpy.ones((4,5), dtype="float32")
>>> xv = numpy.ones((4, 5), dtype="float32")
>>> assert numpy.allclose(f(xv), xv*2)
>>> print numpy.asarray(f(xv))
......
......@@ -886,6 +886,11 @@ class VM_Linker(link.LocalLinker):
storage_map,
compute_map,
no_recycling))
if not hasattr(thunks[-1], 'lazy'):
# We don't want all ops maker to think about lazy Ops.
# So if they didn't specify that its lazy or not, it isn't.
# If this member isn't present, it will crash later.
thunks[-1].lazy = False
except Exception, e:
e.args = ("The following error happened while"
" compiling the node", node, "\n") + e.args
......
......@@ -9,7 +9,7 @@ if not theano.misc.pycuda_init.pycuda_available:
" with pycuda code.")
import theano.sandbox.cuda as cuda_ndarray
if cuda_ndarray.cuda_available == False:
if not cuda_ndarray.cuda_available:
from nose.plugins.skip import SkipTest
raise SkipTest('Optional package cuda disabled')
......
""" test code snippet in the Theano tutorials.
"""
import os, shutil, unittest
import os
import shutil
import unittest
from nose.plugins.skip import SkipTest
import numpy
from numpy import array
import theano
import theano.tensor as T
from theano import function
import numpy
from numpy import array
from theano import config
from theano.tests import unittest_tools as utt
......@@ -15,13 +20,13 @@ from theano.tensor.shared_randomstreams import RandomStreams
class T_extending(unittest.TestCase):
## All tests here belong to files in
## http://deeplearning.net/software/theano/extending
## Theano/doc/extending/*.txt
## Any change you do here also add it to the tutorial!
## This belongs to an entire folder since code-snippets are connected
## from one file to another .. and they do not make sense on their
## own.
# All tests here belong to files in
# http://deeplearning.net/software/theano/extending
# Theano/doc/extending/*.txt
# Any change you do here also add it to the tutorial!
# This belongs to an entire folder since code-snippets are connected
# from one file to another .. and they do not make sense on their
# own.
def test_extending_1(self):
......@@ -103,8 +108,8 @@ class T_extending(unittest.TestCase):
x, y = double('x'), double('y')
z = mul(x, y)
f = theano.function([x, y], z)
assert f(5, 6) == 30.0
assert f(5.6, 6.7) == 37.519999999999996
assert f(5, 6) == 30.0
assert f(5.6, 6.7) == 37.519999999999996
x = double('x')
self.assertRaises(AttributeError, mul, x, 2)
......@@ -156,18 +161,17 @@ class T_extending(unittest.TestCase):
def __str__(self):
return self.name
add = BinaryDoubleOp(name = 'add',
fn = lambda x, y: x + y)
add = BinaryDoubleOp(name='add',
fn=lambda x, y: x + y)
sub = BinaryDoubleOp(name = 'sub',
fn = lambda x, y: x - y)
sub = BinaryDoubleOp(name='sub',
fn=lambda x, y: x - y)
mul = BinaryDoubleOp(name = 'mul',
fn = lambda x, y: x * y)
div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y)
mul = BinaryDoubleOp(name='mul',
fn=lambda x, y: x * y)
div = BinaryDoubleOp(name='div',
fn=lambda x, y: x / y)
def test_extending_2(self):
'''
......@@ -220,22 +224,22 @@ class T_extending(unittest.TestCase):
def __str__(self):
return self.name
add = BinaryDoubleOp(name = 'add',
fn = lambda x, y: x + y)
add = BinaryDoubleOp(name='add',
fn=lambda x, y: x + y)
sub = BinaryDoubleOp(name = 'sub',
fn = lambda x, y: x - y)
sub = BinaryDoubleOp(name='sub',
fn=lambda x, y: x - y)
mul = BinaryDoubleOp(name = 'mul',
fn = lambda x, y: x * y)
mul = BinaryDoubleOp(name='mul',
fn=lambda x, y: x * y)
div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y)
div = BinaryDoubleOp(name='div',
fn=lambda x, y: x / y)
def c_declare(name, sub, check_input=True):
return """
double %(name)s;
""" % dict(name = name)
""" % dict(name=name)
double.c_declare = c_declare
......@@ -380,21 +384,21 @@ class T_extending(unittest.TestCase):
return self.ccode % locals()
add = BinaryDoubleOp(name = 'add',
fn = lambda x, y: x + y,
ccode = "%(z)s = %(x)s + %(y)s;")
add = BinaryDoubleOp(name='add',
fn=lambda x, y: x + y,
ccode="%(z)s = %(x)s + %(y)s;")
sub = BinaryDoubleOp(name = 'sub',
fn = lambda x, y: x - y,
ccode = "%(z)s = %(x)s - %(y)s;")
sub = BinaryDoubleOp(name='sub',
fn=lambda x, y: x - y,
ccode="%(z)s = %(x)s - %(y)s;")
mul = BinaryDoubleOp(name = 'mul',
fn = lambda x, y: x * y,
ccode = "%(z)s = %(x)s * %(y)s;")
mul = BinaryDoubleOp(name='mul',
fn=lambda x, y: x * y,
ccode="%(z)s = %(x)s * %(y)s;")
div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y,
ccode = "%(z)s = %(x)s / %(y)s;")
div = BinaryDoubleOp(name='div',
fn=lambda x, y: x / y,
ccode="%(z)s = %(x)s / %(y)s;")
from theano.gof import toolbox
......@@ -452,10 +456,10 @@ class T_extending(unittest.TestCase):
class T_introduction(unittest.TestCase):
## All tests here belong to
## http://deeplearning.net/software/theano/tutorial/introduction.html
## Theano/doc/tutorial/introduction.txt
## Any change you do here also add it to the tutorial !
# All tests here belong to
# http://deeplearning.net/software/theano/tutorial/introduction.html
# Theano/doc/tutorial/introduction.txt
# Any change you do here also add it to the tutorial !
def test_introduction_1(self):
import theano
......@@ -477,10 +481,10 @@ class T_introduction(unittest.TestCase):
class T_adding(unittest.TestCase):
## All tests here belong to
## http://deeplearning.net/software/theano/tutorial/adding.html
## Theano/doc/tutorial/adding.txt
## Any change you do here also add it to the tutorial !
# All tests here belong to
# http://deeplearning.net/software/theano/tutorial/adding.html
# Theano/doc/tutorial/adding.txt
# Any change you do here also add it to the tutorial !
def test_adding_1(self):
......@@ -508,10 +512,10 @@ class T_adding(unittest.TestCase):
class T_examples(unittest.TestCase):
## All tests here belog to
## http://deeplearning.net/software/theano/tutorial/examples.html
## Theano/doc/tutorial/examples.txt
## Any change you do here also add it to the tutorial !
# All tests here belog to
# http://deeplearning.net/software/theano/tutorial/examples.html
# Theano/doc/tutorial/examples.txt
# Any change you do here also add it to the tutorial !
def test_examples_1(self):
x = T.dmatrix('x')
......@@ -747,10 +751,10 @@ class T_examples(unittest.TestCase):
class T_aliasing(unittest.TestCase):
## All tests here belog to
## http://deeplearning.net/software/theano/tutorial/aliasing.html
## Theano/doc/tutorial/aliasing.txt
## Any change you do here also add it to the tutorial !
# All tests here belog to
# http://deeplearning.net/software/theano/tutorial/aliasing.html
# Theano/doc/tutorial/aliasing.txt
# Any change you do here also add it to the tutorial !
def test_aliasing_1(self):
......@@ -782,7 +786,7 @@ class T_aliasing(unittest.TestCase):
s.set_value(
## some_inplace_fn
# some_inplace_fn
s.get_value(borrow=True).__imul__(2),
borrow=True)
......@@ -797,12 +801,11 @@ class T_aliasing(unittest.TestCase):
f = theano.function([theano.In(x, borrow=True)], theano.Out(y, borrow=True))
class T_loading_and_saving(unittest.TestCase):
## All tests here belong to
## http://deeplearning.net/software/theano/tutorial/loading_and_saving.html
## Theano/doc/tutorial/loading_and_saving.txt
## Any change you do here also add it to the tutorial !
# All tests here belong to
# http://deeplearning.net/software/theano/tutorial/loading_and_saving.html
# Theano/doc/tutorial/loading_and_saving.txt
# Any change you do here also add it to the tutorial !
def test_loading_and_saving_1(self):
......@@ -855,11 +858,12 @@ class T_loading_and_saving(unittest.TestCase):
if tmpdir is not None:
shutil.rmtree(tmpdir)
class T_modes(unittest.TestCase):
## All tests here belog to
## http://deeplearning.net/software/theano/tutorial/modes.html
## Theano/doc/tutorial/modes.txt
## Any change you do here also add it to the tutorial !
# All tests here belog to
# http://deeplearning.net/software/theano/tutorial/modes.html
# Theano/doc/tutorial/modes.txt
# Any change you do here also add it to the tutorial !
def test_modes_1(self):
......@@ -868,15 +872,15 @@ class T_modes(unittest.TestCase):
f = theano.function([x], 10*x, mode='DEBUG_MODE')
assert numpy.all(f([5]) == [50.])
assert numpy.all(f([0]) == [0.] )
assert numpy.all(f([0]) == [0.])
assert numpy.all(f([7]) == [70.])
class T_using_gpu(unittest.TestCase):
## All tests here belog to
## http://deeplearning.net/software/theano/tutorial/using_gpu.html
## Theano/doc/tutorial/using_gpu.txt
## Any change you do here also add it to the tutorial !
class T_using_gpu(unittest.TestCase):
# All tests here belog to
# http://deeplearning.net/software/theano/tutorial/using_gpu.html
# Theano/doc/tutorial/using_gpu.txt
# Any change you do here also add it to the tutorial !
def test_using_gpu_1(self):
# I'm checking if this compiles and runs
......@@ -907,9 +911,7 @@ class T_using_gpu(unittest.TestCase):
else:
assert numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()])
def test_using_gpu_2(self):
if theano.config.device.find('gpu') > -1:
from theano import function, config, shared, sandbox
......@@ -972,6 +974,61 @@ class T_using_gpu(unittest.TestCase):
assert not numpy.any([isinstance(x.op, T.Elemwise)
for x in f.maker.fgraph.toposort()])
def test_using_gpu_pycudaop(self):
import theano.misc.pycuda_init
if not theano.misc.pycuda_init.pycuda_available:
raise SkipTest("Pycuda not installed. Skip test of theano op"
" with pycuda code.")
from pycuda.compiler import SourceModule
import theano.sandbox.cuda as cuda
import theano.sandbox.cuda as cuda_ndarray
if not cuda_ndarray.cuda_available:
raise SkipTest('Optional package cuda disabled')
class PyCUDADoubleOp(theano.Op):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, inp):
inp = cuda.basic_ops.gpu_contiguous(
cuda.basic_ops.as_cuda_ndarray_variable(inp))
assert inp.dtype == "float32"
return theano.Apply(self, [inp], [inp.type()])
def make_thunk(self, node, storage_map, _, _2):
mod = SourceModule("""
__global__ void my_fct(float * i0, float * o0, int size) {
int i = blockIdx.x*blockDim.x + threadIdx.x;
if(i<size){
o0[i] = i0[i]*2;
}
}""")
pycuda_fct = mod.get_function("my_fct")
inputs = [storage_map[v] for v in node.inputs]
outputs = [storage_map[v] for v in node.outputs]
def thunk():
z = outputs[0]
if z[0] is None or z[0].shape != inputs[0][0].shape:
z[0] = cuda.CudaNdarray.zeros(inputs[0][0].shape)
grid = (int(numpy.ceil(inputs[0][0].size / 512.)), 1)
pycuda_fct(inputs[0][0], z[0],
numpy.intc(inputs[0][0].size),
block=(512, 1, 1), grid=grid)
return thunk
x = theano.tensor.fmatrix()
f = theano.function([x], PyCUDADoubleOp()(x))
xv = numpy.ones((4, 5), dtype="float32")
assert numpy.allclose(f(xv), xv*2)
# print numpy.asarray(f(xv))
# Used in T_fibby
class Fibby(theano.Op):
......@@ -1024,10 +1081,10 @@ class Fibby(theano.Op):
class T_fibby(unittest.TestCase):
## All tests here belong to
## http://deeplearning.net/software/theano/extending/fibby.html
## Theano/doc/extending/fibby.txt
## Any change you do here also add it to the tutorial !
# All tests here belong to
# http://deeplearning.net/software/theano/extending/fibby.html
# Theano/doc/extending/fibby.txt
# Any change you do here also add it to the tutorial !
def test_fibby_1(self):
......@@ -1080,10 +1137,10 @@ class T_fibby(unittest.TestCase):
class T_graphstructures(unittest.TestCase):
## All tests here belong to
## http://deeplearning.net/software/theano/extending/graphstructures.html
## Theano/doc/extending/graphstructures.txt
## Any change you do here also add it to the tutorial !
# All tests here belong to
# http://deeplearning.net/software/theano/extending/graphstructures.html
# Theano/doc/extending/graphstructures.txt
# Any change you do here also add it to the tutorial !
def test_graphstructures_1(self):
......@@ -1145,10 +1202,10 @@ class T_graphstructures(unittest.TestCase):
class T_scan(unittest.TestCase):
## All tests here belong to
## http://deeplearning.net/software/theano/tutorial/loop.html
## Theano/doc/tutorial/loop.txt
## Any change you do here also add it to the tutorial !
# All tests here belong to
# http://deeplearning.net/software/theano/tutorial/loop.html
# Theano/doc/tutorial/loop.txt
# Any change you do here also add it to the tutorial !
def test_elemwise(self):
# defining the tensor variables
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论