Skip to content

Commit 99ef190

Browse files
committed
move precision-related test functions to test_precision and allow second attempt with disabled jit
1 parent ff3cd66 commit 99ef190

File tree

2 files changed

+189
-133
lines changed

2 files changed

+189
-133
lines changed

tests/test_precision.py

Lines changed: 189 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,54 @@ def test_calculate_squared_distance():
115115
npt.assert_almost_equal(ref, comp, decimal=14)
116116

117117

118-
def test_snippets():
118+
@pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning)
119+
@patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK)
120+
def test_distance_symmetry_property_in_gpu():
121+
if not cuda.is_available(): # pragma: no cover
122+
pytest.skip("Skipping Tests No GPUs Available")
123+
124+
# This test function raises an error if the distance between a subsequence
125+
# and another one does not satisfy the symmetry property.
126+
seed = 332
127+
np.random.seed(seed)
128+
T = np.random.uniform(-1000.0, 1000.0, [64])
129+
m = 3
130+
131+
i, j = 2, 10
132+
# M_T, Σ_T = core.compute_mean_std(T, m)
133+
# Σ_T[i] is `650.912209452633`
134+
# Σ_T[j] is `722.0717285148525`
135+
136+
# This test raises an error if arithmetic operation in ...
137+
# ... `gpu_stump._compute_and_update_PI_kernel` does not
138+
# generates the same result if values of variable for mean and std
139+
# are swapped.
140+
141+
T_A = T[i : i + m]
142+
T_B = T[j : j + m]
143+
144+
mp_AB = stumpy.gpu_stump(T_A, m, T_B)
145+
mp_BA = stumpy.gpu_stump(T_B, m, T_A)
146+
147+
d_ij = mp_AB[0, 0]
148+
d_ji = mp_BA[0, 0]
149+
150+
comp = d_ij - d_ji
151+
ref = 0.0
152+
153+
npt.assert_almost_equal(comp, ref, decimal=15)
154+
155+
156+
def test_snippets_rare_case_1():
119157
# This test function raises an error if there is a considerable loss of precision
120158
# that violates the symmetry property of a distance measure.
159+
seed = 332
160+
np.random.seed(seed)
161+
T = np.random.uniform(-1000.0, 1000.0, 64)
162+
121163
m = 10
122164
k = 3
123165
s = 3
124-
seed = 332
125-
np.random.seed(seed)
126-
T = np.random.uniform(-1000.0, 1000.0, [64])
127166

128167
isconstant_custom_func = functools.partial(
129168
naive.isconstant_func_stddev_threshold, quantile_threshold=0.05
@@ -190,39 +229,158 @@ def test_snippets():
190229
cache._recompile()
191230

192231

193-
@pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning)
194-
@patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK)
195-
def test_distance_symmetry_property_in_gpu():
196-
if not cuda.is_available(): # pragma: no cover
197-
pytest.skip("Skipping Tests No GPUs Available")
232+
def test_snippets_rare_case_2():
233+
# This test fails when the naive implementation of snippet,
234+
# i.e. `naive.mpdist_snippets`, uses `np.sum` instead of
235+
# math.fsum when calculating the sum of many small
236+
# floating point numbers. For more details, see issue #1061
198237

199-
# This test function raises an error if the distance between a subsequence
200-
# and another one does not satisfy the symmetry property.
201-
seed = 332
238+
seed = 1615
202239
np.random.seed(seed)
203-
T = np.random.uniform(-1000.0, 1000.0, [64])
204-
m = 3
240+
T = np.random.uniform(-1000.0, 1000.0, 64)
205241

206-
i, j = 2, 10
207-
# M_T, Σ_T = core.compute_mean_std(T, m)
208-
# Σ_T[i] is `650.912209452633`
209-
# Σ_T[j] is `722.0717285148525`
242+
m = 10
243+
s = 3
244+
k = 3
210245

