Skip to content

Commit b192515

Browse files
brandonwillardtwiecki
authored andcommitted
Move theano.tensor.basic.batched_*dot functions to theano.tensor.blas
Because tests were moved, the RNG for subsequent tests was altered, which required a change to `utt.assert_allclose` in `tests.tensor.test_basic` for more reasonable `rtol` settings.
1 parent ef85489 commit b192515

File tree

7 files changed

+306
-322
lines changed

7 files changed

+306
-322
lines changed

tests/gpuarray/test_blas.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
gpuger_inplace,
2323
gpuger_no_inplace,
2424
)
25-
from theano.tensor.blas import _dot22, batched_dot, gemm_inplace, gemv, gemv_inplace
25+
from theano.tensor.blas import BatchedDot, _dot22, gemm_inplace, gemv, gemv_inplace
2626
from theano.tensor.type import matrix, tensor, tensor3, vector
2727

2828

@@ -186,7 +186,7 @@ def shared(val):
186186

187187
TestGpuGemmBatch = makeTester(
188188
"GpuGemmBatchTester",
189-
op=lambda z, alpha, x, y, beta: alpha * batched_dot(x, y) + beta * z,
189+
op=lambda z, alpha, x, y, beta: alpha * BatchedDot()(x, y) + beta * z,
190190
gpu_op=gpugemmbatch_inplace,
191191
cases=gemm_batched_tests,
192192
)

tests/tensor/test_basic.py

Lines changed: 5 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import numpy as np
1010
import pytest
11-
from numpy.testing import assert_allclose, assert_almost_equal, assert_array_equal
11+
from numpy.testing import assert_almost_equal, assert_array_equal
1212

1313
import theano
1414
import theano.scalar as ts
@@ -113,7 +113,6 @@
113113
argmax,
114114
argmin,
115115
as_tensor_variable,
116-
batched_dot,
117116
cast,
118117
choose,
119118
clip,
@@ -743,67 +742,6 @@ def test_py_c_match():
743742
bad_runtime=dict(bad1=(rand(5, 7), rand(5, 7)), bad2=(rand(5, 7), rand(8, 3))),
744743
)
745744

