Skip to content

Commit

Permalink
Merge pull request #371 from odlgroup/skip_tests_properly
Browse files Browse the repository at this point in the history
Updates to test skipping and fixtures
  • Loading branch information
adler-j committed Apr 28, 2016
2 parents 6c01a7b + d878545 commit 8d79396
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 206 deletions.
21 changes: 21 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from future import standard_library
standard_library.install_aliases()

import pytest
import odl
from odl.space.cu_ntuples import CUDA_AVAILABLE
from odl.trafos.wavelet import PYWAVELETS_AVAILABLE

Expand All @@ -38,3 +40,22 @@ def pytest_addoption(parser):

parser.addoption('--benchmark', action='store_true',
help='Run benchmarks')


# reusable fixtures
ufunc_params = [ufunc for ufunc in odl.util.ufuncs.UFUNCS]
ufunc_ids = [' ufunc={} '.format(p[0]) for p in ufunc_params]


@pytest.fixture(scope="module", ids=ufunc_ids, params=ufunc_params)
def ufunc(request):
return request.param


reduction_params = [reduction for reduction in odl.util.ufuncs.REDUCTIONS]
reduction_ids = [' reduction={} '.format(p[0]) for p in reduction_params]


@pytest.fixture(scope="module", ids=reduction_ids, params=reduction_params)
def reduction(request):
return request.param
8 changes: 7 additions & 1 deletion odl/util/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from time import time


