Skip to content

Commit

Permalink
update all test to use pytest and xp/dev matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
gschramm committed Dec 23, 2023
1 parent dc0a103 commit cb74010
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 231 deletions.
86 changes: 23 additions & 63 deletions test/parallelproj/test_nontof_joseph.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
from __future__ import annotations

import unittest
import pytest
import parallelproj
import numpy.array_api as nparr
import array_api_compat.numpy as np

from types import ModuleType

# generate list of array_api modules / device combinations to test
xp_dev_list = [(np, 'cpu')]

def fwd_test(xp: ModuleType,
if np.__version__ >= '1.25':
xp_dev_list.append((nparr, 'cpu'))

if parallelproj.cupy_enabled:
import array_api_compat.cupy as cp
xp_dev_list.append((cp, 'cuda'))

if parallelproj.torch_enabled:
import array_api_compat.torch as torch
xp_dev_list.append((torch, 'cpu'))

if parallelproj.cuda_present:
xp_dev_list.append((torch, 'cuda'))

pytestmark = pytest.mark.parametrize("xp,dev", xp_dev_list)

#---------------------------------------------------------------------------------------

def test_fwd(xp: ModuleType,
dev: str,
verbose: bool = True,
rtol: float = 1e-5,
Expand Down Expand Up @@ -97,7 +117,7 @@ def fwd_test(xp: ModuleType,
#--------------------------------------------------------------------------


def adjointness_test(xp: ModuleType,
def test_adjointness(xp: ModuleType,
dev: str,
nLORs: int = 1000000,
seed: int = 1,
Expand Down Expand Up @@ -166,63 +186,3 @@ def adjointness_test(xp: ModuleType,
isclose = (abs(ip_a - ip_b) <= atol + rtol * abs(ip_b))

assert isclose


#--------------------------------------------------------------------------


class TestNonTOFJoseph(unittest.TestCase):
"""test for non TOF joseph projections"""

def test_fwd(self):
fwd_test(np, 'cpu')
if np.__version__ >= '1.25':
fwd_test(nparr, 'cpu')

if parallelproj.cupy_enabled:

def test_fwd_cp(self):
import array_api_compat.cupy as cp
fwd_test(cp, 'cuda')

if parallelproj.torch_enabled:

def test_fwd_torch(self):
import array_api_compat.torch as torch
fwd_test(torch, 'cpu')

if parallelproj.torch_enabled and parallelproj.cupy_enabled:

def test_fwd_torch_cuda(self):
import array_api_compat.torch as torch
fwd_test(torch, 'cuda')

def test_adjoint(self):
"""test non TOF joseph forward projection using different backends"""
adjointness_test(np, 'cpu')
if np.__version__ >= '1.25':
adjointness_test(nparr, 'cpu')

if parallelproj.cupy_enabled:

def test_adjoint_cp(self):
import array_api_compat.cupy as cp
adjointness_test(cp, 'cuda')

if parallelproj.torch_enabled:

def test_adjoint_torch(self):
import array_api_compat.torch as torch
adjointness_test(torch, 'cpu')

if parallelproj.torch_enabled and parallelproj.cupy_enabled:

def test_adjoint_torch_cuda(self):
import array_api_compat.torch as torch
adjointness_test(torch, 'cuda')


#--------------------------------------------------------------------------

if __name__ == '__main__':
unittest.main()
58 changes: 22 additions & 36 deletions test/parallelproj/test_projectors.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
from __future__ import annotations

import unittest
import pytest
import parallelproj
import numpy.array_api as nparr
import array_api_compat
import array_api_compat.numpy as np

# generate list of array_api modules / device combinations to test
xp_dev_list = [(np, 'cpu')]

if np.__version__ >= '1.25':
xp_dev_list.append((nparr, 'cpu'))

if parallelproj.cupy_enabled:
import array_api_compat.cupy as cp
xp_dev_list.append((cp, 'cuda'))

if parallelproj.torch_enabled:
import array_api_compat.torch as torch
xp_dev_list.append((torch, 'cpu'))

if parallelproj.cuda_present:
xp_dev_list.append((torch, 'cuda'))

pytestmark = pytest.mark.parametrize("xp,dev", xp_dev_list)

#---------------------------------------------------------------------------------------

def allclose(x, y, atol: float = 1e-8, rtol: float = 1e-5) -> bool:
"""check if two arrays are close to each other, given absolute and relative error
Expand All @@ -15,7 +35,7 @@ def allclose(x, y, atol: float = 1e-8, rtol: float = 1e-5) -> bool:
return bool(xp.all(xp.less_equal(xp.abs(x - y), atol + rtol * xp.abs(y))))


def parallelviewprojector_test(xp, dev, verbose=True):
def test_parallelviewprojector(xp, dev, verbose=True):
image_shape = (2, 2)
voxel_size = (2., 2.)
image_origin = (-1., -1.)
Expand Down Expand Up @@ -87,37 +107,3 @@ def parallelviewprojector_test(xp, dev, verbose=True):
assert allclose(x3d_fwd[..., 0], exp_result_dp0)
assert allclose(x3d_fwd[..., 1], exp_result_dp1)
assert allclose(x3d_fwd[..., 2], exp_result_dp2)


#--------------------------------------------------------------------------


class TestParallelViewProjector(unittest.TestCase):

def test(self):
parallelviewprojector_test(np, 'cpu')

if np.__version__ >= '1.25':
parallelviewprojector_test(nparr, 'cpu')

if parallelproj.cupy_enabled:

def test_cp(self):
import array_api_compat.cupy as cp
parallelviewprojector_test(cp, 'cuda')

if parallelproj.torch_enabled:

def test_torch(self):
import torch
parallelviewprojector_test(torch, 'cpu')

if parallelproj.torch_enabled and parallelproj.cuda_present:

def test_torch_cuda(self):
import torch
parallelviewprojector_test(torch, dev='cuda')


if __name__ == '__main__':
unittest.main()
92 changes: 25 additions & 67 deletions test/parallelproj/test_toflm_joseph.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import unittest
import pytest
import parallelproj
import numpy.array_api as nparr
import array_api_compat.numpy as np

from types import ModuleType

# generate list of array_api modules / device combinations to test
xp_dev_list = [(np, 'cpu')]

if np.__version__ >= '1.25':
xp_dev_list.append((nparr, 'cpu'))

if parallelproj.cupy_enabled:
import array_api_compat.cupy as cp
xp_dev_list.append((cp, 'cuda'))

if parallelproj.torch_enabled:
import array_api_compat.torch as torch
xp_dev_list.append((torch, 'cpu'))

if parallelproj.cuda_present:
xp_dev_list.append((torch, 'cuda'))

pytestmark = pytest.mark.parametrize("xp,dev", xp_dev_list)

#---------------------------------------------------------------------------------------

def isclose(x: float,
y: float,
Expand All @@ -16,7 +36,7 @@ def isclose(x: float,
return bool(abs(x - y) <= (atol + rtol * abs(y)))


def tof_lm_fwd_test(xp: ModuleType,
def test_tof_lm_fwd(xp: ModuleType,
dev: str,
verbose: bool = True,
atol: float = 1e-6) -> bool:
Expand Down Expand Up @@ -112,10 +132,10 @@ def tof_lm_fwd_test(xp: ModuleType,
)
print('')

return bool(res1 * res2 * res3)
assert bool(res1 * res2 * res3)


def adjointness_test(xp: ModuleType,
def test_adjointness(xp: ModuleType,
dev: str,
nLORs: int = 10000,
seed: int = 1,
Expand Down Expand Up @@ -184,8 +204,6 @@ def adjointness_test(xp: ModuleType,
ip_a = float(xp.sum(back_img * img))
ip_b = float(xp.sum(img_fwd * lst))

res = isclose(ip_a, ip_b)

if verbose:
print(
f'module = {xp.__name__} - cuda_enabled {parallelproj.num_visible_cuda_devices > 0}'
Expand All @@ -194,64 +212,4 @@ def adjointness_test(xp: ModuleType,
print('ip_b = ', ip_b)
print('')

return res


#--------------------------------------------------------------------------


class TestLMTOFJoseph(unittest.TestCase):
"""test for TOF joseph projections"""

def test_fwd(self):
tof_lm_fwd_test(np, 'cpu')
if np.__version__ >= '1.25':
tof_lm_fwd_test(nparr, 'cpu')

if parallelproj.cupy_enabled:

def test_fwd_cp(self):
import array_api_compat.cupy as cp
tof_lm_fwd_test(cp, 'cuda')

if parallelproj.torch_enabled:

def test_fwd_torch(self):
import array_api_compat.torch as torch
tof_lm_fwd_test(torch, 'cpu')

if parallelproj.torch_enabled and parallelproj.cupy_enabled:

def test_fwd_torch_cuda(self):
import array_api_compat.torch as torch
tof_lm_fwd_test(torch, 'cuda')

def test_adjoint(self):
"""test non TOF joseph forward projection using different backends"""
adjointness_test(np, 'cpu')
if np.__version__ >= '1.25':
adjointness_test(nparr, 'cpu')

if parallelproj.cupy_enabled:

def test_adjoint_cp(self):
import array_api_compat.cupy as cp
adjointness_test(cp, 'cuda')

if parallelproj.torch_enabled:

def test_adjoint_torch(self):
import array_api_compat.torch as torch
adjointness_test(torch, 'cpu')

if parallelproj.torch_enabled and parallelproj.cupy_enabled:

def test_adjoint_torch_cuda(self):
import array_api_compat.torch as torch
adjointness_test(torch, 'cuda')


#--------------------------------------------------------------------------

if __name__ == '__main__':
unittest.main()
assert isclose(ip_a, ip_b)
Loading

0 comments on commit cb74010

Please sign in to comment.