746-
TestBatchedDot = makeTester(
747-
name="BatchedDotTester",
748-
op=batched_dot,
749-
expected=(
750-
lambda xs, ys: np.asarray(
751-
list(
752-
x * y if x.ndim == 0 or y.ndim == 0 else np.dot(x, y)
753-
for x, y in zip(xs, ys)
754-
),
755-
dtype=ts.upcast(xs.dtype, ys.dtype),
756-
)
757-
),
758-
checks={},
759-
grad=dict(
760-
correct1=(rand(3, 5, 7), rand(3, 7, 5)),
761-
correct2=(rand(3, 5, 7), rand(3, 7, 9)),
762-
correct3=(rand(3, 5, 7), rand(3, 7)),
763-
correct4=(rand(3, 5), rand(3, 5, 7)),
764-
correct5=(rand(3), rand(3, 5, 7)),
765-
correct6=(rand(3, 5), rand(3)),
766-
correct7=(rand(3, 5), rand(3, 5)),
767-
correct8=(rand(3), rand(3)),
768-
correct9=(rand(3, 5, 7, 11), rand(3)),
769-
correct10=(rand(3, 2, 6, 5), rand(3, 5)),
770-
correct11=(rand(3, 2, 6, 5), rand(3, 5, 7)),
771-
correct12=(rand(3, 2, 6, 5), rand(3, 7, 5, 8)),
772-
mixed1=(rand(3, 5).astype("float32"), rand(3, 5, 7)),
773-
mixed2=(rand(3, 5).astype("float64"), rand(3, 5, 7)),
774-
),
775-
good=dict(
776-
correct1=(rand(3, 5, 7), rand(3, 7, 5)),
777-
correct2=(rand(3, 5, 7), rand(3, 7, 9)),
778-
correct3=(rand(3, 5, 7), rand(3, 7)),
779-
correct4=(rand(3, 5), rand(3, 5, 7)),
780-
correct5=(rand(3), rand(3, 5, 7)),
781-
correct6=(rand(3, 5), rand(3)),
782-
correct7=(rand(3, 5), rand(3, 5)),
783-
correct8=(rand(3), rand(3)),
784-
correct9=(rand(3, 5, 7, 11), rand(3)),
785-
correct10=(rand(3, 7, 11, 5), rand(3, 5)),
786-
correct11=(rand(3, 7, 11, 5), rand(3, 5, 13)),
787-
correct12=(rand(3, 7, 11, 5), rand(3, 13, 5, 17)),
788-
mixed1=(rand(3, 5).astype("float32"), rand(3, 5, 7)),
789-
mixed2=(rand(3, 5).astype("float64"), rand(3, 5, 7)),
790-
),
791-
bad_build=dict(
792-
no_batch_axis2=(rand(), rand(3, 5)), no_batch_axis3=(rand(3, 5), rand())
793-
),
794-
bad_runtime=dict(
795-
batch_dim_mismatch1=(rand(2, 5, 7), rand(3, 7, 9)),
796-
batch_dim_mismatch2=(rand(3, 5, 7), rand(2, 7, 9)),
797-
batch_dim_mismatch3=(rand(3), rand(5)),
798-
bad_dim1=(rand(3, 5, 7), rand(3, 5, 7)),
799-
bad_dim2=(rand(3, 5, 7), rand(3, 8, 3)),
800-
bad_dim3=(rand(3, 5), rand(3, 7)),
801-
bad_dim4=(rand(3, 5, 7, 11), rand(3, 5)),
802-
bad_dim5=(rand(3, 5, 7, 11), rand(3, 5, 13)),
803-
bad_dim6=(rand(3, 5, 7, 11), rand(3, 13, 5, 17)),
804-
),
805-
)
806-
807745

808746
def _numpy_second(x, y):
809747
return np.broadcast_arrays(x, y)[1]
@@ -1595,84 +1533,6 @@ def test_clip_repeat_verify_grad(self):
15951533
# gradient numerically
15961534

15971535

