33from cupy .cuda import nvtx
44import numpy as np
55import pytest
6+
67from httomolibgpu .prep .normalize import normalize
78from httomolibgpu .prep .stripe import (
89 remove_stripe_based_sorting ,
910 remove_stripe_ti ,
1011 remove_all_stripe ,
12+ raven_filter ,
1113)
1214from numpy .testing import assert_allclose
13-
15+ from . stripe_cpu_reference import raven_filter_numpy
1416
1517def test_remove_stripe_ti_on_data (data , flats , darks ):
1618 # --- testing the CuPy implementation from TomoCupy ---#
@@ -51,7 +53,6 @@ def test_remove_stripe_ti_on_data(data, flats, darks):
5153# np.median(corrected_data), np.median(corrected_host_data), rtol=1e-6
5254# )
5355
54-
5556def test_stripe_removal_sorting_cupy (data , flats , darks ):
5657 # --- testing the CuPy port of TomoPy's implementation ---#
5758 data = normalize (data , flats , darks , cutoff = 10 , minus_log = True )
@@ -66,6 +67,43 @@ def test_stripe_removal_sorting_cupy(data, flats, darks):
6667 assert corrected_data .dtype == np .float32
6768 assert corrected_data .flags .c_contiguous
6869
70+ def test_stripe_raven_cupy (data , flats , darks ):
71+ # --- testing the CuPy port of TomoPy's implementation ---#
72+
73+ data = normalize (data , flats , darks , cutoff = 10 , minus_log = True )
74+
75+ data_after_raven_gpu = raven_filter (cp .copy (data )).get ()
76+ data_after_raven_cpu = raven_filter_numpy (cp .copy (data ).get ())
77+
78+ assert_allclose (data_after_raven_cpu , data_after_raven_gpu , rtol = 0 , atol = 4e-01 )
79+
80+ data = None #: free up GPU memory
81+ # make sure the output is float32
82+ assert data_after_raven_gpu .dtype == np .float32
83+ assert data_after_raven_gpu .shape == data_after_raven_cpu .shape
84+
85+ @pytest .mark .parametrize ("uvalue" , [20 , 50 , 100 ])
86+ @pytest .mark .parametrize ("nvalue" , [2 , 4 , 6 ])
87+ @pytest .mark .parametrize ("vvalue" , [2 , 4 ])
88+ @pytest .mark .parametrize ("pad_x" , [0 , 10 , 20 ])
89+ @pytest .mark .parametrize ("pad_y" , [0 , 10 , 20 ])
90+ @cp .testing .numpy_cupy_allclose (rtol = 0 , atol = 3e-01 )
91+ def test_stripe_raven_parameters_cupy (ensure_clean_memory , xp , uvalue , nvalue , vvalue , pad_x , pad_y ):
92+ # because it's random, we explicitly seed and use numpy only, to match the data
93+ np .random .seed (12345 )
94+ data = np .random .random_sample (size = (256 , 5 , 512 )).astype (np .float32 ) * 2.0 + 0.001
95+ data = xp .asarray (data )
96+
97+ if xp .__name__ == "numpy" :
98+ results = raven_filter_numpy (
99+ data , uvalue = uvalue , nvalue = nvalue , vvalue = vvalue , pad_x = pad_x , pad_y = pad_y
100+ ).astype (np .float32 )
101+ else :
102+ results = raven_filter (
103+ data , uvalue = uvalue , nvalue = nvalue , vvalue = vvalue , pad_x = pad_x , pad_y = pad_y
104+ ).get ()
105+
106+ return xp .asarray (results )
69107
70108@pytest .mark .perf
71109def test_stripe_removal_sorting_cupy_performance (ensure_clean_memory ):
@@ -116,6 +154,29 @@ def test_remove_stripe_ti_performance(ensure_clean_memory):
116154
117155 assert "performance in ms" == duration_ms
118156
157+ @pytest .mark .perf
158+ def test_raven_filter_performance (ensure_clean_memory ):
159+ data_host = (
160+ np .random .random_sample (size = (1801 , 5 , 2560 )).astype (np .float32 ) * 2.0 + 0.001
161+ )
162+ data = cp .asarray (data_host , dtype = np .float32 )
163+
164+ # do a cold run first
165+ raven_filter (cp .copy (data ))
166+
167+ dev = cp .cuda .Device ()
168+ dev .synchronize ()
169+
170+ start = time .perf_counter_ns ()
171+ nvtx .RangePush ("Core" )
172+ for _ in range (10 ):
173+ # have to take copy, as data is modified in-place
174+ raven_filter (cp .copy (data ))
175+ nvtx .RangePop ()
176+ dev .synchronize ()
177+ duration_ms = float (time .perf_counter_ns () - start ) * 1e-6 / 10
178+
179+ assert "performance in ms" == duration_ms
119180
120181def test_remove_all_stripe_on_data (data , flats , darks ):
121182 # --- testing the CuPy implementation from TomoCupy ---#
0 commit comments