__all__ = ('almost_equal', 'all_equal', 'all_almost_equal',
__all__ = ('almost_equal', 'all_equal', 'all_almost_equal', 'never_skip',
'skip_if_no_cuda', 'skip_if_no_pywavelets', 'skip_if_no_pyfftw',
'skip_if_no_largescale',
'Timer', 'timeit', 'ProgressBar', 'ProgressRange',
Expand Down Expand Up @@ -185,6 +185,12 @@ def _pass(function):
# Try catch in case user does not have pytest
import pytest

# Used in lists where the elements should all be skipifs
never_skip = pytest.mark.skipif(
"False",
reason='Fill in, never skips'
)

skip_if_no_cuda = pytest.mark.skipif(
"not odl.CUDA_AVAILABLE",
reason='CUDA not available'
Expand Down
152 changes: 43 additions & 109 deletions test/discr/lp_discr_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import odl
from odl.discr.lp_discr import DiscreteLp
from odl.util.testutils import (almost_equal, all_equal, all_almost_equal,
skip_if_no_cuda)
never_skip, skip_if_no_cuda)


def _array(fn):
Expand Down Expand Up @@ -66,14 +66,23 @@ def _vectors(fn, n=1):
# Simply modify exp_params to modify the fixture
exp_params = [2.0, 1.0, float('inf'), 0.5, 1.5]
exp_ids = [' p = {} '.format(p) for p in exp_params]
exp_fixture = pytest.fixture(scope="module", ids=exp_ids, params=exp_params)


@exp_fixture
@pytest.fixture(scope="module", ids=exp_ids, params=exp_params)
def exponent(request):
return request.param


impl_params = [never_skip('numpy'),
skip_if_no_cuda('cuda')]
impl_ids = [' impl = {} '.format(p.args[1]) for p in impl_params]


@pytest.fixture(scope="module", ids=impl_ids, params=impl_params)
def impl(request):
return request.param


def test_init(exponent):
# Validate that the different init patterns work and do not crash.
space = odl.FunctionSpace(odl.Interval(0, 1))
Expand Down Expand Up @@ -580,12 +589,24 @@ def test_astype():
assert cdiscr._real_space == rdiscr


def _impl_test_ufuncs(fn, name, n_args, n_out):
def test_ufunc(impl, ufunc):
space = odl.uniform_discr([0, 0], [1, 1], (2, 2), impl=impl)
name, n_args, n_out, _ = ufunc
if (np.issubsctype(space.dtype, np.floating) and
name in ['bitwise_and',
'bitwise_or',
'bitwise_xor',
'invert',
'left_shift',
'right_shift']):
# Skip integer only methods if floating point type
return

# Get the ufunc from numpy as reference
ufunc = getattr(np, name)

# Create some data
data = _vectors(fn, n_args + n_out)
data = _vectors(space, n_args + n_out)
in_arrays = data[:n_args]
out_arrays = data[n_args:n_args + n_out]
data_vector = data[n_args + n_out]
Expand All @@ -604,10 +625,10 @@ def _impl_test_ufuncs(fn, name, n_args, n_out):

# Test type of output
if n_out == 1:
assert isinstance(odl_result, fn.element_type)
assert isinstance(odl_result, space.element_type)
elif n_out > 1:
for i in range(n_out):
assert isinstance(odl_result[i], fn.element_type)
assert isinstance(odl_result[i], space.element_type)

# In place:
np_result = ufunc(*(in_arrays + out_arrays))
Expand All @@ -630,29 +651,10 @@ def _impl_test_ufuncs(fn, name, n_args, n_out):

# Test type of output
if n_out == 1:
assert isinstance(odl_result, fn.element_type)
assert isinstance(odl_result, space.element_type)
elif n_out > 1:
for i in range(n_out):
assert isinstance(odl_result[i], fn.element_type)


impl_params = [('numpy',), skip_if_no_cuda(('cuda',))]


@pytest.mark.parametrize(('impl',), impl_params)
def test_ufuncs(impl):
space = odl.uniform_discr([0, 0], [1, 1], (2, 2), impl=impl)
for name, n_args, n_out, _ in odl.util.ufuncs.UFUNCS:
if (np.issubsctype(space.dtype, np.floating) and
name in ['bitwise_and',
'bitwise_or',
'bitwise_xor',
'invert',
'left_shift',
'right_shift']):
# Skip integer only methods if floating point type
continue
_impl_test_ufuncs(space, name, n_args, n_out)
assert isinstance(odl_result[i], space.element_type)


def test_real_imag():
Expand Down Expand Up @@ -707,25 +709,18 @@ def test_real_imag():
assert all_equal(x.real, [4, 5, 6, 7])


def _impl_test_reduction(fn, name):
def test_reduction(impl, reduction):
space = odl.uniform_discr([0, 0], [1, 1], [2, 2], impl=impl)

name, _ = reduction

ufunc = getattr(np, name)

# Create some data
x_arr, x = _vectors(fn, 1)
x_arr, x = _vectors(space, 1)
assert almost_equal(ufunc(x_arr), getattr(x.ufunc, name)())


def test_reductions():
spaces = [odl.uniform_discr([0, 0], [1, 1], [2, 2])]

if odl.CUDA_AVAILABLE:
spaces += [odl.uniform_discr([0, 0], [1, 1], [2, 2], impl='cuda')]

for fn in spaces:
for name, _ in odl.util.ufuncs.REDUCTIONS:
yield _impl_test_reduction, fn, name


def test_norm_interval(exponent):
# Test the function f(x) = x^2 on the interval (0, 1). Its
# L^p-norm is (1 + 2*p)^(-1/p) for finite p and 1 for p=inf
Expand Down Expand Up @@ -761,79 +756,18 @@ def test_norm_rectangle(exponent):
assert almost_equal(discr_testfunc.norm(), true_norm, places=2)


def test_norm_rectangle_boundary(exponent):
def test_norm_rectangle_boundary(impl, exponent):
# Check the constant function 1 in different situations regarding the
# placement of the outermost grid points.
rect = odl.Rectangle([-1, -2], [1, 2])

# Standard case
discr = odl.uniform_discr_fromspace(odl.FunctionSpace(rect), (4, 8),
exponent=exponent)
if exponent == float('inf'):
assert discr.one().norm() == 1
else:
assert almost_equal(discr.one().norm(),
(rect.volume) ** (1 / exponent))

# Nodes on the boundary (everywhere)
discr = odl.uniform_discr_fromspace(
odl.FunctionSpace(rect), (4, 8), exponent=exponent,
nodes_on_bdry=True)

if exponent == float('inf'):
assert discr.one().norm() == 1
else:
assert almost_equal(discr.one().norm(),
(rect.volume) ** (1 / exponent))

# Nodes on the boundary (selective)
discr = odl.uniform_discr_fromspace(
odl.FunctionSpace(rect), (4, 8), exponent=exponent,
nodes_on_bdry=((False, True), False))

if exponent == float('inf'):
assert discr.one().norm() == 1
else:
assert almost_equal(discr.one().norm(),
(rect.volume) ** (1 / exponent))

discr = odl.uniform_discr_fromspace(
odl.FunctionSpace(rect), (4, 8), exponent=exponent,
nodes_on_bdry=(False, (True, False)))

if exponent == float('inf'):
assert discr.one().norm() == 1
else:
assert almost_equal(discr.one().norm(),
(rect.volume) ** (1 / exponent))

# Completely arbitrary boundary
grid = odl.RegularGrid([0, 0], [1, 1], (4, 4))
part = odl.RectPartition(rect, grid)
weight = 1.0 if exponent == float('inf') else part.cell_volume
dspace = odl.Rn(part.size, exponent=exponent, weight=weight)
discr = DiscreteLp(odl.FunctionSpace(rect), part, dspace,
exponent=exponent)

if exponent == float('inf'):
assert discr.one().norm() == 1
else:
assert almost_equal(discr.one().norm(),
(rect.volume) ** (1 / exponent))

pytest.xfail('inf-norm not implemented in CUDA')

@skip_if_no_cuda
def test_norm_rectangle_boundary_cuda(exponent):
# Check the constant function 1 in different situations regarding the
# placement of the outermost grid points.
rect = odl.Rectangle([-1, -2], [1, 2])

if exponent == float('inf'):
pytest.xfail('inf-norm not implemented in CUDA')

# Standard case
discr = odl.uniform_discr_fromspace(odl.FunctionSpace(rect), (4, 8),
exponent=exponent, impl='cuda')
impl=impl, exponent=exponent)
if exponent == float('inf'):
assert discr.one().norm() == 1
else:
Expand All @@ -843,7 +777,7 @@ def test_norm_rectangle_boundary_cuda(exponent):
# Nodes on the boundary (everywhere)
discr = odl.uniform_discr_fromspace(
odl.FunctionSpace(rect), (4, 8), exponent=exponent,
nodes_on_bdry=True, impl='cuda')
impl=impl, nodes_on_bdry=True)

