Skip to content

Commit 5be3b20

Browse files
authored
Merge pull request #191 from DiamondLightSource/testsnew
adds tests for the added 360 data sample
2 parents d6ad4c4 + a6f3109 commit 5be3b20

File tree

6 files changed

+202
-43
lines changed

6 files changed

+202
-43
lines changed

.scripts/download_zenodo.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import urllib.request
55
import hashlib
66
import sys
7-
import os
87
from pathlib import Path
98

109

@@ -19,15 +18,15 @@ def calculate_md5(filename):
1918

2019
def download_zenodo_files(output_dir: Path):
2120
"""
22-
Download all files from Zenodo record 14652312 and verify their checksums.
21+
Download all files from Zenodo record 14833590 and verify their checksums.
2322
2423
Args:
2524
output_dir: Directory where files should be downloaded
2625
"""
2726
try:
28-
print("Fetching files from Zenodo record 14652312...")
27+
print("Fetching files from Zenodo record 14833590...")
2928
with urllib.request.urlopen(
30-
"https://zenodo.org/api/records/14652312"
29+
"https://zenodo.org/api/records/14833590"
3130
) as response:
3231
data = json.loads(response.read())
3332

pyproject.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ addopts = [
7272
"-vv",
7373
"-ra",
7474
"-q",
75-
"--benchmark-sort=mean",
76-
"--benchmark-columns=mean",
7775
"--tb=native",
7876
"--cov-report=term",
7977
"--cov-report=xml:cov.xml",

zenodo-tests/conftest.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import cupy as cp
33
import numpy as np
44
import pytest
5+
import gc
6+
57

68
def pytest_addoption(parser):
79
parser.addoption(
@@ -31,8 +33,8 @@ def pytest_collection_modifyitems(config, items):
3133
item.add_marker(skip_perf)
3234

3335

34-
#CUR_DIR = os.path.abspath(os.path.dirname(__file__))
35-
CUR_DIR = "/dls/science/users/kjy41806/zenodo-tests/"
36+
CUR_DIR = os.path.abspath(os.path.dirname(__file__))
37+
3638

3739
@pytest.fixture(scope="session")
3840
def test_data_path():
@@ -119,6 +121,22 @@ def i13_dataset2(i13_dataset2_file):
119121
)
120122

121123

124+
@pytest.fixture(scope="session")
125+
def i13_dataset3_file(test_data_path):
126+
in_file = os.path.join(test_data_path, "i13_dataset3.npz")
127+
return np.load(in_file)
128+
129+
130+
@pytest.fixture
131+
def i13_dataset3(i13_dataset3_file):
132+
return (
133+
cp.asarray(i13_dataset3_file["projdata"]),
134+
i13_dataset3_file["angles"],
135+
cp.asarray(i13_dataset3_file["flats"]),
136+
cp.asarray(i13_dataset3_file["darks"]),
137+
)
138+
139+
122140
@pytest.fixture(scope="session")
123141
def k11_dataset1_file(test_data_path):
124142
in_file = os.path.join(test_data_path, "k11_dataset1.npz")
@@ -153,8 +171,15 @@ def geant4_dataset1(geant4_dataset1_file):
153171

154172
@pytest.fixture
155173
def ensure_clean_memory():
174+
gc.collect()
156175
cp.get_default_memory_pool().free_all_blocks()
157176
cp.get_default_pinned_memory_pool().free_all_blocks()
158177
yield None
159178
cp.get_default_memory_pool().free_all_blocks()
160179
cp.get_default_pinned_memory_pool().free_all_blocks()
180+
181+
182+
def force_clean_gpu_memory():
183+
gc.collect()
184+
cp.get_default_memory_pool().free_all_blocks()
185+
cp.get_default_pinned_memory_pool().free_all_blocks()

zenodo-tests/test_misc/test_morph.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,22 @@
66
from numpy.testing import assert_allclose
77
from httomolibgpu.misc.morph import sino_360_to_180
88
from httomolibgpu.prep.normalize import normalize
9+
from conftest import force_clean_gpu_memory
910

1011

11-
def test_sino_360_to_180_i13_dataset1(i13_dataset1, ensure_clean_memory):
12-
12+
def test_sino_360_to_180_i13_dataset1(i13_dataset1):
1313
projdata = i13_dataset1[0]
1414
flats = i13_dataset1[2]
1515
darks = i13_dataset1[3]
1616
del i13_dataset1
17-
17+
1818
data_normalised = normalize(projdata, flats, darks, minus_log=True)
1919
del flats, darks, projdata
20-
ensure_clean_memory
20+
force_clean_gpu_memory()
2121

22-
stiched_data_180degrees = sino_360_to_180(data_normalised, overlap = 473.822265625, rotation = 'right')
22+
stiched_data_180degrees = sino_360_to_180(
23+
data_normalised, overlap=473.822265625, rotation="right"
24+
)
2325
stiched_data_180degrees = stiched_data_180degrees.get()
2426

2527
assert_allclose(np.sum(stiched_data_180degrees), 28512826.0, rtol=1e-07, atol=1e-6)
@@ -28,4 +30,22 @@ def test_sino_360_to_180_i13_dataset1(i13_dataset1, ensure_clean_memory):
2830
assert stiched_data_180degrees.flags.c_contiguous
2931

3032

33+
def test_sino_360_to_180_i13_dataset3(i13_dataset3):
34+
projdata = i13_dataset3[0]
35+
flats = i13_dataset3[2]
36+
darks = i13_dataset3[3]
37+
del i13_dataset3
38+
39+
data_normalised = normalize(projdata, flats, darks, minus_log=True)
40+
del flats, darks, projdata
41+
force_clean_gpu_memory()
3142

43+
stiched_data_180degrees = sino_360_to_180(
44+
data_normalised, overlap=438.173828, rotation="left"
45+
)
46+
stiched_data_180degrees = stiched_data_180degrees.get()
47+
48+
assert_allclose(np.sum(stiched_data_180degrees), 24865750.0, rtol=1e-07, atol=1e-6)
49+
assert stiched_data_180degrees.shape == (3000, 3, 4682)
50+
assert stiched_data_180degrees.dtype == np.float32
51+
assert stiched_data_180degrees.flags.c_contiguous

zenodo-tests/test_recon/test_algorithm.py

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,23 @@
33
import pytest
44
from cupy.cuda import nvtx
55
import time
6+
from math import isclose
67

78
from httomolibgpu.prep.normalize import normalize
89
from httomolibgpu.recon.algorithm import (
910
FBP,
1011
LPRec,
1112
)
13+
from httomolibgpu.misc.morph import sino_360_to_180
1214
from numpy.testing import assert_allclose
1315
import time
1416
import pytest
1517
from cupy.cuda import nvtx
18+
from conftest import force_clean_gpu_memory
1619

17-
def test_reconstruct_FBP_i12_dataset1(i12_dataset1, ensure_clean_memory):
1820

21+
def test_reconstruct_FBP_i12_dataset1(i12_dataset1):
22+
force_clean_gpu_memory()
1923
projdata = i12_dataset1[0]
2024
angles = i12_dataset1[1]
2125
flats = i12_dataset1[2]
@@ -24,22 +28,64 @@ def test_reconstruct_FBP_i12_dataset1(i12_dataset1, ensure_clean_memory):
2428

2529
data_normalised = normalize(projdata, flats, darks, minus_log=True)
2630
del flats, darks, projdata
27-
ensure_clean_memory
31+
force_clean_gpu_memory()
2832

2933
recon_data = FBP(
3034
data_normalised,
3135
np.deg2rad(angles),
3236
center=1253.75,
33-
filter_freq_cutoff=0.35,
37+
filter_freq_cutoff=0.35,
3438
)
3539
assert recon_data.flags.c_contiguous
3640
recon_data = recon_data.get()
3741
assert_allclose(np.sum(recon_data), 46569.395, rtol=1e-07, atol=1e-6)
3842
assert recon_data.dtype == np.float32
3943
assert recon_data.shape == (2560, 50, 2560)
4044

45+
46+
def test_reconstruct_LP_REC_i13_dataset1(i13_dataset1):
47+
force_clean_gpu_memory()
48+
projdata = i13_dataset1[0]
49+
angles = i13_dataset1[1]
50+
flats = i13_dataset1[2]
51+
darks = i13_dataset1[3]
52+
del i13_dataset1
53+
54+
data_normalised = normalize(projdata, flats, darks, minus_log=True)
55+
del flats, darks, projdata
56+
force_clean_gpu_memory()
57+
58+
stiched_data_180degrees = sino_360_to_180(
59+
data_normalised[:, 2:3, :], overlap=473.822265625, rotation="right"
60+
)
61+
del data_normalised
62+
force_clean_gpu_memory()
63+
64+
# GPU archetictures older than 5.3 wont accept the data larger than
65+
# (4096, 4096, 4096), while the newer ones can accept (16384 x 16384 x 16384)
66+
67+
# recon_data = FBP(
68+
# stiched_data_180degrees,
69+
# np.deg2rad(angles[0:3000]),
70+
# center=2322,
71+
# filter_freq_cutoff=0.35,
72+
# )
73+
recon_data = LPRec(
74+
data=stiched_data_180degrees,
75+
angles=np.deg2rad(angles[0:3000]),
76+
center=2322.08,
77+
)
78+
79+
assert recon_data.flags.c_contiguous
80+
recon_data = recon_data.get()
81+
assert isclose(np.sum(recon_data), 620.856, abs_tol=10**-3)
82+
assert recon_data.dtype == np.float32
83+
assert recon_data.shape == (4646, 1, 4646)
84+
85+
4186
@pytest.mark.perf
42-
def test_FBP_performance_i13_dataset2(i13_dataset2, ensure_clean_memory):
87+
def test_FBP_performance_i13_dataset2(i13_dataset2):
88+
force_clean_gpu_memory()
4389
dev = cp.cuda.Device()
4490
projdata = i13_dataset2[0]
4591
angles = i13_dataset2[1]
@@ -49,25 +95,25 @@ def test_FBP_performance_i13_dataset2(i13_dataset2, ensure_clean_memory):
4995

5096
data_normalised = normalize(projdata, flats, darks, minus_log=True)
5197
del flats, darks, projdata
52-
ensure_clean_memory
98+
force_clean_gpu_memory()
5399

54100
# cold run first
55101
FBP(
56102
data_normalised,
57103
np.deg2rad(angles),
58104
center=1253.75,
59105
filter_freq_cutoff=0.35,
60-
)
106+
)
61107
dev.synchronize()
62108

