提交 19de7f5d authored 作者: bergstrj@iro.umontreal.ca's avatar bergstrj@iro.umontreal.ca

merged

import unittest
from core import build_mode, pop_mode
from ops import *
class _testCase_add_build_mode(unittest.TestCase):
def setUp(self):
build_mode()
numpy.random.seed(44)
def tearDown(self):
pop_mode()
class _testCase_dot(unittest.TestCase):
def setUp(self):
build_eval_mode()
numpy.random.seed(44)
def tearDown(self):
pop_mode()
@staticmethod
def rand(*args):
return numpy.random.rand(*args)
def cmp_dot(self,x,y):
if 0:
def spec(x):
x = numpy.asarray(x)
return type(x), x.dtype, x.shape
zspec = dot.specs(spec(x), spec(y))
nz = numpy.dot(x,y)
self.failUnless(zspec == spec(nz))
self.failUnless(_approx_eq(dot(x,y), numpy.dot(x,y)))
def cmp_dot_comp(self, x,y):
x = numpy.asarray(x)
y = numpy.asarray(y)
z = dot(x,y)
p = compile.single(z)
if len(x.shape):
x[:] = numpy.random.rand(*x.shape)
else:
x.fill(numpy.random.rand(*x.shape))
if len(y.shape):
y[:] = numpy.random.rand(*y.shape)
else:
y.fill(numpy.random.rand(*y.shape))
p() # recalculate z
self.failUnless(_approx_eq(z, numpy.dot(x,y)))
def test_dot_0d_0d(self): self.cmp_dot(1.1, 2.2)
def test_dot_0d_1d(self): self.cmp_dot(1.1, self.rand(5))
def test_dot_0d_2d(self): self.cmp_dot(3.0, self.rand(6,7))
def test_dot_0d_3d(self): self.cmp_dot(3.0, self.rand(8,6,7))
def test_dot_1d_0d(self): self.cmp_dot(self.rand(5), 1.1 )
def test_dot_1d_1d(self): self.cmp_dot(self.rand(5), self.rand(5))
def test_dot_1d_2d(self): self.cmp_dot(self.rand(6), self.rand(6,7))
def test_dot_1d_3d(self): self.cmp_dot(self.rand(6), self.rand(8,6,7))
def test_dot_2d_0d(self): self.cmp_dot(self.rand(5,6), 1.0)
def test_dot_2d_1d(self): self.cmp_dot(self.rand(5,6), self.rand(6))
def test_dot_2d_2d(self): self.cmp_dot(self.rand(5,6), self.rand(6,7))
def test_dot_2d_3d(self): self.cmp_dot(self.rand(5,6), self.rand(8,6,7))
def test_dot_3d_0d(self): self.cmp_dot(self.rand(4,5,6), 1.0)
def test_dot_3d_1d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6))
def test_dot_3d_2d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6,7))
def test_dot_3d_3d(self): self.cmp_dot(self.rand(4,5,6), self.rand(8,6,7))
def test_dot_0d_0d_(self): self.cmp_dot_comp(1.1, 2.2)
def test_dot_0d_1d_(self): self.cmp_dot_comp(1.1, self.rand(5))
def test_dot_0d_2d_(self): self.cmp_dot_comp(3.0, self.rand(6,7))
def test_dot_0d_3d_(self): self.cmp_dot_comp(3.0, self.rand(8,6,7))
def test_dot_1d_0d_(self): self.cmp_dot_comp(self.rand(5), 1.1 )
def test_dot_1d_1d_(self): self.cmp_dot_comp(self.rand(5), self.rand(5))
def test_dot_1d_2d_(self): self.cmp_dot_comp(self.rand(6), self.rand(6,7))
def test_dot_1d_3d_(self): self.cmp_dot_comp(self.rand(6), self.rand(8,6,7))
def test_dot_2d_0d_(self): self.cmp_dot_comp(self.rand(5,6), 1.0)
def test_dot_2d_1d_(self): self.cmp_dot_comp(self.rand(5,6), self.rand(6))
def test_dot_2d_2d_(self): self.cmp_dot_comp(self.rand(5,6), self.rand(6,7))
def test_dot_2d_3d_(self): self.cmp_dot_comp(self.rand(5,6), self.rand(8,6,7))
def test_dot_3d_0d_(self): self.cmp_dot_comp(self.rand(4,5,6), 1.0)
def test_dot_3d_1d_(self): self.cmp_dot_comp(self.rand(4,5,6), self.rand(6))
def test_dot_3d_2d_(self): self.cmp_dot_comp(self.rand(4,5,6), self.rand(6,7))
def test_dot_3d_3d_(self): self.cmp_dot_comp(self.rand(4,5,6), self.rand(8,6,7))
def test_dot_fail_1_1(self):
x = numpy.random.rand(5)
y = numpy.random.rand(6)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_1_2(self):
x = numpy.random.rand(5)
y = numpy.random.rand(6,4)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_1_3(self):
x = numpy.random.rand(5)
y = numpy.random.rand(6,4,7)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_2_1(self):
x = numpy.random.rand(5,4)
y = numpy.random.rand(6)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_2_2(self):
x = numpy.random.rand(5,4)
y = numpy.random.rand(6,7)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_2_3(self):
x = numpy.random.rand(5,4)
y = numpy.random.rand(6,7,8)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_3_1(self):
x = numpy.random.rand(5,4,3)
y = numpy.random.rand(6)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_3_2(self):
x = numpy.random.rand(5,4,3)
y = numpy.random.rand(6,7)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_3_3(self):
x = numpy.random.rand(5,4,3)
y = numpy.random.rand(6,7,8)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
class gemm(omega_op):
def destroy_map(self):
return {self.out:[self.inputs[0]]}
def impl(z, a, x, y, b):
if b == 0.0:
if a == 1.0:
z[:] = numpy.dot(x,y)
elif a == -1.0:
z[:] = -numpy.dot(x,y)
else:
z[:] = a * numpy.dot(x,y)
elif b == 1.0:
if a == 1.0:
z += numpy.dot(x,y)
elif a == -1.0:
z -= numpy.dot(x,y)
else:
z += a * numpy.dot(x,y)
else:
z *= b
z += a * numpy.dot(x,y)
return z[:]
def grad(z, a, x, y, b, gz):
raise NotImplemented
def refresh(self, alloc = False):
z,a,x,y,b = self.inputs
self.out.shape = z.shape
self.out.dtype = z.dtype
if alloc:
self.out.data = z.data
def c_support_code(self):
return blas.cblas_header_text()
def c_libs(self):
return blas.ldflags()
def c_impl((_zin, _a, _x, _y, _b), (_z,)):
check_ab = """
{
if ((_a->descr->type_num != PyArray_DOUBLE)
&& (_a->descr->type_num != PyArray_FLOAT))
goto _dot_execute_fallback;
if ((_b->descr->type_num != PyArray_DOUBLE)
&& (_b->descr->type_num != PyArray_FLOAT))
goto _dot_execute_fallback;
}
"""
return blas.gemm_code( check_ab,
'(_a->descr->type_num == PyArray_FLOAT) ? (REAL)(((float*)_a->data)[0]) : (REAL)(((double*)_a->data)[0])',
'(_b->descr->type_num == PyArray_FLOAT) ? (REAL)(((float*)_b->data)[0]) : (REAL)(((double*)_b->data)[0])')
if __name__ == '__main__':
unittest.main()
...@@ -53,6 +53,20 @@ def verify_grad(testcase, op_cls, pt, n_tests=1, rng=numpy.random, eps=0.0000001 ...@@ -53,6 +53,20 @@ def verify_grad(testcase, op_cls, pt, n_tests=1, rng=numpy.random, eps=0.0000001
verify_grad.E_grad = 'gradient error exceeded tolerance' verify_grad.E_grad = 'gradient error exceeded tolerance'
#useful mostly for unit tests
def _approx_eq(a,b,eps=1.0e-9):
a = numpy.asarray(a)
b = numpy.asarray(b)
if a.shape != b.shape:
if _approx_eq.debug:
print a.shape, b.shape
return False
if numpy.max(numpy.abs(a-b)) >= eps:
if _approx_eq.debug:
print a, b
return False
return True
_approx_eq.debug = 0
def check_eq(self, node_in, node_out, arg_in, arg_out): def check_eq(self, node_in, node_out, arg_in, arg_out):
fn = Function([node_in], [node_out]) fn = Function([node_in], [node_out])
...@@ -97,16 +111,16 @@ class T_argmax(unittest.TestCase): ...@@ -97,16 +111,16 @@ class T_argmax(unittest.TestCase):
n = astensor(numpy.random.rand(2,3)) n = astensor(numpy.random.rand(2,3))
try: try:
eval_outputs(argmax(n,axis=3)) eval_outputs(argmax(n,axis=3))
self.fail()
except ValueError, e: except ValueError, e:
return return
self.fail()
def test2_invalid_neg(self): def test2_invalid_neg(self):
n = astensor(numpy.random.rand(2,3)) n = astensor(numpy.random.rand(2,3))
try: try:
eval_outputs(argmax(n,axis=-3)) eval_outputs(argmax(n,axis=-3))
self.fail()
except ValueError, e: except ValueError, e:
return return
self.fail()
def test2_valid_neg(self): def test2_valid_neg(self):
n = astensor(numpy.random.rand(2,3)) n = astensor(numpy.random.rand(2,3))
v,i = eval_outputs(argmax(n,axis=-1)) v,i = eval_outputs(argmax(n,axis=-1))
...@@ -178,19 +192,20 @@ class T_subtensor(unittest.TestCase): ...@@ -178,19 +192,20 @@ class T_subtensor(unittest.TestCase):
n = astensor(numpy.ones(())) n = astensor(numpy.ones(()))
try: try:
t = n[0] t = n[0]
self.fail()
except ValueError, e: except ValueError, e:
self.failUnless(e[0] is Subtensor.e_invalid) self.failUnless(e[0] is Subtensor.e_invalid)
return
self.fail()
def test1_err_bounds(self): def test1_err_bounds(self):
n = astensor(numpy.ones(3)) n = astensor(numpy.ones(3))
t = n[7] t = n[7]
self.failUnless(t.owner.__class__ is Subtensor) self.failUnless(t.owner.__class__ is Subtensor)
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
self.fail()
except Exception, e: except Exception, e:
if e[0] != 'index out of bounds': if e[0] != 'index out of bounds':
raise raise
self.fail()
def test1_ok_range_finite(self): def test1_ok_range_finite(self):
n = astensor(numpy.ones(3)*5) n = astensor(numpy.ones(3)*5)
t = n[0:2] t = n[0:2]
...@@ -209,9 +224,9 @@ class T_subtensor(unittest.TestCase): ...@@ -209,9 +224,9 @@ class T_subtensor(unittest.TestCase):
n = astensor(numpy.ones(1)) n = astensor(numpy.ones(1))
try: try:
t = n[0,0] t = n[0,0]
self.fail()
except ValueError, e: except ValueError, e:
self.failUnless(e[0] is Subtensor.e_invalid) self.failUnless(e[0] is Subtensor.e_invalid)
self.fail()
def test1_ok_elem(self): def test1_ok_elem(self):
n = astensor(numpy.ones(1)*5) n = astensor(numpy.ones(1)*5)
t = n[0] t = n[0]
...@@ -244,9 +259,9 @@ class T_subtensor(unittest.TestCase): ...@@ -244,9 +259,9 @@ class T_subtensor(unittest.TestCase):
self.failUnless(t.owner.__class__ is Subtensor) self.failUnless(t.owner.__class__ is Subtensor)
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
self.fail()
except IndexError, e: except IndexError, e:
return return
self.fail()
def test2_err_bounds1(self): def test2_err_bounds1(self):
n = astensor(numpy.ones((2,3))*5) n = astensor(numpy.ones((2,3))*5)
t = n[4:5,2] t = n[4:5,2]
...@@ -356,9 +371,10 @@ class T_abs(unittest.TestCase): ...@@ -356,9 +371,10 @@ class T_abs(unittest.TestCase):
def test_badgrad(self): def test_badgrad(self):
try: try:
verify_grad(self, T_abs.AbsBadGrad, [numpy.ones(())]) verify_grad(self, T_abs.AbsBadGrad, [numpy.ones(())])
self.fail()
except Exception, e: except Exception, e:
self.failUnless(str(e) == verify_grad.E_grad, str(e)) self.failUnless(str(e) == verify_grad.E_grad, str(e))
return
self.fail()
class T_fill(unittest.TestCase): class T_fill(unittest.TestCase):
def test0(self): def test0(self):
...@@ -425,9 +441,10 @@ class T_mul(unittest.TestCase): ...@@ -425,9 +441,10 @@ class T_mul(unittest.TestCase):
try: try:
check_eq2(self, [a,b], MulElemwise(a,b).out, check_eq2(self, [a,b], MulElemwise(a,b).out,
[numpy.ones(3), numpy.ones(4)], 1.0) [numpy.ones(3), numpy.ones(4)], 1.0)
self.fail()
except ValueError, e: except ValueError, e:
self.failUnless(e[0] is tensor._assert_same_shapes.E_shape) self.failUnless(e[0] is tensor._assert_same_shapes.E_shape)
return
self.fail()
class T_div(unittest.TestCase): class T_div(unittest.TestCase):
def setUp(self): def setUp(self):
...@@ -501,5 +518,124 @@ class _testCase_matinv(unittest.TestCase): ...@@ -501,5 +518,124 @@ class _testCase_matinv(unittest.TestCase):
"""Matrix reciprocal by gradient descent""" """Matrix reciprocal by gradient descent"""
self.assertEqual(('6.10141615619', '0.00703816291711'), self.mat_reciprocal(3)) self.assertEqual(('6.10141615619', '0.00703816291711'), self.mat_reciprocal(3))
class t_dot(unittest.TestCase):
def setUp(self):
numpy.random.seed(44)
@staticmethod
def rand(*args):
return numpy.random.rand(*args)
def cmp_dot(self,x,y):
#x, y are matrices or numbers
def spec(x):
x = numpy.asarray(x)
return type(x), x.dtype, x.shape
nz = numpy.dot(x,y)
tz = eval_outputs([dot(tinit(x), tinit(y))])
self.failUnless(tz.dtype == nz.dtype)
self.failUnless(tz.shape == nz.shape)
self.failUnless(_approx_eq(nz, tz))
def test_dot_0d_0d(self): self.cmp_dot(1.1, 2.2)
def test_dot_0d_1d(self): self.cmp_dot(1.1, self.rand(5))
def test_dot_0d_2d(self): self.cmp_dot(3.0, self.rand(6,7))
def test_dot_0d_3d(self): self.cmp_dot(3.0, self.rand(8,6,7))
def test_dot_1d_0d(self): self.cmp_dot(self.rand(5), 1.1 )
def test_dot_1d_1d(self): self.cmp_dot(self.rand(5), self.rand(5))
def test_dot_1d_2d(self): self.cmp_dot(self.rand(6), self.rand(6,7))
def test_dot_1d_3d(self): self.cmp_dot(self.rand(6), self.rand(8,6,7))
def test_dot_2d_0d(self): self.cmp_dot(self.rand(5,6), 1.0)
def test_dot_2d_1d(self): self.cmp_dot(self.rand(5,6), self.rand(6))
def test_dot_2d_2d(self): self.cmp_dot(self.rand(5,6), self.rand(6,7))
def test_dot_2d_3d(self): self.cmp_dot(self.rand(5,6), self.rand(8,6,7))
def test_dot_3d_0d(self): self.cmp_dot(self.rand(4,5,6), 1.0)
def test_dot_3d_1d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6))
def test_dot_3d_2d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6,7))
def test_dot_3d_3d(self): self.cmp_dot(self.rand(4,5,6), self.rand(8,6,7))
def not_aligned(self, x, y):
z = dot(x,y)
try:
tz = eval_outputs([z])
except ValueError, e:
self.failUnless(e[0] == 'objects are not aligned', e)
return
self.fail()
def test_align_1_1(self): self.not_aligned(self.rand(5), self.rand(6))
def test_align_1_2(self): self.not_aligned(self.rand(5), self.rand(6,4))
def test_align_1_3(self): self.not_aligned(self.rand(5), self.rand(6,4,7))
def test_align_2_1(self): self.not_aligned(self.rand(5,4), self.rand(6))
def test_align_2_1(self): self.not_aligned(self.rand(5,4), self.rand(6,7))
def test_align_2_3(self): self.not_aligned(self.rand(5,4), self.rand(6,7,8))
def test_align_3_1(self): self.not_aligned(self.rand(5,4,3), self.rand(6))
def test_align_3_2(self): self.not_aligned(self.rand(5,4,3), self.rand(6,7))
def test_align_3_3(self): self.not_aligned(self.rand(5,4,3), self.rand(6,7,8))
class t_gemm(unittest.TestCase):
def setUp(self):
numpy.random.seed(44)
_approx_eq.debug = 0
@staticmethod
def _gemm(z,a,x,y,b):
assert a.shape == ()
assert b.shape == ()
return b * z + a * numpy.dot(x,y)
@staticmethod
def rand(*args):
return numpy.random.rand(*args)
def cmp(self, z, a, x, y, b):
z,a,x,y,b = [numpy.asarray(p) for p in z,a,x,y,b]
cz = z.copy()
tz,ta,tx,ty,tb = [tinit(p) for p in z,a,x,y,b]
f = Function([tz,ta,tx,ty,tb], [gemm(tz,ta,tx,ty,tb)])
new_z = f(z,a,x,y,b)
_z = self._gemm(cz, a, x, y, b)
self.failUnless(z is new_z)
#print cz, _z, z, type(cz), type(_z), type(z)
#_approx_eq.debug = 1
self.failUnless(_approx_eq(_z, z))
if a == 0.0 and b == 1.0:
return
else:
self.failIf(numpy.all(cz == z))
def test0(self): self.cmp(1., 0., 1.0, 1.0, 1.0)
def test1(self): self.cmp(2., 0., 1.0, 1.0, 0.0)
def test2(self):
try:
self.cmp(2., 1.0, [3,2,1.], [[1],[2],[3.]], 1.0)
except ValueError, e:
self.failUnless(e[0] == Gemm.E_bcast)
return
self.fail()
def test3(self): self.cmp([2.], 1.,[3,2,1.], [[1],[2],[3.]], 1.0)
def test4(self): self.cmp(self.rand(3,4), 1.0,
self.rand(3,5), self.rand(5,4), 0.0)
def test5(self): self.cmp(self.rand(3,4), 1.0,
self.rand(3,5), self.rand(5,4), 1.0)
def test6(self): self.cmp(self.rand(3,4), 1.0,
self.rand(3,5), self.rand(5,4), -1.0)
def test7(self): self.cmp(self.rand(3,4), 0.0,
self.rand(3,5), self.rand(5,4), 0.0)
def test8(self): self.cmp(self.rand(3,4), 0.0,
self.rand(3,5), self.rand(5,4), 0.6)
def test9(self): self.cmp(self.rand(3,4), 0.0,
self.rand(3,5), self.rand(5,4), -1.0)
def test10(self):
_approx_eq.debug = 1
self.cmp(self.rand(3,4), -1.0, self.rand(3,5), self.rand(5,4), 0.0)
def test11(self): self.cmp(self.rand(3,4), -1.0,
self.rand(3,5), self.rand(5,4), 1.0)
def test12(self): self.cmp(self.rand(3,4), -1.0,
self.rand(3,5), self.rand(5,4), -1.0)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
import unittest
from gof import ResultBase, Op, Env, modes
import gof
from tensor import *
from tensor_ops import *
import numpy
import sys
from scipy import weave
def inputs():
l1 = [[1.0, 2.0], [3.0, 4.0]]
l2 = [[3.0, 4.0], [1.0, 2.0]]
l3 = numpy.ones((2, 3))
x = modes.build(tensor(l1, 'x'))
y = modes.build(tensor(l2, 'y'))
z = modes.build(tensor(l3, 'z'))
return x, y, z
def env(inputs, outputs, validate = True, features = []):
return Env(inputs, outputs, features = features, consistency_check = validate)
class _test_TensorOps(unittest.TestCase):
def test_0(self):
x, y, z = inputs()
# e = mul(add(x, y), 2)
e = (x + y) * 2
fn, i, o = gof.PerformLinker(env([x, y], [e])).make_thunk(True)
fn()
assert (e.data == numpy.array([[8, 12], [8, 12]])).all()
def test_1(self):
x, y, z = inputs()
e = dot(x, z).T
fn, i, o = gof.PerformLinker(env([x, z], [e])).make_thunk(True)
fn()
assert (e.data == numpy.array([[3, 3, 3], [7, 7, 7]]).T).all()
def test_2(self):
x, y, z = inputs()
x = x.data
y = weave.inline("""
PyObject* p = PyArray_Transpose(x_array, NULL);
return_val = p;
""", ['x'])
print y
# def test_0(self):
# x, y, z = inputs()
# e = transpose(x)
# g = env([x], [e])
# fn, (i, ), (o, ) = gof.cc.CLinker(g).make_thunk()
# # print sys.getrefcount(i.data)
# for blah in xrange(10000):
# i.data = numpy.ones((1000, 1000)) # [[1.0, 2.0], [3.0, 4.0]]
# fn()
# # print sys.getrefcount(i.data)
# # print sys.getrefcount(o.data)
# print o.data
# # assert res == numpy.asarray(arr)
# # def test_1(self):
# # x, y, z = inputs()
# # e = mul(add(x, y), div(x, y))
# # g = env([x, y], [e])
# # fn = gof.cc.CLinker(g).make_function()
# # assert fn(1.0, 2.0) == 1.5
# # assert e.data == 1.5
from core import *
import unittest
import gradient
#useful mostly for unit tests
def _approx_eq(a,b,eps=1.0e-9):
a = numpy.asarray(a)
b = numpy.asarray(b)
if a.shape != b.shape:
return False
return numpy.max(numpy.abs(a-b)) < eps
if 1: # run gradient tests
def _scalar(x):
rval = numpy.zeros(())
rval.itemset(x)
return rval
def _test_grad(self, op_cls, args, n_tests=1,eps=0.0000001, tol=0.0001):
"""unittest.TestCase.failUnless( analytic gradient matches finite-diff gradient )
The criterion is that every input gradient must match every
finite-difference gradient (using stepsize of eps) to relative precision
tol.
"""
def _finite_diff1(f, x, eps, f_of_x = None):
if f_of_x is None: f_of_x = f(x)
y_eps = f(x+eps)
return (y_eps - f_of_x) / eps
def _scalar_f(op_cls, args, R, arg_idx, coord=None):
m = args[arg_idx].data
if () == m.shape:
def rval(x):
old_x = float(m)
m.itemset(x)
y = float(sum(mul_elemwise(R, op_cls(*args))).data)
m.itemset(old_x)
return y
return rval
else:
def rval(x):
old_x = m.__getitem__(coord)
#print old_x.shape
#print x.shape
m.__setitem__(coord, x)
y = float(sum(mul_elemwise(R, op_cls(*args))).data)
m.__setitem__(coord, old_x)
return y
return rval
self.failUnless(hasattr(op_cls, 'update_gradient'), op_cls)
op_out = op_cls(*args)
if len(op_out.owner.outputs) > 1:
raise NotImplementedError('cant autotest gradient of op with multiple outputs')
# we could make loop over outputs making random projections R for each,
# but this doesn't handle the case where not all the outputs are
# differentiable... so I leave this as TODO for now -jsb.
R = numpy.random.rand(*op_out.shape)
y = sum(mul_elemwise(R, op_out))
g = gradient.grad(y)
def abs_rel_err(a,b):
return abs( (a-b) / (a+b+eps))
for idx in range(len(args)):
#print 'aaaaaaa', op_cls, [i.shape for i in args]
g_i = g(args[idx])
if g_i is gradient.Undefined:
continue
if args[idx].shape == ():
fd_grad = _finite_diff1(_scalar_f(op_cls, args, R, idx),
args[idx].data, eps, y.data)
err = abs_rel_err(fd_grad,g_i.data)
self.failUnless( err < tol, (err, op_cls, idx))
elif len(args[idx].shape) == 1:
for i in xrange(args[idx].shape[0]):
fd_grad = _finite_diff1(_scalar_f(op_cls, args, R, idx, (i,)),
args[idx].data[i], eps, y.data)
err = abs_rel_err(fd_grad,g_i.data[i])
self.failUnless( abs(err) < tol, (err, op_cls, idx, i))
elif len(args[idx].shape) == 2:
for i in xrange(args[idx].shape[0]):
for j in xrange(args[idx].shape[1]):
fd_grad = _finite_diff1(_scalar_f(op_cls, args, R, idx, (i,j)),
args[idx].data[i,j], eps, y.data)
err = abs_rel_err(fd_grad,g_i.data[i,j])
self.failUnless( abs(err) < tol, (err, op_cls, idx, i, j))
else:
raise NotImplementedError()
def _testgrad_unary_elemwise_randnearzero(op_cls, n_tests=1,eps=0.000001, tol=0.0001):
class test_some_op_gradient(unittest.TestCase):
def setUp(self):
gof.lib.build_eval_mode()
numpy.random.seed([234,234,23333])
def tearDown(self):
gof.lib.pop_mode()
def test0(self):
"""Gradient Test with a small scalar"""
_test_grad(self, op_cls,
(Numpy2(data=(numpy.ones(()))*0.03),),
n_tests, eps, tol)
def test1(self):
"""Gradient Test with a medium scalar"""
_test_grad(self, op_cls,
(Numpy2(data=(numpy.ones(()))*1.03),),
n_tests, eps, tol)
def test2(self):
"""Gradient Test with a big scalar"""
_test_grad(self, op_cls,
(Numpy2(data=(numpy.ones(()))*90.03),),
n_tests, eps, tol)
def test3(self):
"""Gradient Test with a vector"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.random.rand(3)+0.01),),
n_tests, eps, tol)
def test4(self):
"""Gradient Test with a matrix"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.random.rand(2,3)*4),),
n_tests, eps, tol)
return test_some_op_gradient
neg_test = _testgrad_unary_elemwise_randnearzero(neg)
twice_test = _testgrad_unary_elemwise_randnearzero(twice)
exp_test = _testgrad_unary_elemwise_randnearzero(exp)
sqr_test = _testgrad_unary_elemwise_randnearzero(sqr)
sqrt_test = _testgrad_unary_elemwise_randnearzero(sqrt)
inv_test = _testgrad_unary_elemwise_randnearzero(inv_elemwise)
transpose_test = _testgrad_unary_elemwise_randnearzero(transpose)
def _testgrad_unary_elemwise_randpositive(op_cls, n_tests=1,eps=0.000001, tol=0.0001):
class test_some_op_gradient(unittest.TestCase):
def setUp(self):
gof.lib.build_eval_mode()
numpy.random.seed([234,234,23333])
def tearDown(self):
gof.lib.pop_mode()
def test0(self):
"""Gradient Test with a small scalar"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.ones(())*0.03),),
n_tests, eps, tol)
def test1(self):
"""Gradient Test with a medium scalar"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.ones(())*1.03),),
n_tests, eps, tol)
def test2(self):
"""Gradient Test with a big scalar"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.ones(())*90.03),),
n_tests, eps, tol)
def test3(self):
"""Gradient Test with a vector"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.random.rand(3)+0.01),),
n_tests, eps, tol)
def test4(self):
"""Gradient Test with a matrix"""
_test_grad(self, op_cls,
(Numpy2(data=numpy.random.rand(2,3)*4),),
n_tests, eps, tol)
return test_some_op_gradient
log_test = _testgrad_unary_elemwise_randpositive(log)
log2_test = _testgrad_unary_elemwise_randpositive(log2)
sqrt_test = _testgrad_unary_elemwise_randpositive(sqrt)
def _testgrad_binary_elemwise(op_cls, domain, n_tests=1,eps=0.000001, tol=0.0001):
class test_some_op_gradient(unittest.TestCase):
def setUp(self):
gof.lib.build_eval_mode()
numpy.random.seed([234,234,23333])
def tearDown(self):
gof.lib.pop_mode()
def mytest(self, *raw_args):
args = [Numpy2(data=d(a)) for a,d in zip(raw_args,domain)]
_test_grad(self, op_cls, args, n_tests, eps, tol)
def test0(self):
"""Gradient test low"""
self.mytest(numpy.zeros(()), numpy.zeros(()))
def test1(self):
"""Gradient test middle"""
self.mytest(numpy.ones(())*.5, numpy.ones(())*0.5)
def test2(self):
"""Gradient test high"""
self.mytest(numpy.ones(()), numpy.ones(()))
def test3(self):
"""Gradient test with a vector"""
self.mytest(numpy.random.rand(4),numpy.random.rand(4))
def test4(self):
"""Gradient test with a matrix"""
self.mytest(numpy.random.rand(3,2),numpy.random.rand(3,2))
return test_some_op_gradient
add_test = _testgrad_binary_elemwise(add_elemwise, [lambda x:(x-0.5)*50]*2)
sub_test = _testgrad_binary_elemwise(sub_elemwise, [lambda x:(x-0.5)*50]*2)
mul_test = _testgrad_binary_elemwise(mul_elemwise, [lambda x:(x-0.5)*50]*2)
div_test = _testgrad_binary_elemwise(div_elemwise, [lambda x:(x-0.4)*50]*2)
pow_test = _testgrad_binary_elemwise(pow_elemwise, [lambda x:x*10+0.01, lambda x:(x-0.5)*4])
def _testgrad_binary_scalar(op_cls, domain, n_tests=1,eps=0.000001, tol=0.0001):
class test_some_op_gradient(unittest.TestCase):
def setUp(self):
gof.lib.build_eval_mode()
numpy.random.seed([234,234,23333])
def tearDown(self):
gof.lib.pop_mode()
def mytest(self, *raw_args):
args = [Numpy2(data=domain[0](raw_args[0])),
Numpy2(data=_scalar(domain[1](raw_args[1])))]
#print repr(args[0].data), repr(args[1].data)
_test_grad(self, op_cls, args, n_tests, eps, tol)
def test0_low(self):
self.mytest(numpy.zeros(()), _scalar(0))
def test1_middle(self):
self.mytest(numpy.ones(())*.5, _scalar(0.5))
def test2_high(self):
self.mytest(numpy.ones(()), _scalar(1.0))
def test3_vector(self):
self.mytest(numpy.random.rand(4),_scalar(numpy.random.rand()))
def test4_matrix(self):
self.mytest(numpy.random.rand(3,2),_scalar(numpy.random.rand()))
test_some_op_gradient.__name__ = str(op_cls.__name__) + '_test'
return test_some_op_gradient
add_scalar_test = _testgrad_binary_scalar(add_scalar, [lambda x:(x-0.5)*50]*2)
mul_scalar_test = _testgrad_binary_scalar(mul_scalar, [lambda x:(x-0.5)*50]*2)
pow_scalar_l_test = _testgrad_binary_scalar(pow_scalar_l,
[lambda x:(x-0.5)*10, lambda x:(x+0.01)*10.0])
pow_scalar_r_test = _testgrad_binary_scalar(pow_scalar_r,
[lambda x:(x+0.01)*10, lambda x:(x-0.5)*10.0])
fill_test = _testgrad_binary_scalar(fill, [lambda x:(x-0.5)*50]*2)
class test_some_op_gradient(unittest.TestCase):
def setUp(self):
gof.lib.build_eval_mode()
numpy.random.seed([234,234,23333])
def tearDown(self):
gof.lib.pop_mode()
def mytest(self, *raw_args):
n_tests = 1
eps = 0.000001
tol=0.00001
args = [Numpy2(data=raw_args[0]),
Numpy2(data=raw_args[1])]
#print repr(args[0].data), repr(args[1].data)
_test_grad(self, dot, args, n_tests, eps, tol)
def test0(self):
"""Gradient test low"""
self.mytest(numpy.zeros(()), _scalar(0))
def test1(self):
"""Gradient test middle"""
self.mytest(_scalar(0.5), _scalar(0.5))
def test2(self):
"""Gradient test high"""
self.mytest(numpy.ones(()), _scalar(1.0))
def test3(self):
"""Gradient test dot with vectors"""
self.mytest(numpy.random.rand(4),numpy.random.rand(4))
def test4(self):
"""Gradient test dot with matrices"""
self.mytest(numpy.random.rand(3,2),numpy.random.rand(2,4))
def _notyet_test5(self):
"""Gradient test dot with 3d-tensor on left"""
self.mytest(numpy.random.rand(3,4,2),numpy.random.rand(2,5))
def _notyet_test6(self):
"""Gradient test dot with 3d-tensor on right"""
self.mytest(numpy.random.rand(4,2),numpy.random.rand(3,2,5))
class testCase_slicing(unittest.TestCase):
def setUp(self):
build_eval_mode()
def tearDown(self):
pop_mode()
def test_getitem0(self):
a = numpy.ones((4,4))
wa1 = wrap(a)[:,1]
try:
err = wa1 + a
except ValueError, e:
self.failUnless(str(e) == \
'The dimensions of the inputs do not match.',
'Wrong ValueError')
return
self.fail('add should not have succeeded')
def test_getitem1(self):
a = numpy.ones((4,4))
wa1 = wrap(a)[1]
self.failUnless(wa1.data.shape == (4,))
def test_getslice_0d_all(self):
"""Test getslice does not work on 0d array """
a = numpy.ones(())
try:
wa1 = wrap(a)[:]
except IndexError, e:
self.failUnless(str(e) == "0-d arrays can't be indexed.")
return
self.fail()
def test_getslice_1d_all(self):
"""Test getslice on 1d array"""
a = numpy.ones(4)
wa1 = wrap(a)[:]
self.failUnless(wa1.data.shape == (4,), 'wrong shape')
self.failUnless(numpy.all(wa1.data == a), 'unequal value')
a[1] = 3.4
self.failUnless(wa1.data[1] == 3.4, 'not a view')
try:
wa1[2] = 2.5
except TypeError, e:
self.failUnless("object does not support item assignment" in str(e))
return
self.fail()
def test_getslice_3d_all(self):
"""Test getslice on 3d array"""
a = numpy.ones((4,5,6))
wa1 = wrap(a)[:]
self.failUnless(wa1.data.shape == (4,5,6), 'wrong shape')
self.failUnless(numpy.all(wa1.data == a), 'unequal value')
a[1,1,1] = 3.4
self.failUnless(wa1.data[1,1,1] == 3.4, 'not a view')
def test_getslice_1d_some(self):
"""Test getslice on 1d array"""
a = numpy.ones(5)
wa1 = wrap(a)[1:3]
a[2] = 5.0
a[3] = 2.5
self.failUnless(wa1.data.shape == (2,))
self.failUnless(a[1] == wa1.data[0])
self.failUnless(a[2] == wa1.data[1])
def test_getslice_1d_step(self):
"""Test getslice on 1d array"""
a = numpy.ones(8)
wa1 = wrap(a)[0:8:2]
for i in xrange(8): a[i] = i
self.failUnless(wa1.shape == (4,))
for i in xrange(4):
self.failUnless(a[i*2] == wa1.data[i])
def test_getslice_3d_float(self):
"""Test getslice on 3d array"""
a = numpy.asarray(range(4*5*6))
a.resize((4,5,6))
wa1 = wrap(a)[1:3]
self.failUnless(wa1.shape == (2,5,6))
self.failUnless(numpy.all(a[1:3] == wa1.data))
a[1] *= -1.0
self.failUnless(numpy.all(a[1:3] == wa1.data))
def test_getslice_3d_one(self):
"""Test getslice on 3d array"""
a = numpy.asarray(range(4*5*6))
a.resize((4,5,6))
wa = wrap(a)
wa_123 = wa[1,2,3]
self.failUnless(wa_123.shape == (), wa_123.shape)
class test_Numpy2(unittest.TestCase):
def setUp(self):
build_eval_mode()
numpy.random.seed(44)
def tearDown(self):
pop_mode()
def test_0(self):
r = Numpy2()
def test_1(self):
o = numpy.ones((3,3))
r = Numpy2(data=o)
self.failUnless(r.data is o)
self.failUnless(r.shape == (3,3))
self.failUnless(str(r.dtype) == 'float64')
def test_2(self):
r = Numpy2(data=[(3,3),'int32'])
self.failUnless(r.data is None)
self.failUnless(r.shape == (3,3))
self.failUnless(str(r.dtype) == 'int32')
r.alloc()
self.failUnless(isinstance(r.data, numpy.ndarray))
self.failUnless(r.shape == (3,3))
self.failUnless(str(r.dtype) == 'int32')
def test_3(self):
a = Numpy2(data=numpy.ones((2,2)))
b = Numpy2(data=numpy.ones((2,2)))
c = add(a,b)
self.failUnless(_approx_eq(c, numpy.ones((2,2))*2))
def test_4(self):
ones = numpy.ones((2,2))
a = Numpy2(data=ones)
o = numpy.asarray(a)
self.failUnless((ones == o).all())
def test_5(self):
ones = numpy.ones((2,2))
self.failUnless(_approx_eq(Numpy2(data=ones), Numpy2(data=ones)))
class testCase_producer_build_mode(unittest.TestCase):
def test_0(self):
"""producer in build mode"""
build_mode()
a = ones(4)
self.failUnless(a.data is None, a.data)
self.failUnless(a.state is gof.result.Empty, a.state)
self.failUnless(a.shape == 4, a.shape)
self.failUnless(str(a.dtype) == 'float64', a.dtype)
pop_mode()
def test_1(self):
"""producer in build_eval mode"""
build_eval_mode()
a = ones(4)
self.failUnless((a.data == numpy.ones(4)).all(), a.data)
self.failUnless(a.state is gof.result.Computed, a.state)
self.failUnless(a.shape == (4,), a.shape)
self.failUnless(str(a.dtype) == 'float64', a.dtype)
pop_mode()
class testCase_add_build_mode(unittest.TestCase):
def setUp(self):
build_mode()
numpy.random.seed(44)
def tearDown(self):
pop_mode()
class testCase_dot(unittest.TestCase):
def setUp(self):
build_eval_mode()
numpy.random.seed(44)
def tearDown(self):
pop_mode()
@staticmethod
def rand(*args):
return numpy.random.rand(*args)
def cmp_dot(self,x,y):
def spec(x):
x = numpy.asarray(x)
return type(x), x.dtype, x.shape
zspec = dot.specs(spec(x), spec(y))
nz = numpy.dot(x,y)
self.failUnless(zspec == spec(nz))
self.failUnless(_approx_eq(dot(x,y), numpy.dot(x,y)))
def cmp_dot_comp(self, x,y):
x = numpy.asarray(x)
y = numpy.asarray(y)
z = dot(x,y)
p = compile.single(z)
if len(x.shape):
x[:] = numpy.random.rand(*x.shape)
else:
x.fill(numpy.random.rand(*x.shape))
if len(y.shape):
y[:] = numpy.random.rand(*y.shape)
else:
y.fill(numpy.random.rand(*y.shape))
p() # recalculate z
self.failUnless(_approx_eq(z, numpy.dot(x,y)))
def test_dot_0d_0d(self): self.cmp_dot(1.1, 2.2)
def test_dot_0d_1d(self): self.cmp_dot(1.1, self.rand(5))
def test_dot_0d_2d(self): self.cmp_dot(3.0, self.rand(6,7))
def test_dot_0d_3d(self): self.cmp_dot(3.0, self.rand(8,6,7))
def test_dot_1d_0d(self): self.cmp_dot(self.rand(5), 1.1 )
def test_dot_1d_1d(self): self.cmp_dot(self.rand(5), self.rand(5))
def test_dot_1d_2d(self): self.cmp_dot(self.rand(6), self.rand(6,7))
def test_dot_1d_3d(self): self.cmp_dot(self.rand(6), self.rand(8,6,7))
def test_dot_2d_0d(self): self.cmp_dot(self.rand(5,6), 1.0)
def test_dot_2d_1d(self): self.cmp_dot(self.rand(5,6), self.rand(6))
def test_dot_2d_2d(self): self.cmp_dot(self.rand(5,6), self.rand(6,7))
def test_dot_2d_3d(self): self.cmp_dot(self.rand(5,6), self.rand(8,6,7))
def test_dot_3d_0d(self): self.cmp_dot(self.rand(4,5,6), 1.0)
def test_dot_3d_1d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6))
def test_dot_3d_2d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6,7))
def test_dot_3d_3d(self): self.cmp_dot(self.rand(4,5,6), self.rand(8,6,7))
def test_dot_0d_0d_(self): self.cmp_dot_comp(1.1, 2.2)
def test_dot_0d_1d_(self): self.cmp_dot_comp(1.1, self.rand(5))
def test_dot_0d_2d_(self): self.cmp_dot_comp(3.0, self.rand(6,7))
def test_dot_0d_3d_(self): self.cmp_dot_comp(3.0, self.rand(8,6,7))
def test_dot_1d_0d_(self): self.cmp_dot_comp(self.rand(5), 1.1 )
def test_dot_1d_1d_(self): self.cmp_dot_comp(self.rand(5), self.rand(5))
def test_dot_1d_2d_(self): self.cmp_dot_comp(self.rand(6), self.rand(6,7))
def test_dot_1d_3d_(self): self.cmp_dot_comp(self.rand(6), self.rand(8,6,7))
def test_dot_2d_0d_(self): self.cmp_dot_comp(self.rand(5,6), 1.0)
def test_dot_2d_1d_(self): self.cmp_dot_comp(self.rand(5,6), self.rand(6))
def test_dot_2d_2d_(self): self.cmp_dot_comp(self.rand(5,6), self.rand(6,7))
def test_dot_2d_3d_(self): self.cmp_dot_comp(self.rand(5,6), self.rand(8,6,7))
def test_dot_3d_0d_(self): self.cmp_dot_comp(self.rand(4,5,6), 1.0)
def test_dot_3d_1d_(self): self.cmp_dot_comp(self.rand(4,5,6), self.rand(6))
def test_dot_3d_2d_(self): self.cmp_dot_comp(self.rand(4,5,6), self.rand(6,7))
def test_dot_3d_3d_(self): self.cmp_dot_comp(self.rand(4,5,6), self.rand(8,6,7))
def test_dot_fail_1_1(self):
x = numpy.random.rand(5)
y = numpy.random.rand(6)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_1_2(self):
x = numpy.random.rand(5)
y = numpy.random.rand(6,4)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_1_3(self):
x = numpy.random.rand(5)
y = numpy.random.rand(6,4,7)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_2_1(self):
x = numpy.random.rand(5,4)
y = numpy.random.rand(6)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_2_2(self):
x = numpy.random.rand(5,4)
y = numpy.random.rand(6,7)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_2_3(self):
x = numpy.random.rand(5,4)
y = numpy.random.rand(6,7,8)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_3_1(self):
x = numpy.random.rand(5,4,3)
y = numpy.random.rand(6)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_3_2(self):
x = numpy.random.rand(5,4,3)
y = numpy.random.rand(6,7)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
def test_dot_fail_3_3(self):
x = numpy.random.rand(5,4,3)
y = numpy.random.rand(6,7,8)
try:
z = dot(x,y)
except ValueError, e:
self.failUnless(str(e) == 'objects are not aligned', e)
return
self.fail()
class testCase_transpose(unittest.TestCase):
def setUp(self):
build_eval_mode()
def tearDown(self):
pop_mode()
def test_1d_alias(self):
a = numpy.ones(10)
ta = transpose(a)
self.failUnless(ta.data.shape == a.shape)
self.failUnless(numpy.all(ta.data == a))
a[3] *= -1.0
self.failUnless(numpy.all(ta.data == a))
def test_1d_copy(self):
a = numpy.ones(10)
ta = transpose_copy(a)
self.failUnless(ta.data.shape == a.shape)
self.failUnless(numpy.all(ta.data == a))
a[3] *= -1.0
self.failIf(numpy.all(ta.data == a))
def test_2d_alias(self):
a = numpy.ones((10,3))
ta = transpose(a)
self.failUnless(ta.data.shape == (3,10))
def test_3d_alias(self):
a = numpy.ones((10,3,5))
ta = transpose(a)
self.failUnless(ta.data.shape == (5,3,10))
a[9,0,0] = 5.0
self.failUnless(ta.data[0,0,9] == 5.0)
def test_3d_copy(self):
a = numpy.ones((10,3,5))
ta = transpose_copy(a)
self.failUnless(ta.data.shape == (5,3,10))
a[9,0,0] = 5.0
self.failUnless(ta.data[0,0,9] == 1.0)
class testCase_power(unittest.TestCase):
def setUp(self):
build_eval_mode()
numpy.random.seed(44)
def tearDown(self):
pop_mode()
def test1(self):
r = numpy.random.rand(50)
exp_r = exp(r)
self.failUnless(exp_r.__array__().__class__ is numpy.ndarray)
def test_0(self):
r = numpy.random.rand(50)
exp_r = exp(r)
n_exp_r = numpy.exp(r)
self.failUnless( _approx_eq(exp_r, n_exp_r),
(exp_r, exp_r.data, n_exp_r,
numpy.max(numpy.abs(n_exp_r.__sub__(exp_r.__array__())))))
log_exp_r = log(exp_r)
self.failUnless( _approx_eq(log_exp_r, r), log_exp_r)
def test_1(self):
r = numpy.random.rand(50)
r2 = pow(r,2)
self.failUnless( _approx_eq(r2, r*r))
if __name__ == '__main__':
unittest.main()
if __name__ == '__main__':
unittest.main()
...@@ -4,10 +4,9 @@ def test_root_dir(): ...@@ -4,10 +4,9 @@ def test_root_dir():
suite = None suite = None
filenames = os.listdir('.') filenames = os.listdir('.')
for filename in filenames: for filename in filenames:
if filename[-3:] == '.py': if filename[-3:] == '.py' and filename[0:5] == '_test':
modname = filename[:-3]
if modname in ['__init__', 'autotest']: continue
#print >>sys.stderr, 'Loading', modname #print >>sys.stderr, 'Loading', modname
modname = filename[0:-3]
tests = unittest.TestLoader().loadTestsFromModule(__import__(modname)) tests = unittest.TestLoader().loadTestsFromModule(__import__(modname))
if tests.countTestCases() > 0: if tests.countTestCases() > 0:
print >>sys.stderr, 'Testing', modname print >>sys.stderr, 'Testing', modname
......
import os, sys import os, sys
from gof import PatternOptimizer as pattern_opt, OpSubOptimizer as op_sub
import scipy.weave as weave import scipy.weave as weave
""" """
......
from core import *
import gof
from gof import PatternOptimizer as pattern_opt, OpSubOptimizer as op_sub
""" """
This variable is used in compile.prog as the optimizer for all programs built This variable is used in compile.prog as the optimizer for all programs built
using either compile.single, compile.to_func, and compile.prog. using either compile.single, compile.to_func, and compile.prog.
"""
def optimizer(lst): if 0:
def optimizer(lst):
begin = gof.SeqOptimizer([]) begin = gof.SeqOptimizer([])
end = gof.SeqOptimizer([gof.DummyRemover]) end = gof.SeqOptimizer([gof.DummyRemover])
seq_opt = gof.SeqOptimizer(begin + lst + end) seq_opt = gof.SeqOptimizer(begin + lst + end)
...@@ -34,3 +29,4 @@ if 0: ...@@ -34,3 +29,4 @@ if 0:
(iadd_elemwise, 'y', 'x'))]]]) (iadd_elemwise, 'y', 'x'))]]])
# ['remove_copies', gof.OpRemover(array_copy)], # ['remove_copies', gof.OpRemover(array_copy)],
# [None, gof.DummyRemover] # has to be at the end # [None, gof.DummyRemover] # has to be at the end
"""
...@@ -3,13 +3,11 @@ import unittest ...@@ -3,13 +3,11 @@ import unittest
import numpy import numpy
from scipy import sparse from scipy import sparse
import gof.lib import gof
import core
import grad
# Wrapper type # Wrapper type
class SparseR(core.ResultBase): class SparseR(gof.ResultBase):
""" """
Attribute: Attribute:
format - a subclass of sparse.spmatrix indicating self.data.__class__ format - a subclass of sparse.spmatrix indicating self.data.__class__
......
...@@ -690,6 +690,101 @@ pow = _scalar_switch(pow_elemwise, pow_scalar_r, pow_scalar_l) ...@@ -690,6 +690,101 @@ pow = _scalar_switch(pow_elemwise, pow_scalar_r, pow_scalar_l)
pow_inplace = _scalar_switch(pow_elemwise_inplace, pow_scalar_r_inplace) pow_inplace = _scalar_switch(pow_elemwise_inplace, pow_scalar_r_inplace)
#########################
# Linalg : Dot
#########################
class Dot(_Op):
nin=2
nout=1
@staticmethod
def broadcastable_rule(bx,by):
if len(bx) == 0: # x is a scalar
rval = by
else:
if len(by) >= 2: #y is a matrix or tensor
rval = bx[:-1] + by[:-2] + by[-1:]
elif len(by)==1: #y is vector
rval = bx[:-1]
else: #y is a scalar
rval = bx
return rval
def propagate_broadcastable(self, bx, by):
return [self.broadcastable_rule(bx,by)]
def impl(self, x, y):
return numpy.dot(x, y)
def grad(self, (x, y), gz):
return dot(gz, y.T), dot(x.T, gz)
if 0:
def c_support_code(self):
return blas.cblas_header_text()
def c_libs(self):
return blas.ldflags()
def c_impl(self, (_x, _y), (_z, )):
return blas.gemm_code('', '1.0', '0.0')
dot = _constructor(Dot)
class Gemm(_Op):
nin=5
nout=1
E_bcast = 'incompatible broadcastable flags'
def destroy_map(self):
return {self.out:[self.inputs[0]]}
def propagate_broadcastable(self, bz, ba, bx, by, bb):
if len(bz) != len(Dot.broadcastable_rule(bx,by)):
raise ValueError(Gemm.E_bcast, bz, bx, by)
return [bz]
def impl(self, z, a, x, y, b):
assert a.shape == ()
assert b.shape == ()
if z.shape == ():
z.itemset(z*a + b*numpy.dot(x,y))
return z
else:
if b == 0.0:
if a == 1.0:
z[:] = numpy.dot(x,y)
elif a == -1.0:
z[:] = -numpy.dot(x,y)
else:
z[:] = a * numpy.dot(x,y)
elif b == 1.0:
if a == 1.0:
z += numpy.dot(x,y)
elif a == -1.0:
z -= numpy.dot(x,y)
else:
z += a * numpy.dot(x,y)
else:
z *= b
z += a * numpy.dot(x,y)
return z
def grad(self, (z, a, x, y, b), gz):
raise NotImplementedError()
if 0:
def c_support_code(self):
return blas.cblas_header_text()
def c_libs(self):
return blas.ldflags()
def c_impl((_zin, _a, _x, _y, _b), (_z,)):
check_ab = """
{
if ((_a->descr->type_num != PyArray_DOUBLE)
&& (_a->descr->type_num != PyArray_FLOAT))
goto _dot_execute_fallback;
if ((_b->descr->type_num != PyArray_DOUBLE)
&& (_b->descr->type_num != PyArray_FLOAT))
goto _dot_execute_fallback;
}
"""
return blas.gemm_code( check_ab,
'(_a->descr->type_num == PyArray_FLOAT) ? (REAL)(((float*)_a->data)[0]) : (REAL)(((double*)_a->data)[0])',
'(_b->descr->type_num == PyArray_FLOAT) ? (REAL)(((float*)_b->data)[0]) : (REAL)(((double*)_b->data)[0])')
gemm = _constructor(Gemm)
if 0: if 0:
########################## ##########################
# Comparisons # Comparisons
......
from gof import Op, utils, Destroyer, Viewer
import gof.op
from tensor import *
###########################
#### Binary Operations ####
###########################
#########
## Dot ##
#########
class Dot(TensorOp):
@staticmethod
def _output_shape(xshape, yshape):
# This describes the logic to calculate numpy.dot(x, y).shape
# given x.shape and y.shape
if len(xshape) == 0: # x is a scalar
shape = yshape
else:
if len(yshape) >= 2: #y is a matrix or tensor
assert xshape[-1] == yshape[-2]
shape = tuple(xshape[:-1]+ yshape[:-2]+yshape[-1:])
elif len(yshape)==1: #y is vector
assert xshape[-1] == yshape[-1]
shape = tuple(xshape[:-1])
else: #y is a scalar
shape = xshape
return shape
def impl(self, x, y):
return numpy.dot(x, y)
def grad(self, (x, y), gz):
return dot(gz, transpose(y)), dot(transpose(x), gz)
def propagate_broadcastable(self, x, y):
assert len(x) == 2 and len(x) == len(y)
return [(x[0], y[1])]
def c_support_code(self):
return blas.cblas_header_text()
def c_libs(self):
return blas.ldflags()
def c_impl(self, (_x, _y), (_z, )):
return blas.gemm_code('', '1.0', '0.0')
############
## Others ##
############
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论