if exponent == float('inf'):
assert discr.one().norm() == 1
Expand All @@ -854,7 +788,7 @@ def test_norm_rectangle_boundary_cuda(exponent):
# Nodes on the boundary (selective)
discr = odl.uniform_discr_fromspace(
odl.FunctionSpace(rect), (4, 8), exponent=exponent,
nodes_on_bdry=((False, True), False), impl='cuda')
impl=impl, nodes_on_bdry=((False, True), False))

if exponent == float('inf'):
assert discr.one().norm() == 1
Expand All @@ -864,7 +798,7 @@ def test_norm_rectangle_boundary_cuda(exponent):

discr = odl.uniform_discr_fromspace(
odl.FunctionSpace(rect), (4, 8), exponent=exponent,
nodes_on_bdry=(False, (True, False)), impl='cuda')
impl=impl, nodes_on_bdry=(False, (True, False)))

if exponent == float('inf'):
assert discr.one().norm() == 1
Expand All @@ -878,7 +812,7 @@ def test_norm_rectangle_boundary_cuda(exponent):
weight = 1.0 if exponent == float('inf') else part.cell_volume
dspace = odl.Rn(part.size, exponent=exponent, weight=weight)
discr = DiscreteLp(odl.FunctionSpace(rect), part, dspace,
exponent=exponent, impl='cuda')
impl=impl, exponent=exponent)

if exponent == float('inf'):
assert discr.one().norm() == 1
Expand Down
Loading

0 comments on commit 8d79396

Please sign in to comment.