211-
# This test raises an error if arithmetic operation in ...
212-
# ... `gpu_stump._compute_and_update_PI_kernel` does not
213-
# generates the same result if values of variable for mean and std
214-
# are swapped.
246+
isconstant_custom_func = functools.partial(
247+
naive.isconstant_func_stddev_threshold, quantile_threshold=0.05
248+
)
249+
(
250+
ref_snippets,
251+
ref_indices,
252+
ref_profiles,
253+
ref_fractions,
254+
ref_areas,
255+
ref_regimes,
256+
) = naive.mpdist_snippets(
257+
T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func
258+
)
215259

216-
T_A = T[i : i + m]
217-
T_B = T[j : j + m]
260+
(
261+
cmp_snippets,
262+
cmp_indices,
263+
cmp_profiles,
264+
cmp_fractions,
265+
cmp_areas,
266+
cmp_regimes,
267+
) = stumpy.snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func)
218268

219-
mp_AB = stumpy.gpu_stump(T_A, m, T_B)
220-
mp_BA = stumpy.gpu_stump(T_B, m, T_A)
269+
if (
270+
not np.allclose(ref_snippets, cmp_snippets) and not numba.config.DISABLE_JIT
271+
): # pragma: no cover
272+
# Revise fastmath flags by removing reassoc (to improve precision),
273+
# recompile njit functions, and re-compute snippets.
274+
fastmath._set(
275+
"core", "_calculate_squared_distance", {"nsz", "arcp", "contract", "afn"}
276+
)
277+
cache._recompile()
221278

222-
d_ij = mp_AB[0, 0]
223-
d_ji = mp_BA[0, 0]
279+
(
280+
cmp_snippets,
281+
cmp_indices,
282+
cmp_profiles,
283+
cmp_fractions,
284+
cmp_areas,
285+
cmp_regimes,
286+
) = stumpy.snippets(
287+
T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func
288+
)
224289

225-
comp = d_ij - d_ji
226-
ref = 0.0
290+
npt.assert_almost_equal(
291+
ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION
292+
)
293+
npt.assert_almost_equal(
294+
ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION
295+
)
296+
npt.assert_almost_equal(
297+
ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION
298+
)
299+
npt.assert_almost_equal(
300+
ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION
301+
)
302+
npt.assert_almost_equal(ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION)
303+
npt.assert_almost_equal(ref_regimes, cmp_regimes)
227304

228-
npt.assert_almost_equal(comp, ref, decimal=15)
305+
if not numba.config.DISABLE_JIT: # pragma: no cover
306+
# Revert fastmath flag back to their default values
307+
fastmath._reset("core", "_calculate_squared_distance")
308+
cache._recompile()
309+
310+
311+
def test_snippets_rare_case_3():
312+
# This test fails when the naive implementation of snippet,
313+
# i.e. `naive.mpdist_snippets`, uses `np.sum` instead of
314+
# math.fsum when calculating the sum of many small
315+
# floating point numbers. For more details, see issue #1061
316+
317+
seed = 2636
318+
np.random.seed(seed)
319+
T = np.random.uniform(-1000.0, 1000.0, 64)
320+
m = 9
321+
s = 3
322+
k = 3
323+
324+
isconstant_custom_func = functools.partial(
325+
naive.isconstant_func_stddev_threshold, quantile_threshold=0.05
326+
)
327+
(
328+
ref_snippets,
329+
ref_indices,
330+
ref_profiles,
331+
ref_fractions,
332+
ref_areas,
333+
ref_regimes,
334+
) = naive.mpdist_snippets(
335+
T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func
336+
)
337+
338+
(
339+
cmp_snippets,
340+
cmp_indices,
341+
cmp_profiles,
342+
cmp_fractions,
343+
cmp_areas,
344+
cmp_regimes,
345+
) = stumpy.snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func)
346+
347+
if (
348+
not np.allclose(ref_snippets, cmp_snippets) and not numba.config.DISABLE_JIT
349+
): # pragma: no cover
350+
# Revise fastmath flags by removing reassoc (to improve precision),
351+
# recompile njit functions, and re-compute snippets.
352+
fastmath._set(
353+
"core", "_calculate_squared_distance", {"nsz", "arcp", "contract", "afn"}
354+
)
355+
cache._recompile()
356+
357+
(
358+
cmp_snippets,
359+
cmp_indices,
360+
cmp_profiles,
361+
cmp_fractions,
362+
cmp_areas,
363+
cmp_regimes,
364+
) = stumpy.snippets(
365+
T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func
366+
)
367+
368+
npt.assert_almost_equal(
369+
ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION
370+
)
371+
npt.assert_almost_equal(
372+
ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION
373+
)
374+
npt.assert_almost_equal(
375+
ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION
376+
)
377+
npt.assert_almost_equal(
378+
ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION
379+
)
380+
npt.assert_almost_equal(ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION)
381+
npt.assert_almost_equal(ref_regimes, cmp_regimes)
382+
383+
if not numba.config.DISABLE_JIT: # pragma: no cover
384+
# Revert fastmath flag back to their default values
385+
fastmath._reset("core", "_calculate_squared_distance")
386+
cache._recompile()