63109
start = time.perf_counter_ns()
64110
nvtx.RangePush("Core")
65111
for _ in range(10):
66112
FBP(
67-
data_normalised,
68-
np.deg2rad(angles),
69-
center=1286.25,
70-
filter_freq_cutoff=0.35,
113+
data_normalised,
114+
np.deg2rad(angles),
115+
center=1286.25,
116+
filter_freq_cutoff=0.35,
71117
)
72118
nvtx.RangePop()
73119
dev.synchronize()
@@ -76,8 +122,8 @@ def test_FBP_performance_i13_dataset2(i13_dataset2, ensure_clean_memory):
76122
assert "performance in ms" == duration_ms
77123

78124

79-
def test_reconstruct_LPREC_i13_dataset2(i13_dataset2, ensure_clean_memory):
80-
125+
def test_reconstruct_LPREC_i13_dataset2(i13_dataset2):
126+
force_clean_gpu_memory()
81127
projdata = i13_dataset2[0]
82128
angles = i13_dataset2[1]
83129
flats = i13_dataset2[2]
@@ -86,8 +132,7 @@ def test_reconstruct_LPREC_i13_dataset2(i13_dataset2, ensure_clean_memory):
86132

87133
data_normalised = normalize(projdata, flats, darks, minus_log=True)
88134
del flats, darks, projdata
89-
ensure_clean_memory
90-
135+
force_clean_gpu_memory()
91136

