提交 895dd59c authored 作者: Frederic Bastien's avatar Frederic Bastien

Make CudaNdarray DimShuffle return error as Tensor instead of returning bad value.

上级 67a656a5
...@@ -2980,11 +2980,17 @@ CudaNdarray_dimshuffle(CudaNdarray * self, unsigned int len, const int * pattern ...@@ -2980,11 +2980,17 @@ CudaNdarray_dimshuffle(CudaNdarray * self, unsigned int len, const int * pattern
newdims[i] = 1; newdims[i] = 1;
newstrides[i] = 0; newstrides[i] = 0;
} }
else if(dims_taken[pattern[i]])
{
PyErr_SetString(PyExc_ValueError, "Cudandarray_dimshuffle: The same input dimension may not appear twice in the list of output dimensions");
free(newdims);
return -1;
}
else else
{ {
if ((dims_taken[pattern[i]]) || (pattern[i]>= self->nd)) if ((dims_taken[pattern[i]]) || (pattern[i]>= self->nd))
{ {
PyErr_SetString(PyExc_ValueError, "invalid pattern for Cudandarray_dimshuffle"); PyErr_SetString(PyExc_ValueError, "Cudandarray_dimshuffle: invalid pattern for Cudandarray_dimshuffle");
free(newdims); free(newdims);
return -1; return -1;
} }
...@@ -2993,6 +2999,16 @@ CudaNdarray_dimshuffle(CudaNdarray * self, unsigned int len, const int * pattern ...@@ -2993,6 +2999,16 @@ CudaNdarray_dimshuffle(CudaNdarray * self, unsigned int len, const int * pattern
dims_taken[pattern[i]] = 1; dims_taken[pattern[i]] = 1;
} }
} }
//Check if we dropped not broadcastable dims
for (int i = 0; i < self->nd; ++i)
{
if (dims_taken[i]==0 && CudaNdarray_HOST_DIMS(self)[i]!=1)
{
PyErr_SetString(PyExc_ValueError, "Cudandarray_dimshuffle: You cannot drop a non-broadcastable dimension.");
free(newdims);
return -1;
}
}
//swap this structure in for the one in self, and sync to the card //swap this structure in for the one in self, and sync to the card
if (CudaNdarray_set_nd(self, len)) if (CudaNdarray_set_nd(self, len))
{ {
......
import time, copy, sys, unittest
from theano.tests import unittest_tools as utt from theano.tests import unittest_tools as utt
import time, copy, sys
import theano import theano
import theano.sandbox.cuda as cuda_ndarray import theano.sandbox.cuda as cuda_ndarray
# Skip test if cuda_ndarray is not available. # Skip test if cuda_ndarray is not available.
...@@ -154,14 +156,64 @@ def test_nvcc_bug(): ...@@ -154,14 +156,64 @@ def test_nvcc_bug():
assert numpy.allclose(a+a, numpy.asarray(c)) assert numpy.allclose(a+a, numpy.asarray(c))
assert numpy.allclose(a, numpy.asarray(d)) assert numpy.allclose(a, numpy.asarray(d))
def test_dimshuffle(): class test_DimShuffle(unittest.TestCase):
def test_dimshuffle(self):
utt.seed_rng() utt.seed_rng()
rng = numpy.random.RandomState(utt.fetch_seed()) rng = numpy.random.RandomState(utt.fetch_seed())
a = theano._asarray(rng.randn(3,11), dtype='float32') # 2d -> 0d
a = theano._asarray(rng.randn(1,1), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(numpy.transpose(a), cuda_ndarray.dimshuffle(b,()))
# Test when we drop a axis that don't have shape 1
a = theano._asarray(rng.randn(2,1), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
self.assertRaises(ValueError, cuda_ndarray.dimshuffle, b,())
# Test that we can't take a dimensions multiple time
a = theano._asarray(rng.randn(2,1), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
self.assertRaises(ValueError, cuda_ndarray.dimshuffle, b,(1,1))
# 1d
a = theano._asarray(rng.randn(3,), dtype='float32')
b = cuda_ndarray.CudaNdarray(a) b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(numpy.transpose(a), cuda_ndarray.dimshuffle(b,(0,)))
assert numpy.allclose(a[None,:,None], cuda_ndarray.dimshuffle(b,(-1,0,-1)))
# 2d
a = theano._asarray(rng.randn(3,11), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(numpy.transpose(a), cuda_ndarray.dimshuffle(b,(1,0))) assert numpy.allclose(numpy.transpose(a), cuda_ndarray.dimshuffle(b,(1,0)))
assert numpy.allclose(numpy.transpose(a)[None,:,None,:,None], cuda_ndarray.dimshuffle(b,(-1,1,-1,0,-1)))
# 2d -> 1d
a = theano._asarray(rng.randn(1,11), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(a[:,], cuda_ndarray.dimshuffle(b,(1,)))
a = theano._asarray(rng.randn(11,1), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(a.reshape((11,)), cuda_ndarray.dimshuffle(b,(0,)))
# 3d
a = theano._asarray(rng.randn(3,4,5), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(a, cuda_ndarray.dimshuffle(b,(0,1,2)))
assert numpy.allclose(numpy.swapaxes(a,0,1), cuda_ndarray.dimshuffle(b,(1,0,2)))
assert numpy.allclose(numpy.swapaxes(a,0,2), cuda_ndarray.dimshuffle(b,(2,1,0)))
assert numpy.allclose(numpy.swapaxes(a,1,2), cuda_ndarray.dimshuffle(b,(0,2,1)))
assert numpy.allclose(numpy.swapaxes(a,1,2)[None,:,None,:,:,None], cuda_ndarray.dimshuffle(b,(-1,0,-1,2,1,-1)))
# 4d
a = theano._asarray(rng.randn(3,11,4,5), dtype='float32')
b = cuda_ndarray.CudaNdarray(a)
assert numpy.allclose(numpy.swapaxes(a,0,1), cuda_ndarray.dimshuffle(b,(1,0,2,3)))
assert numpy.allclose(numpy.swapaxes(a,0,2), cuda_ndarray.dimshuffle(b,(2,1,0,3)))
assert numpy.allclose(numpy.swapaxes(a,0,3), cuda_ndarray.dimshuffle(b,(3,1,2,0)))
assert numpy.allclose(numpy.swapaxes(a,0,3), cuda_ndarray.dimshuffle(b,(3,1,2,0)))
assert numpy.allclose(numpy.swapaxes(a,0,3)[None,:,None,:,:,:], cuda_ndarray.dimshuffle(b,(-1,3,-1,1,2,0)))
def test_dot(): def test_dot():
print >>sys.stdout, 'starting test_dot' print >>sys.stdout, 'starting test_dot'
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论