tests/test_snippets.py

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -222,105 +222,3 @@ def test_mpdist_snippets_s_with_isconstant(T, m, k, s):
222222
)
223223
npt.assert_almost_equal(ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION)
224224
npt.assert_almost_equal(ref_regimes, cmp_regimes)
225-
226-
227-
def test_mpdist_snippets_s_with_isconstant_rare_case_1():
228-
# This test fails when the naive implementation of snippet,
229-
# i.e. `naive.mpdist_snippets`, uses `np.sum` instead of
230-
# math.fsum when calculating the sum of many small
231-
# floating point numbers. For more details, see issue #1061
232-
233-
seed = 1615
234-
np.random.seed(seed)
235-
T = np.random.uniform(-1000.0, 1000.0, 64)
236-
m = 10
237-
s = 3
238-
k = 3
239-
240-
isconstant_custom_func = functools.partial(
241-
naive.isconstant_func_stddev_threshold, quantile_threshold=0.05
242-
)
243-
(
244-
ref_snippets,
245-
ref_indices,
246-
ref_profiles,
247-
ref_fractions,
248-
ref_areas,
249-
ref_regimes,
250-
) = naive.mpdist_snippets(
251-
T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func
252-
)
253-
(
254-
cmp_snippets,
255-
cmp_indices,
256-
cmp_profiles,
257-
cmp_fractions,
258-
cmp_areas,
259-
cmp_regimes,
260-
) = snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func)
261-
262-
npt.assert_almost_equal(
263-
ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION
264-
)
265-
npt.assert_almost_equal(
266-
ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION
267-
)
268-
npt.assert_almost_equal(
269-
ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION
270-
)
271-
npt.assert_almost_equal(
272-
ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION
273-
)
274-
npt.assert_almost_equal(ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION)
275-
npt.assert_almost_equal(ref_regimes, cmp_regimes)
276-
277-
278-
def test_mpdist_snippets_s_with_isconstant_rare_case_2():
279-
# This test fails when the naive implementation of snippet,
280-
# i.e. `naive.mpdist_snippets`, uses `np.sum` instead of
281-
# math.fsum when calculating the sum of many small
282-
# floating point numbers. For more details, see issue #1061
283-
284-
seed = 2636
285-
np.random.seed(seed)
286-
T = np.random.uniform(-1000.0, 1000.0, 64)
287-
m = 9
288-
s = 3
289-
k = 3
290-
291-
isconstant_custom_func = functools.partial(
292-
naive.isconstant_func_stddev_threshold, quantile_threshold=0.05
293-
)
294-
(
295-
ref_snippets,
296-
ref_indices,
297-
ref_profiles,
298-
ref_fractions,
299-
ref_areas,
300-
ref_regimes,
301-
) = naive.mpdist_snippets(
302-
T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func
303-
)
304-
(
305-
cmp_snippets,
306-
cmp_indices,
307-
cmp_profiles,
308-
cmp_fractions,
309-
cmp_areas,
310-
cmp_regimes,
311-
) = snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func)
312-
313-
npt.assert_almost_equal(
314-
ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION
315-
)
316-
npt.assert_almost_equal(
317-
ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION
318-
)
319-
npt.assert_almost_equal(
320-
ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION
321-
)
322-
npt.assert_almost_equal(
323-
ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION
324-
)
325-
npt.assert_almost_equal(ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION)
326-
npt.assert_almost_equal(ref_regimes, cmp_regimes)

0 commit comments

Comments
 (0)