92137
recon_data = LPRec(
93138
data=data_normalised,
@@ -97,13 +142,13 @@ def test_reconstruct_LPREC_i13_dataset2(i13_dataset2, ensure_clean_memory):
97142
assert recon_data.flags.c_contiguous
98143
recon_data = recon_data.get()
99144

100-
assert_allclose(np.sum(recon_data), 2044.9531, rtol=1e-07, atol=1e-6)
145+
assert isclose(np.sum(recon_data), 2044.953, abs_tol=10**-3)
101146
assert recon_data.dtype == np.float32
102147
assert recon_data.shape == (2560, 10, 2560)
103148

104149

105150
@pytest.mark.perf
106-
def test_LPREC_performance_i13_dataset2(i13_dataset2, ensure_clean_memory):
151+
def test_LPREC_performance_i13_dataset2(i13_dataset2):
107152
dev = cp.cuda.Device()
108153
projdata = i13_dataset2[0]
109154
angles = i13_dataset2[1]
@@ -113,7 +158,7 @@ def test_LPREC_performance_i13_dataset2(i13_dataset2, ensure_clean_memory):
113158

114159
data_normalised = normalize(projdata, flats, darks, minus_log=True)
115160
del flats, darks, projdata
116-
ensure_clean_memory
161+
force_clean_gpu_memory()
117162

118163
# cold run first
119164
LPRec(
@@ -127,12 +172,45 @@ def test_LPREC_performance_i13_dataset2(i13_dataset2, ensure_clean_memory):
127172
nvtx.RangePush("Core")
128173
for _ in range(10):
129174
LPRec(
130-
data=data_normalised,
131-
angles=np.deg2rad(angles),
132-
center=1286.25,
175+
data=data_normalised,
176+
angles=np.deg2rad(angles),
177+
center=1286.25,
133178
)
134179
nvtx.RangePop()
135180
dev.synchronize()
136181
duration_ms = float(time.perf_counter_ns() - start) * 1e-6 / 10
137182

138-
assert "performance in ms" == duration_ms
183+
assert "performance in ms" == duration_ms
184+
185+
186+
def test_reconstruct_FBP_i13_dataset3(i13_dataset3):
187+
force_clean_gpu_memory()
188+
projdata = i13_dataset3[0]
189+
angles = i13_dataset3[1]
190+
flats = i13_dataset3[2]
191+
darks = i13_dataset3[3]
192+
del i13_dataset3
193+
194+
data_normalised = normalize(projdata, flats, darks, minus_log=True)
195+
del flats, darks, projdata
196+
force_clean_gpu_memory()
197+
198+
stiched_data_180degrees = sino_360_to_180(
199+
data_normalised, overlap=438.173828, rotation="left"
200+
)
201+
force_clean_gpu_memory()
202+
203+
# GPU archetictures older than 5.3 wont accept the data larger than
204+
# (4096, 4096, 4096), while the newer ones can accept (16384 x 16384 x 16384)
205+
206+
recon_data = FBP(
207+
stiched_data_180degrees,
208+
np.deg2rad(angles[0:3000]),
209+
center=2341,
210+
filter_freq_cutoff=0.35,
211+
)
212+
213+
assert recon_data.flags.c_contiguous
214+
recon_data = recon_data.get()
215+
assert recon_data.dtype == np.float32
216+
assert recon_data.shape == (4682, 3, 4682)

0 commit comments

Comments
 (0)