1598-
def test_batched_dot():
1599-
first = tensor3("first")
1600-
second = tensor3("second")
1601-
output = batched_dot(first, second)
1602-
first_val = np.random.rand(10, 10, 20).astype(config.floatX)
1603-
second_val = np.random.rand(10, 20, 5).astype(config.floatX)
1604-
result_fn = theano.function([first, second], output)
1605-
result = result_fn(first_val, second_val)
1606-
assert result.shape[0] == first_val.shape[0]
1607-
assert result.shape[1] == first_val.shape[1]
1608-
assert result.shape[2] == second_val.shape[2]
1609-
1610-
first_mat = dmatrix("first")
1611-
second_mat = dmatrix("second")
1612-
output = batched_dot(first_mat, second_mat)
1613-
first_mat_val = np.random.rand(10, 10).astype(config.floatX)
1614-
second_mat_val = np.random.rand(10, 10).astype(config.floatX)
1615-
result_fn = theano.function([first_mat, second_mat], output)
1616-
result = result_fn(first_mat_val, second_mat_val)
1617-
1618-
assert result.shape[0] == first_mat_val.shape[0]
1619-
1620-
1621-
def test_batched_dot_not_contiguous():
1622-
def np_genarray(*_shape):
1623-
size = 1
1624-
for dimsize in _shape:
1625-
size *= dimsize
1626-
return np.arange(size, dtype=config.floatX).reshape(_shape)
1627-
1628-
X = tensor3()
1629-
W = tensor3()
1630-
Z = batched_dot(X, W)
1631-
f = function([X, W], Z)
1632-
1633-
w = np_genarray(30, 10, 5)
1634-
reversed_x_container = np_genarray(20, 40, 30)
1635-
x_container = reversed_x_container.T
1636-
1637-
def check_first_dim(inverted):
1638-
direction = -1 if inverted else 1
1639-
x = x_container[::direction, ::2, ::2]
1640-
assert x.shape == (30, 20, 10)
1641-
assert x.strides[0] == direction * np.dtype(config.floatX).itemsize
1642-
assert not (x.flags["C_CONTIGUOUS"] or x.flags["F_CONTIGUOUS"])
1643-
result = f(x, w)
1644-
ref_result = np.asarray(list(np.dot(u, v) for u, v in zip(x, w)))
1645-
utt.assert_allclose(ref_result, result)
1646-
1647-
for inverted in (0, 1):
1648-
check_first_dim(inverted)
1649-
1650-
1651-
def test_batched_tensordot():
1652-
first = tensor4("first")
1653-
second = tensor4("second")
1654-
axes = [[1, 2], [3, 1]]
1655-
output = tt.batched_tensordot(first, second, axes)
1656-
first_val = np.random.rand(8, 10, 20, 3).astype(config.floatX)
1657-
second_val = np.random.rand(8, 20, 5, 10).astype(config.floatX)
1658-
result_fn = theano.function([first, second], output)
1659-
result = result_fn(first_val, second_val)
1660-
assert result.shape[0] == first_val.shape[0]
1661-
assert result.shape[1] == first_val.shape[3]
1662-
assert result.shape[2] == second_val.shape[2]
1663-
1664-
first_mat = dmatrix("first")
1665-
second_mat = dmatrix("second")
1666-
axes = 1
1667-
output = tt.batched_tensordot(first_mat, second_mat, axes)
1668-
first_mat_val = np.random.rand(10, 4).astype(config.floatX)
1669-
second_mat_val = np.random.rand(10, 4).astype(config.floatX)
1670-
result_fn = theano.function([first_mat, second_mat], output)
1671-
result = result_fn(first_mat_val, second_mat_val)
1672-
assert result.shape[0] == first_mat_val.shape[0]
1673-
assert len(result.shape) == 1
1674-
1675-
16761536
def test_tensor_values_eq_approx():
16771537
# test, inf, -inf and nan equal themself
16781538
a = np.asarray([-np.inf, -1, 0, 1, np.inf, np.nan])
@@ -2369,7 +2229,7 @@ def test_outer(self):
23692229
v1 = np.asarray(np.random.rand(*s1)).astype(config.floatX)
23702230
v2 = np.asarray(np.random.rand(*s2)).astype(config.floatX)
23712231
o = tt.outer(x, y).eval({x: v1, y: v2})
2372-
assert_allclose(o, np.outer(v1, v2))
2232+
utt.assert_allclose(o, np.outer(v1, v2))
23732233

23742234
def test_grad(self):
23752235
# Test the combined graph of the graph of outer
@@ -6719,10 +6579,10 @@ def test_dot(self):
67196579
x, y = self.vals
67206580
# Use allclose comparison as a user reported on the mailing
67216581
# list failure otherwise with array that print exactly the same.
6722-
assert_allclose(x.dot(y), X.dot(Y).eval({X: x, Y: y}))
6582+
utt.assert_allclose(x.dot(y), X.dot(Y).eval({X: x, Y: y}))
67236583
Z = X.dot(Y)
67246584
z = x.dot(y)
6725-
assert_allclose(x.dot(z), X.dot(Z).eval({X: x, Z: z}))
6585+
utt.assert_allclose(x.dot(z), X.dot(Z).eval({X: x, Z: z}))
67266586

67276587
def test_real_imag(self):
67286588
X, Y = self.vars
@@ -6751,7 +6611,7 @@ def test_std(self):
67516611
# std() is implemented as theano tree and does not pass its
67526612
# args directly to numpy. This sometimes results in small
67536613
# difference, so we use allclose test.
6754-
assert_allclose(X.std().eval({X: x}), x.std())
6614+
utt.assert_allclose(X.std().eval({X: x}), x.std())
67556615

67566616
def test_repeat(self):
67576617
X, _ = self.vars

0 commit comments

Comments
 (0)