diff --git a/environment.yml b/environment.yml index bc06af95d..4bb5e81ac 100644 --- a/environment.yml +++ b/environment.yml @@ -27,3 +27,4 @@ dependencies: - jupyterlab-myst>=2.0.0 - myst-nb>=1.0.0 - polars>=1.14.0 + - numba-cuda>=0.24.0 diff --git a/pyproject.toml b/pyproject.toml index 2a2d5dfbb..22dae45d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,6 +88,7 @@ pip = "*" lxml = "*" fftw = "*" pyfftw = "*" +numba-cuda = "*" # readthedocs sphinx = ">=3.5.3" pydata-sphinx-theme = "*" @@ -112,5 +113,5 @@ tbb = ">=2019.5" tests = "./test.sh" coverage = "./test.sh coverage" docs = "cd docs && ./setup.sh" -black = 'black --exclude=".*\.ipynb" --extend-exclude=".venv|.pixi" --diff ./' +black = 'black --exclude=".*\.ipynb" --extend-exclude=".venv|.pixi" ./' isort = 'isort --profile black --skip .venv --skip .pixi ./' diff --git a/stumpy/__init__.py b/stumpy/__init__.py index 5df46ff8c..9d0ba9200 100644 --- a/stumpy/__init__.py +++ b/stumpy/__init__.py @@ -1,39 +1,63 @@ import ast +import importlib import os.path import pathlib +import types from importlib.metadata import distribution from site import getsitepackages from numba import cuda from . import cache, config -from .aamp import aamp # noqa: F401 -from .aamp_mmotifs import aamp_mmotifs # noqa: F401 -from .aamp_motifs import aamp_match, aamp_motifs # noqa: F401 -from .aamp_ostinato import aamp_ostinato, aamp_ostinatoed # noqa: F401 -from .aamp_stimp import aamp_stimp, aamp_stimped # noqa: F401 -from .aampdist import aampdist, aampdisted # noqa: F401 -from .aampdist_snippets import aampdist_snippets # noqa: F401 -from .aamped import aamped # noqa: F401 -from .aampi import aampi # noqa: F401 -from .chains import allc, atsc # noqa: F401 -from .core import mass # noqa: F401 -from .floss import floss, fluss # noqa: F401 -from .maamp import maamp, maamp_mdl, maamp_subspace # noqa: F401 -from .maamped import maamped # noqa: F401 -from .mmotifs import mmotifs # noqa: F401 -from .motifs import match, motifs # noqa: F401 -from .mpdist import mpdist, mpdisted # noqa: F401 -from .mstump import mdl, mstump, subspace # noqa: F401 -from .mstumped import mstumped # noqa: F401 -from .ostinato import ostinato, ostinatoed # noqa: F401 -from .scraamp import prescraamp, scraamp # noqa: F401 -from .scrump import prescrump, scrump # noqa: F401 -from .snippets import snippets # noqa: F401 -from .stimp import stimp, stimped # noqa: F401 -from .stump import stump # noqa: F401 -from .stumped import stumped # noqa: F401 -from .stumpi import stumpi # noqa: F401 + +# Define which functions belong to which module +# Key: function name to expose at top level +# Value: name of the module +_lazy_imports = { + "aamp": "aamp", + "aamp_mmotifs": "aamp_mmotifs", + "aamp_match": "aamp_motifs", + "aamp_motifs": "aamp_motifs", + "aamp_ostinato": "aamp_ostinato", + "aamp_ostinatoed": "aamp_ostinato", + "aamp_stimp": "aamp_stimp", + "aamp_stimped": "aamp_stimp", + "aampdist": "aampdist", + "aampdisted": "aampdist", + "aampdist_snippets": "aampdist_snippets", + "aamped": "aamped", + "aampi": "aampi", + "allc": "chains", + "atsc": "chains", + "mass": "core", + "floss": "floss", + "fluss": "floss", + "maamp": "maamp", + "maamp_mdl": "maamp", + "maamp_subspace": "maamp", + "maamped": "maamped", + "mmotifs": "mmotifs", + "match": "motifs", + "motifs": "motifs", + "mpdist": "mpdist", + "mpdisted": "mpdist", + "mdl": "mstump", + "mstump": "mstump", + "subspace": "mstump", + "mstumped": "mstumped", + "ostinato": "ostinato", + "ostinatoed": "ostinato", + "prescraamp": "scraamp", + "scraamp": "scraamp", + "prescrump": "scrump", + "scrump": "scrump", + "snippets": "snippets", + "stimp": "stimp", + "stimped": "stimp", + "stump": "stump", + "stumped": "stumped", + "stumpi": "stumpi", +} # Get the default fastmath flags for all njit functions # and update the _STUMPY_DEFAULTS dictionary @@ -61,14 +85,18 @@ def _get_fastmath_value(module_name, func_name): # pragma: no cover config._STUMPY_DEFAULTS[key] = _get_fastmath_value(module_name, func_name) if cuda.is_available(): - from .gpu_aamp import gpu_aamp # noqa: F401 - from .gpu_aamp_ostinato import gpu_aamp_ostinato # noqa: F401 - from .gpu_aamp_stimp import gpu_aamp_stimp # noqa: F401 - from .gpu_aampdist import gpu_aampdist # noqa: F401 - from .gpu_mpdist import gpu_mpdist # noqa: F401 - from .gpu_ostinato import gpu_ostinato # noqa: F401 - from .gpu_stimp import gpu_stimp # noqa: F401 - from .gpu_stump import gpu_stump # noqa: F401 + _lazy_imports.update( + { + "gpu_aamp": "gpu_aamp", + "gpu_aamp_ostinato": "gpu_aamp_ostinato", + "gpu_aamp_stimp": "gpu_aamp_stimp", + "gpu_aampdist": "gpu_aampdist", + "gpu_mpdist": "gpu_mpdist", + "gpu_ostinato": "gpu_ostinato", + "gpu_stimp": "gpu_stimp", + "gpu_stump": "gpu_stump", + } + ) else: # pragma: no cover from . import core from .core import _gpu_aamp_driver_not_found as gpu_aamp # noqa: F401 @@ -220,3 +248,69 @@ def _get_fastmath_value(module_name, func_name): # pragma: no cover __version__ = "Please install this project with setup.py" else: # pragma: no cover __version__ = _dist.version + + +# PEP 562: module-level __getattr__ for lazy imports +def __getattr__(name): # pragma: no cover + if name in _lazy_imports: + mod_name = _lazy_imports[name] + module = importlib.import_module(f"{__package__}.{mod_name}") + # Retrieve the attribute from the loaded module and cache it + attr = getattr(module, name) + globals()[name] = attr + return attr + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +# Ensure that if a module was imported during package import +# (causing the package attribute to point to the module object), we +# replace that entry with the actual attribute (e.g., function) so that +# users get the expected callable at `stumpy.aamp` rather than the module. +for _name, _sub in _lazy_imports.items(): # pragma: no cover + val = globals().get(_name) + if isinstance(val, types.ModuleType): + try: + replacement = getattr(val, _name) + except AttributeError: + # Nothing to do if the module doesn't define the attribute + continue + globals()[_name] = replacement + + +# Eagerly import exports that would otherwise collide with +# same-named modules. This keeps lazy imports for most names but +# ensures that when a top-level exported name exactly matches its +# module (e.g., `stump` -> `stump.py`), the exported attribute is +# available immediately so REPL completers prefer the callable/class +# instead of the module. +for _name, _sub in _lazy_imports.items(): # pragma: no cover + try: + if _name == _sub: + filepath = pathlib.Path(__file__).parent / f"{_sub}.py" + if filepath.exists(): + module = importlib.import_module(f"{__package__}.{_sub}") + try: + globals()[_name] = getattr(module, _name) + except AttributeError: + # If the module doesn't define the attribute, keep it lazy + pass + except Exception: + # Be conservative: don't let eager-import attempts raise during package import + pass + + +def __dir__(): # pragma: no cover + # Expose lazy names in dir() for discoverability + # Also include __all__ so tools that consult it will see the intended + # top-level exports (this helps some REPL completers prefer the + # callable/class exports over same-named modules). + all_names = list(globals().keys()) + list(_lazy_imports.keys()) + all_names += list(globals().get("__all__", [])) + return sorted(all_names) + + +# Make the lazy-exported names explicit for tools that respect __all__. +# This helps REPL tab-completion prefer functions/classes over modules +# when names collide (e.g., `stumpy.stump` should point to the function +# rather than the module during completion). +__all__ = sorted(list(_lazy_imports.keys())) diff --git a/stumpy/gpu_aamp_ostinato.py b/stumpy/gpu_aamp_ostinato.py index 261be03fb..dec46d3c0 100644 --- a/stumpy/gpu_aamp_ostinato.py +++ b/stumpy/gpu_aamp_ostinato.py @@ -2,8 +2,9 @@ # Copyright 2019 TD Ameritrade. Released under the terms of the 3-Clause BSD license. # STUMPY is a trademark of TD Ameritrade IP Company, Inc. All rights reserved. -from . import core, gpu_aamp +from . import core from .aamp_ostinato import _aamp_ostinato, _get_aamp_central_motif +from .gpu_aamp import gpu_aamp def gpu_aamp_ostinato(Ts, m, device_id=0, p=2.0): diff --git a/stumpy/gpu_aamp_stimp.py b/stumpy/gpu_aamp_stimp.py index 665a54d17..b2254b567 100644 --- a/stumpy/gpu_aamp_stimp.py +++ b/stumpy/gpu_aamp_stimp.py @@ -2,8 +2,8 @@ # Copyright 2019 TD Ameritrade. Released under the terms of the 3-Clause BSD license. # STUMPY is a trademark of TD Ameritrade IP Company, Inc. All rights reserved. -from . import gpu_aamp from .aamp_stimp import _aamp_stimp +from .gpu_aamp import gpu_aamp class gpu_aamp_stimp(_aamp_stimp): diff --git a/stumpy/gpu_aampdist.py b/stumpy/gpu_aampdist.py index 1879eb339..e05590e3e 100644 --- a/stumpy/gpu_aampdist.py +++ b/stumpy/gpu_aampdist.py @@ -4,8 +4,8 @@ import functools -from . import gpu_aamp from .core import _mpdist +from .gpu_aamp import gpu_aamp def gpu_aampdist(T_A, T_B, m, percentage=0.05, k=None, device_id=0, p=2.0): diff --git a/stumpy/stimp.py b/stumpy/stimp.py index 84452cd39..442353b2b 100644 --- a/stumpy/stimp.py +++ b/stumpy/stimp.py @@ -4,8 +4,9 @@ import numpy as np -from . import core, scrump +from . import core from .aamp_stimp import aamp_stimp, aamp_stimped +from .scrump import scrump from .stump import stump from .stumped import stumped diff --git a/stumpy/stomp.py b/stumpy/stomp.py index fc81aa03a..ea8a06e1a 100644 --- a/stumpy/stomp.py +++ b/stumpy/stomp.py @@ -6,7 +6,8 @@ import numpy as np -from . import config, core, stamp +from . import config, core +from .stamp import _mass_PI def _stomp(T_A, m, T_B=None, ignore_trivial=True): @@ -105,7 +106,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True): IR = -1 else: if ignore_trivial: - P, I = stamp._mass_PI( + P, I = _mass_PI( T_A[:m], T_B, M_T, @@ -115,7 +116,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True): T_subseq_isconstant=T_subseq_isconstant, Q_subseq_isconstant=Q_subseq_isconstant[[0]], ) - PR, IR = stamp._mass_PI( + PR, IR = _mass_PI( T_A[:m], T_B, M_T, @@ -127,7 +128,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True): Q_subseq_isconstant=Q_subseq_isconstant[[0]], ) else: - P, I = stamp._mass_PI( + P, I = _mass_PI( T_A[:m], T_B, M_T, diff --git a/stumpy/stumpi.py b/stumpy/stumpi.py index bf6d40661..da5cf7938 100644 --- a/stumpy/stumpi.py +++ b/stumpy/stumpi.py @@ -4,8 +4,9 @@ import numpy as np -from . import config, core, stump +from . import config, core from .aampi import aampi +from .stump import stump @core.non_normalized( diff --git a/tests/test_aamp.py b/tests/test_aamp.py index 99b5e9017..ab5dfc64a 100644 --- a/tests/test_aamp.py +++ b/tests/test_aamp.py @@ -4,7 +4,8 @@ import pandas as pd import pytest -from stumpy import aamp, config +from stumpy import config +from stumpy.aamp import aamp test_data = [ ( diff --git a/tests/test_aamp_mmotifs.py b/tests/test_aamp_mmotifs.py index 9f3c765be..b205fa2a5 100755 --- a/tests/test_aamp_mmotifs.py +++ b/tests/test_aamp_mmotifs.py @@ -3,7 +3,8 @@ import numpy.testing as npt import pytest -from stumpy import aamp_mmotifs, config +from stumpy import config +from stumpy.aamp_mmotifs import aamp_mmotifs test_data = [ np.array( diff --git a/tests/test_aamp_motifs.py b/tests/test_aamp_motifs.py index bf419d6b8..17e2488f0 100644 --- a/tests/test_aamp_motifs.py +++ b/tests/test_aamp_motifs.py @@ -3,7 +3,8 @@ import numpy.testing as npt import pytest -from stumpy import aamp_match, aamp_motifs, core +from stumpy import core +from stumpy.aamp_motifs import aamp_match, aamp_motifs test_data = [ ( diff --git a/tests/test_aamp_ostinato.py b/tests/test_aamp_ostinato.py index 241f3b0e1..466fb7efa 100644 --- a/tests/test_aamp_ostinato.py +++ b/tests/test_aamp_ostinato.py @@ -4,7 +4,8 @@ import pytest from dask.distributed import Client, LocalCluster -import stumpy +from stumpy import core +from stumpy.aamp_ostinato import aamp_ostinato, aamp_ostinatoed @pytest.fixture(scope="module") @@ -28,7 +29,7 @@ def test_random_ostinato(seed): Ts = [np.random.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.aamp_ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinato(Ts, m) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -43,7 +44,7 @@ def test_deterministic_ostinato(seed): for p in [1.0, 2.0, 3.0]: ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.aamp_ostinato(Ts, m, p=p) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinato(Ts, m, p=p) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -60,9 +61,7 @@ def test_random_ostinatoed(seed, dask_cluster): Ts = [np.random.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.aamp_ostinatoed( - dask_client, Ts, m - ) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinatoed(dask_client, Ts, m) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -78,7 +77,7 @@ def test_deterministic_ostinatoed(seed, dask_cluster): for p in [1.0, 2.0, 3.0]: ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.aamp_ostinatoed( + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinatoed( dask_client, Ts, m, p=p ) @@ -98,7 +97,7 @@ def test_input_not_overwritten_ostinato(): # raise error if aamp_ostinato overwrite its input Ts_input = [T.copy() for T in Ts] - stumpy.aamp_ostinato(Ts_input, m) + aamp_ostinato(Ts_input, m) for i in range(len(Ts)): T_ref = Ts[i] T_comp = Ts_input[i] @@ -119,7 +118,7 @@ def test_extract_several_consensus_ostinato(): # Find consensus motif and its NN in each time series in Ts_comp # Remove them from Ts_comp as well as Ts_ref, and assert that the # two time series are the same - radius, Ts_idx, subseq_idx = stumpy.aamp_ostinato(Ts_comp, m) + radius, Ts_idx, subseq_idx = aamp_ostinato(Ts_comp, m) consensus_motif = Ts_comp[Ts_idx][subseq_idx : subseq_idx + m].copy() for i in range(len(Ts_comp)): if i == Ts_idx: @@ -128,7 +127,7 @@ def test_extract_several_consensus_ostinato(): query_idx = None idx = np.argmin( - stumpy.core.mass( + core.mass( consensus_motif, Ts_comp[i], normalize=False, query_idx=query_idx ) ) @@ -152,7 +151,7 @@ def test_input_not_overwritten_ostinatoed(dask_cluster): # raise error if ostinato overwrite its input Ts_input = [T.copy() for T in Ts] - stumpy.aamp_ostinatoed(dask_client, Ts_input, m) + aamp_ostinatoed(dask_client, Ts_input, m) for i in range(len(Ts)): T_ref = Ts[i] T_comp = Ts_input[i] @@ -176,7 +175,7 @@ def test_extract_several_consensus_ostinatoed(dask_cluster): # Find consensus motif and its NN in each time series in Ts_comp # Remove them from Ts_comp as well as Ts_ref, and assert that the # two time series are the same - radius, Ts_idx, subseq_idx = stumpy.aamp_ostinatoed(dask_client, Ts_comp, m) + radius, Ts_idx, subseq_idx = aamp_ostinatoed(dask_client, Ts_comp, m) consensus_motif = Ts_comp[Ts_idx][subseq_idx : subseq_idx + m].copy() for i in range(len(Ts_comp)): if i == Ts_idx: @@ -185,7 +184,7 @@ def test_extract_several_consensus_ostinatoed(dask_cluster): query_idx = None idx = np.argmin( - stumpy.core.mass( + core.mass( consensus_motif, Ts_comp[i], normalize=False, diff --git a/tests/test_aamp_stimp.py b/tests/test_aamp_stimp.py index b573f09b9..d0588aa91 100644 --- a/tests/test_aamp_stimp.py +++ b/tests/test_aamp_stimp.py @@ -4,7 +4,7 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import aamp_stimp, aamp_stimped +from stumpy.aamp_stimp import aamp_stimp, aamp_stimped T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), diff --git a/tests/test_aampdist.py b/tests/test_aampdist.py index 973ce3726..541f92649 100644 --- a/tests/test_aampdist.py +++ b/tests/test_aampdist.py @@ -4,8 +4,7 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import aampdist, aampdisted -from stumpy.aampdist import _aampdist_vect +from stumpy.aampdist import _aampdist_vect, aampdist, aampdisted @pytest.fixture(scope="module") diff --git a/tests/test_aampdist_snippets.py b/tests/test_aampdist_snippets.py index 7ff912001..7356f3101 100644 --- a/tests/test_aampdist_snippets.py +++ b/tests/test_aampdist_snippets.py @@ -3,7 +3,8 @@ import numpy.testing as npt import pytest -from stumpy import aampdist_snippets, config +from stumpy import config +from stumpy.aampdist_snippets import aampdist_snippets test_data = [np.random.uniform(-1000, 1000, [64]).astype(np.float64)] s = [6, 7, 8] diff --git a/tests/test_aamped.py b/tests/test_aamped.py index 5c12ad730..58cd9e402 100644 --- a/tests/test_aamped.py +++ b/tests/test_aamped.py @@ -5,7 +5,8 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import aamped, config +from stumpy import config +from stumpy.aamped import aamped @pytest.fixture(scope="module") diff --git a/tests/test_aampi.py b/tests/test_aampi.py index 745404b12..03c6d6914 100644 --- a/tests/test_aampi.py +++ b/tests/test_aampi.py @@ -4,7 +4,8 @@ import pandas as pd import pytest -from stumpy import aampi, config, core +from stumpy import config, core +from stumpy.aampi import aampi substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] substitution_values = [np.nan, np.inf] diff --git a/tests/test_cache.py b/tests/test_cache.py index 2127c8ed2..4b70b48ae 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,7 +1,8 @@ import numba import numpy as np -from stumpy import cache, stump +from stumpy import cache +from stumpy.stump import stump def test_cache_get_njit_funcs(): diff --git a/tests/test_chains.py b/tests/test_chains.py index bdc3bd176..a2cb70aba 100644 --- a/tests/test_chains.py +++ b/tests/test_chains.py @@ -2,7 +2,7 @@ import numpy.testing as npt import pytest -from stumpy import allc, atsc +from stumpy.chains import allc, atsc test_data = [ ( diff --git a/tests/test_core.py b/tests/test_core.py index 109754b9b..0db8684ca 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -11,7 +11,8 @@ from numba import cuda from scipy.spatial.distance import cdist -from stumpy import config, core, stump +from stumpy import config, core +from stumpy.stump import stump if cuda.is_available(): diff --git a/tests/test_floss.py b/tests/test_floss.py index 74735d1af..af06c71e5 100644 --- a/tests/test_floss.py +++ b/tests/test_floss.py @@ -5,8 +5,10 @@ import numpy.testing as npt import pytest -from stumpy import aamp, core, floss, fluss, stump -from stumpy.floss import _cac, _iac, _nnmark, _rea +from stumpy import core +from stumpy.aamp import aamp +from stumpy.floss import _cac, _iac, _nnmark, _rea, floss, fluss +from stumpy.stump import stump def naive_nnmark(I): diff --git a/tests/test_gpu_aamp.py b/tests/test_gpu_aamp.py index 903f00f6d..7b180bc24 100644 --- a/tests/test_gpu_aamp.py +++ b/tests/test_gpu_aamp.py @@ -5,7 +5,13 @@ import pandas as pd from numba import cuda -from stumpy import config, gpu_aamp +from stumpy import config + +if cuda.is_available(): + from stumpy.gpu_aamp import gpu_aamp +else: # pragma: no cover + from stumpy.core import _gpu_aamp_driver_not_found as gpu_aamp # noqa: F401 + try: from numba.errors import NumbaPerformanceWarning diff --git a/tests/test_gpu_aamp_ostinato.py b/tests/test_gpu_aamp_ostinato.py index 8284aeff2..39069a49a 100644 --- a/tests/test_gpu_aamp_ostinato.py +++ b/tests/test_gpu_aamp_ostinato.py @@ -12,7 +12,14 @@ import naive import pytest -from stumpy import core, gpu_aamp_ostinato +from stumpy import core + +if cuda.is_available(): + from stumpy.gpu_aamp_ostinato import gpu_aamp_ostinato +else: # pragma: no cover + from stumpy.core import ( # noqa: F401 + _gpu_aamp_ostinato_driver_not_found as gpu_aamp_ostinato, + ) TEST_THREADS_PER_BLOCK = 10 diff --git a/tests/test_gpu_aamp_stimp.py b/tests/test_gpu_aamp_stimp.py index ce12c9402..e1226b457 100644 --- a/tests/test_gpu_aamp_stimp.py +++ b/tests/test_gpu_aamp_stimp.py @@ -4,7 +4,12 @@ import numpy.testing as npt from numba import cuda -from stumpy import gpu_aamp_stimp +if cuda.is_available(): + from stumpy.gpu_aamp_stimp import gpu_aamp_stimp +else: # pragma: no cover + from stumpy.core import ( # noqa: F401 + _gpu_aamp_stimp_driver_not_found as gpu_aamp_stimp, + ) try: from numba.errors import NumbaPerformanceWarning diff --git a/tests/test_gpu_aampdist.py b/tests/test_gpu_aampdist.py index 51f968bb6..c53b1bd88 100644 --- a/tests/test_gpu_aampdist.py +++ b/tests/test_gpu_aampdist.py @@ -4,7 +4,10 @@ import numpy.testing as npt from numba import cuda -from stumpy import gpu_aampdist +if cuda.is_available(): + from stumpy.gpu_aampdist import gpu_aampdist +else: # pragma: no cover + from stumpy.core import _gpu_aampdist_driver_not_found as gpu_aampdist # noqa: F401 try: from numba.errors import NumbaPerformanceWarning diff --git a/tests/test_gpu_mpdist.py b/tests/test_gpu_mpdist.py index ea481b151..49850d3d9 100644 --- a/tests/test_gpu_mpdist.py +++ b/tests/test_gpu_mpdist.py @@ -5,7 +5,10 @@ import numpy.testing as npt from numba import cuda -from stumpy import gpu_mpdist +if cuda.is_available(): + from stumpy.gpu_mpdist import gpu_mpdist +else: # pragma: no cover + from stumpy.core import _gpu_mpdist_driver_not_found as gpu_mpdist # noqa: F401 try: from numba.errors import NumbaPerformanceWarning diff --git a/tests/test_gpu_ostinato.py b/tests/test_gpu_ostinato.py index 30eb9539c..081de959d 100644 --- a/tests/test_gpu_ostinato.py +++ b/tests/test_gpu_ostinato.py @@ -14,7 +14,13 @@ import naive import pytest -from stumpy import core, gpu_ostinato +from stumpy import core + +if cuda.is_available(): + from stumpy.gpu_ostinato import gpu_ostinato +else: # pragma: no cover + from stumpy.core import _gpu_ostinato_driver_not_found as gpu_ostinato # noqa: F401 + TEST_THREADS_PER_BLOCK = 10 diff --git a/tests/test_gpu_stimp.py b/tests/test_gpu_stimp.py index 38a11b1bb..0507adf9a 100644 --- a/tests/test_gpu_stimp.py +++ b/tests/test_gpu_stimp.py @@ -5,7 +5,10 @@ import numpy.testing as npt from numba import cuda -from stumpy import gpu_stimp +if cuda.is_available(): + from stumpy.gpu_stimp import gpu_stimp +else: # pragma: no cover + from stumpy.core import _gpu_stimp_driver_not_found as gpu_stimp # noqa: F401 try: from numba.errors import NumbaPerformanceWarning diff --git a/tests/test_gpu_stump.py b/tests/test_gpu_stump.py index c80deb913..78913bd24 100644 --- a/tests/test_gpu_stump.py +++ b/tests/test_gpu_stump.py @@ -6,7 +6,13 @@ import pandas as pd from numba import cuda -from stumpy import config, gpu_stump +from stumpy import config + +if cuda.is_available(): + from stumpy.gpu_stump import gpu_stump +else: # pragma: no cover + from stumpy.core import _gpu_stump_driver_not_found as gpu_stump # noqa: F401 + try: from numba.errors import NumbaPerformanceWarning diff --git a/tests/test_maamp.py b/tests/test_maamp.py index 9294e99db..6ee8d4731 100644 --- a/tests/test_maamp.py +++ b/tests/test_maamp.py @@ -4,11 +4,14 @@ import pandas as pd import pytest -from stumpy import config, core, maamp, maamp_mdl, maamp_subspace +from stumpy import config, core from stumpy.maamp import ( _get_first_maamp_profile, _multi_mass_absolute, + maamp, + maamp_mdl, maamp_multi_distance_profile, + maamp_subspace, ) test_data = [ diff --git a/tests/test_maamped.py b/tests/test_maamped.py index 19b901e57..ff5ccd9a7 100644 --- a/tests/test_maamped.py +++ b/tests/test_maamped.py @@ -5,7 +5,8 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import config, maamped +from stumpy import config +from stumpy.maamped import maamped @pytest.fixture(scope="module") diff --git a/tests/test_mmotifs.py b/tests/test_mmotifs.py index 8752a6192..d70b476bb 100755 --- a/tests/test_mmotifs.py +++ b/tests/test_mmotifs.py @@ -3,7 +3,8 @@ import numpy.testing as npt import pytest -from stumpy import config, mmotifs +from stumpy import config +from stumpy.mmotifs import mmotifs test_data = [ np.array( diff --git a/tests/test_mmparray.py b/tests/test_mmparray.py index 06bf81bfa..b5803b94d 100644 --- a/tests/test_mmparray.py +++ b/tests/test_mmparray.py @@ -3,7 +3,8 @@ import numpy.testing as npt import pytest -from stumpy import maamp, mstump +from stumpy.maamp import maamp +from stumpy.mstump import mstump test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), diff --git a/tests/test_motifs.py b/tests/test_motifs.py index 61e9dedf1..cfe56c170 100644 --- a/tests/test_motifs.py +++ b/tests/test_motifs.py @@ -5,7 +5,8 @@ import numpy.testing as npt import pytest -from stumpy import core, match, motifs +from stumpy import core +from stumpy.motifs import match, motifs def naive_motifs(T, m, max_motifs, max_matches, T_subseq_isconstant=None): diff --git a/tests/test_mparray.py b/tests/test_mparray.py index 4f8ff3926..1ac0cf34a 100644 --- a/tests/test_mparray.py +++ b/tests/test_mparray.py @@ -4,8 +4,10 @@ import pandas as pd import pytest -from stumpy import aamp, config, stump +from stumpy import config +from stumpy.aamp import aamp from stumpy.mparray import mparray +from stumpy.stump import stump test_data = [ ( diff --git a/tests/test_mpdist.py b/tests/test_mpdist.py index 3ca444405..fe99e4812 100644 --- a/tests/test_mpdist.py +++ b/tests/test_mpdist.py @@ -6,8 +6,7 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import mpdist, mpdisted -from stumpy.mpdist import _mpdist_vect +from stumpy.mpdist import _mpdist_vect, mpdist, mpdisted @pytest.fixture(scope="module") diff --git a/tests/test_mstump.py b/tests/test_mstump.py index 6cb81b5d6..3e97cf58a 100644 --- a/tests/test_mstump.py +++ b/tests/test_mstump.py @@ -7,12 +7,15 @@ import polars as pl import pytest -from stumpy import config, core, mdl, mstump, subspace +from stumpy import config, core from stumpy.mstump import ( _get_first_mstump_profile, _get_multi_QT, _multi_mass, + mdl, + mstump, multi_distance_profile, + subspace, ) diff --git a/tests/test_mstumped.py b/tests/test_mstumped.py index 37906fda0..ef14991dc 100644 --- a/tests/test_mstumped.py +++ b/tests/test_mstumped.py @@ -7,7 +7,8 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import config, mstumped +from stumpy import config +from stumpy.mstumped import mstumped @pytest.fixture(scope="module") diff --git a/tests/test_non_normalized_decorator.py b/tests/test_non_normalized_decorator.py index 0395c3206..7dcafa5f8 100644 --- a/tests/test_non_normalized_decorator.py +++ b/tests/test_non_normalized_decorator.py @@ -4,9 +4,54 @@ from dask.distributed import Client, LocalCluster from numba import cuda -import stumpy -from stumpy.maamp import maamp_multi_distance_profile -from stumpy.mstump import multi_distance_profile +from stumpy import core +from stumpy.aamp import aamp +from stumpy.aamp_mmotifs import aamp_mmotifs +from stumpy.aamp_motifs import aamp_match, aamp_motifs +from stumpy.aamp_ostinato import aamp_ostinato, aamp_ostinatoed +from stumpy.aamp_stimp import aamp_stimp, aamp_stimped +from stumpy.aampdist import aampdist, aampdisted +from stumpy.aampdist_snippets import aampdist_snippets +from stumpy.aamped import aamped +from stumpy.aampi import aampi + +if cuda.is_available(): + from stumpy.gpu_aamp import gpu_aamp + from stumpy.gpu_aamp_ostinato import gpu_aamp_ostinato + from stumpy.gpu_aamp_stimp import gpu_aamp_stimp + from stumpy.gpu_aampdist import gpu_aampdist + from stumpy.gpu_mpdist import gpu_mpdist + from stumpy.gpu_ostinato import gpu_ostinato + from stumpy.gpu_stimp import gpu_stimp + from stumpy.gpu_stump import gpu_stump +else: # pragma: no cover + from stumpy.core import _gpu_aamp_driver_not_found as gpu_aamp # noqa: F401 + from stumpy.core import ( + _gpu_aamp_ostinato_driver_not_found as gpu_aamp_ostinato, + ) # noqa: F401 + from stumpy.core import ( + _gpu_aamp_stimp_driver_not_found as gpu_aamp_stimp, + ) # noqa: F401 + from stumpy.core import _gpu_aampdist_driver_not_found as gpu_aampdist # noqa: F401 + from stumpy.core import _gpu_mpdist_driver_not_found as gpu_mpdist # noqa: F401 + from stumpy.core import _gpu_ostinato_driver_not_found as gpu_ostinato # noqa: F401 + from stumpy.core import _gpu_stimp_driver_not_found as gpu_stimp # noqa: F401 + from stumpy.core import _gpu_stump_driver_not_found as gpu_stump # noqa: F401 +from stumpy.maamp import maamp, maamp_mdl, maamp_multi_distance_profile, maamp_subspace +from stumpy.maamped import maamped +from stumpy.mmotifs import mmotifs +from stumpy.motifs import match, motifs +from stumpy.mpdist import mpdist, mpdisted +from stumpy.mstump import mdl, mstump, multi_distance_profile, subspace +from stumpy.mstumped import mstumped +from stumpy.ostinato import ostinato, ostinatoed +from stumpy.scraamp import prescraamp, scraamp +from stumpy.scrump import prescrump, scrump +from stumpy.snippets import snippets +from stumpy.stimp import stimp, stimped +from stumpy.stump import stump +from stumpy.stumped import stumped +from stumpy.stumpi import stumpi try: from numba.errors import NumbaPerformanceWarning @@ -37,20 +82,20 @@ def dask_cluster(): def test_mass(): Q = np.random.rand(10) T = np.random.rand(20) - ref = stumpy.core.mass_absolute(Q, T) - comp = stumpy.core.mass(Q, T, normalize=False) + ref = core.mass_absolute(Q, T) + comp = core.mass(Q, T, normalize=False) npt.assert_almost_equal(ref, comp) Q = np.random.rand(10) T = np.random.rand(20) - T, T_subseq_isfinite = stumpy.core.preprocess_non_normalized(T, 10) - T_squared = np.sum(stumpy.core.rolling_window(T * T, Q.shape[0]), axis=-1) - ref = stumpy.core.mass_absolute(Q, T) - comp = stumpy.core.mass(Q, T, M_T=T_subseq_isfinite, normalize=False) + T, T_subseq_isfinite = core.preprocess_non_normalized(T, 10) + T_squared = np.sum(core.rolling_window(T * T, Q.shape[0]), axis=-1) + ref = core.mass_absolute(Q, T) + comp = core.mass(Q, T, M_T=T_subseq_isfinite, normalize=False) npt.assert_almost_equal(ref, comp) - comp = stumpy.core.mass(Q, T, Σ_T=T_squared, normalize=False) + comp = core.mass(Q, T, Σ_T=T_squared, normalize=False) npt.assert_almost_equal(ref, comp) - comp = stumpy.core.mass(Q, T, M_T=T_subseq_isfinite, Σ_T=T_squared, normalize=False) + comp = core.mass(Q, T, M_T=T_subseq_isfinite, Σ_T=T_squared, normalize=False) npt.assert_almost_equal(ref, comp) @@ -60,8 +105,8 @@ def test_stump(T, m): T = T.copy() T = T[0] - ref = stumpy.aamp(T, m) - comp = stumpy.stump(T, m, normalize=False) + ref = aamp(T, m) + comp = stump(T, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -71,8 +116,8 @@ def test_prescrump(T, m): T = T.copy() T = T[0] - ref = stumpy.prescraamp(T, m) - comp = stumpy.prescrump(T, m, normalize=False) + ref = prescraamp(T, m) + comp = prescrump(T, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -85,9 +130,9 @@ def test_scrump(T, m): seed = np.random.randint(100000) np.random.seed(seed) - ref = stumpy.scraamp(T, m) + ref = scraamp(T, m) np.random.seed(seed) - comp = stumpy.scrump(T, m, normalize=False) + comp = scrump(T, m, normalize=False) npt.assert_almost_equal(ref.P_, comp.P_) for i in range(10): @@ -104,9 +149,9 @@ def test_scrump_plus_plus(T, m): seed = np.random.randint(100000) np.random.seed(seed) - ref = stumpy.scraamp(T, m, pre_scraamp=True) + ref = scraamp(T, m, pre_scraamp=True) np.random.seed(seed) - comp = stumpy.scrump(T, m, pre_scrump=True, normalize=False) + comp = scrump(T, m, pre_scrump=True, normalize=False) npt.assert_almost_equal(ref.P_, comp.P_) for i in range(10): @@ -124,9 +169,9 @@ def test_scrump_plus_plus_full(T, m): seed = np.random.randint(100000) np.random.seed(seed) - ref = stumpy.scraamp(T, m, percentage=0.1, pre_scraamp=True) + ref = scraamp(T, m, percentage=0.1, pre_scraamp=True) np.random.seed(seed) - comp = stumpy.scrump(T, m, percentage=0.1, pre_scrump=True, normalize=False) + comp = scrump(T, m, percentage=0.1, pre_scrump=True, normalize=False) npt.assert_almost_equal(ref.P_, comp.P_) for i in range(10): @@ -143,8 +188,8 @@ def test_stumped(T, m, dask_cluster): T = T[0] with Client(dask_cluster) as dask_client: - ref = stumpy.aamped(dask_client, T, m) - comp = stumpy.stumped(dask_client, T, m, normalize=False) + ref = aamped(dask_client, T, m) + comp = stumped(dask_client, T, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -158,8 +203,8 @@ def test_gpu_stump(T, m): T = T.copy() T = T[0] - ref = stumpy.gpu_aamp(T, m) - comp = stumpy.gpu_stump(T, m, normalize=False) + ref = gpu_aamp(T, m) + comp = gpu_stump(T, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -169,8 +214,8 @@ def test_stumpi(T, m): T = T.copy() T = T[0] - ref_stream = stumpy.aampi(T, m) - comp_stream = stumpy.stumpi(T, m, normalize=False) + ref_stream = aampi(T, m) + comp_stream = stumpi(T, m, normalize=False) for i in range(10): t = np.random.rand() ref_stream.update(t) @@ -182,8 +227,8 @@ def test_ostinato(): m = 50 Ts = [np.random.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = stumpy.aamp_ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinato(Ts, m, normalize=False) + ref_radius, ref_Ts_idx, ref_subseq_idx = aamp_ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m, normalize=False) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -196,10 +241,8 @@ def test_ostinatoed(dask_cluster): Ts = [np.random.rand(n) for n in [64, 128, 256]] with Client(dask_cluster) as dask_client: - ref_radius, ref_Ts_idx, ref_subseq_idx = stumpy.aamp_ostinatoed( - dask_client, Ts, m - ) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinatoed( + ref_radius, ref_Ts_idx, ref_subseq_idx = aamp_ostinatoed(dask_client, Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed( dask_client, Ts, m, normalize=False ) @@ -216,10 +259,8 @@ def test_gpu_ostinato(): m = 50 Ts = [np.random.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = stumpy.gpu_aamp_ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.gpu_ostinato( - Ts, m, normalize=False - ) + ref_radius, ref_Ts_idx, ref_subseq_idx = gpu_aamp_ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato(Ts, m, normalize=False) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -231,8 +272,8 @@ def test_mpdist(): T_B = np.random.uniform(-1000, 1000, [64]).astype(np.float64) m = 5 - ref = stumpy.aampdist(T_A, T_B, m) - comp = stumpy.mpdist(T_A, T_B, m, normalize=False) + ref = aampdist(T_A, T_B, m) + comp = mpdist(T_A, T_B, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -243,8 +284,8 @@ def test_mpdisted(dask_cluster): m = 5 with Client(dask_cluster) as dask_client: - ref = stumpy.aampdisted(dask_client, T_A, T_B, m) - comp = stumpy.mpdisted(dask_client, T_A, T_B, m, normalize=False) + ref = aampdisted(dask_client, T_A, T_B, m) + comp = mpdisted(dask_client, T_A, T_B, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -257,8 +298,8 @@ def test_gpu_mpdist(): T_B = np.random.uniform(-1000, 1000, [64]).astype(np.float64) m = 5 - ref = stumpy.gpu_aampdist(T_A, T_B, m) - comp = stumpy.gpu_mpdist(T_A, T_B, m, normalize=False) + ref = gpu_aampdist(T_A, T_B, m) + comp = gpu_mpdist(T_A, T_B, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -272,8 +313,8 @@ def test_multi_distance_profile(T, m): @pytest.mark.parametrize("T, m", test_data) def test_mstump(T, m): - ref = stumpy.maamp(T, m) - comp = stumpy.mstump(T, m, normalize=False) + ref = maamp(T, m) + comp = mstump(T, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -281,8 +322,8 @@ def test_mstump(T, m): @pytest.mark.parametrize("T, m", test_data) def test_mstumped(T, m, dask_cluster): with Client(dask_cluster) as dask_client: - ref = stumpy.maamped(dask_client, T, m) - comp = stumpy.mstumped(dask_client, T, m, normalize=False) + ref = maamped(dask_client, T, m) + comp = mstumped(dask_client, T, m, normalize=False) npt.assert_almost_equal(ref, comp) @@ -292,8 +333,8 @@ def test_subspace(T, m): nn_idx = 4 for k in range(T.shape[0]): - ref_S = stumpy.maamp_subspace(T, m, subseq_idx, nn_idx, k) - comp_S = stumpy.subspace(T, m, subseq_idx, nn_idx, k, normalize=False) + ref_S = maamp_subspace(T, m, subseq_idx, nn_idx, k) + comp_S = subspace(T, m, subseq_idx, nn_idx, k, normalize=False) npt.assert_almost_equal(ref_S, comp_S) @@ -302,8 +343,8 @@ def test_mdl(T, m): subseq_idx = np.full(T.shape[0], 1) nn_idx = np.full(T.shape[0], 4) - ref_MDL, ref_S = stumpy.maamp_mdl(T, m, subseq_idx, nn_idx) - comp_MDL, comp_S = stumpy.mdl(T, m, subseq_idx, nn_idx, normalize=False) + ref_MDL, ref_S = maamp_mdl(T, m, subseq_idx, nn_idx) + comp_MDL, comp_S = mdl(T, m, subseq_idx, nn_idx, normalize=False) npt.assert_almost_equal(ref_MDL, comp_MDL) for ref, cmp in zip(ref_S, comp_S): @@ -316,9 +357,9 @@ def test_motifs(T, m): T = T.copy() T = T[0] - mp = stumpy.aamp(T, m) - ref = stumpy.aamp_motifs(T, mp[:, 0]) - comp = stumpy.motifs(T, mp[:, 0], normalize=False) + mp = aamp(T, m) + ref = aamp_motifs(T, mp[:, 0]) + comp = motifs(T, mp[:, 0], normalize=False) npt.assert_almost_equal(ref, comp) @@ -329,18 +370,16 @@ def test_match(T, m): T = T[0] Q = T[:m] - ref = stumpy.aamp_match(Q, T) - comp = stumpy.match(Q, T, normalize=False) + ref = aamp_match(Q, T) + comp = match(Q, T, normalize=False) npt.assert_almost_equal(ref, comp) @pytest.mark.parametrize("T, m", test_data) def test_mmotifs(T, m): - mps, indices = stumpy.maamp(T, m) - ref_distances, ref_indices, ref_subspaces, ref_mdls = stumpy.aamp_mmotifs( - T, mps, indices - ) - cmp_distances, cmp_indices, cmp_subspaces, cmp_mdls = stumpy.mmotifs( + mps, indices = maamp(T, m) + ref_distances, ref_indices, ref_subspaces, ref_mdls = aamp_mmotifs(T, mps, indices) + cmp_distances, cmp_indices, cmp_subspaces, cmp_mdls = mmotifs( T, mps, indices, normalize=False ) npt.assert_almost_equal(ref_distances, cmp_distances) @@ -359,7 +398,7 @@ def test_snippets(): ref_fractions, ref_areas, ref_regimes, - ) = stumpy.aampdist_snippets(T, m, k) + ) = aampdist_snippets(T, m, k) ( cmp_snippets, cmp_indices, @@ -367,7 +406,7 @@ def test_snippets(): cmp_fractions, cmp_areas, cmp_regimes, - ) = stumpy.snippets(T, m, k, normalize=False) + ) = snippets(T, m, k, normalize=False) npt.assert_almost_equal(ref_snippets, cmp_snippets) @@ -380,12 +419,12 @@ def test_stimp(T, m): seed = np.random.randint(100000) np.random.seed(seed) - ref = stumpy.aamp_stimp(T, m) + ref = aamp_stimp(T, m) for i in range(n): ref.update() np.random.seed(seed) - cmp = stumpy.stimp(T, m, normalize=False) + cmp = stimp(T, m, normalize=False) for i in range(n): cmp.update() @@ -412,12 +451,12 @@ def test_stimped(T, m, dask_cluster): seed = np.random.randint(100000) with Client(dask_cluster) as dask_client: np.random.seed(seed) - ref = stumpy.aamp_stimped(dask_client, T, m) + ref = aamp_stimped(dask_client, T, m) for i in range(n): ref.update() np.random.seed(seed) - cmp = stumpy.stimped(dask_client, T, m, normalize=False) + cmp = stimped(dask_client, T, m, normalize=False) for i in range(n): cmp.update() @@ -447,12 +486,12 @@ def test_gpu_stimp(T, m): seed = np.random.randint(100000) np.random.seed(seed) - ref = stumpy.gpu_aamp_stimp(T, m) + ref = gpu_aamp_stimp(T, m) for i in range(n): ref.update() np.random.seed(seed) - cmp = stumpy.gpu_stimp(T, m, normalize=False) + cmp = gpu_stimp(T, m, normalize=False) for i in range(n): cmp.update() diff --git a/tests/test_ostinato.py b/tests/test_ostinato.py index 23a04440d..04bd3b441 100644 --- a/tests/test_ostinato.py +++ b/tests/test_ostinato.py @@ -6,7 +6,8 @@ import pytest from dask.distributed import Client, LocalCluster -import stumpy +from stumpy import core +from stumpy.ostinato import ostinato, ostinatoed @pytest.fixture(scope="module") @@ -30,7 +31,7 @@ def test_random_ostinato(seed): Ts = [np.random.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -44,7 +45,7 @@ def test_deterministic_ostinato(seed): Ts = [np.random.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -61,9 +62,7 @@ def test_random_ostinatoed(seed, dask_cluster): Ts = [np.random.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinatoed( - dask_client, Ts, m - ) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed(dask_client, Ts, m) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -78,9 +77,7 @@ def test_deterministic_ostinatoed(seed, dask_cluster): Ts = [np.random.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinatoed( - dask_client, Ts, m - ) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed(dask_client, Ts, m) npt.assert_almost_equal(ref_radius, comp_radius) npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) @@ -103,7 +100,7 @@ def test_random_ostinato_with_isconstant(seed): ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant ) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinato( + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato( Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant ) @@ -135,7 +132,7 @@ def test_deterministic_ostinatoed_with_isconstant(seed, dask_cluster): ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant ) - comp_radius, comp_Ts_idx, comp_subseq_idx = stumpy.ostinatoed( + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed( dask_client, Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant ) @@ -155,7 +152,7 @@ def test_input_not_overwritten_ostinato(): # raise error if ostinato overwrite its input Ts_input = [T.copy() for T in Ts] - stumpy.ostinato(Ts_input, m) + ostinato(Ts_input, m) for i in range(len(Ts)): T_ref = Ts[i] T_comp = Ts_input[i] @@ -176,7 +173,7 @@ def test_extract_several_consensus_ostinato(): # Find consensus motif and its NN in each time series in Ts_comp # Remove them from Ts_comp as well as Ts_ref, and assert that the # two time series are the same - radius, Ts_idx, subseq_idx = stumpy.ostinato(Ts_comp, m) + radius, Ts_idx, subseq_idx = ostinato(Ts_comp, m) consensus_motif = Ts_comp[Ts_idx][subseq_idx : subseq_idx + m].copy() for i in range(len(Ts_comp)): if i == Ts_idx: @@ -184,9 +181,7 @@ def test_extract_several_consensus_ostinato(): else: query_idx = None - idx = np.argmin( - stumpy.core.mass(consensus_motif, Ts_comp[i], query_idx=query_idx) - ) + idx = np.argmin(core.mass(consensus_motif, Ts_comp[i], query_idx=query_idx)) Ts_comp[i][idx : idx + m] = np.nan Ts_ref[i][idx : idx + m] = np.nan @@ -207,7 +202,7 @@ def test_input_not_overwritten_ostinatoed(dask_cluster): # raise error if ostinato overwrite its input Ts_input = [T.copy() for T in Ts] - stumpy.ostinatoed(dask_client, Ts_input, m) + ostinatoed(dask_client, Ts_input, m) for i in range(len(Ts)): T_ref = Ts[i] T_comp = Ts_input[i] @@ -231,7 +226,7 @@ def test_extract_several_consensus_ostinatoed(dask_cluster): # Find consensus motif and its NN in each time series in Ts_comp # Remove them from Ts_comp as well as Ts_ref, and assert that the # two time series are the same - radius, Ts_idx, subseq_idx = stumpy.ostinatoed(dask_client, Ts_comp, m) + radius, Ts_idx, subseq_idx = ostinatoed(dask_client, Ts_comp, m) consensus_motif = Ts_comp[Ts_idx][subseq_idx : subseq_idx + m].copy() for i in range(len(Ts_comp)): if i == Ts_idx: @@ -240,7 +235,7 @@ def test_extract_several_consensus_ostinatoed(dask_cluster): query_idx = None idx = np.argmin( - stumpy.core.mass(consensus_motif, Ts_comp[i], query_idx=query_idx) + core.mass(consensus_motif, Ts_comp[i], query_idx=query_idx) ) Ts_comp[i][idx : idx + m] = np.nan Ts_ref[i][idx : idx + m] = np.nan diff --git a/tests/test_precision.py b/tests/test_precision.py index 12a4481f8..dadb2802f 100644 --- a/tests/test_precision.py +++ b/tests/test_precision.py @@ -8,9 +8,14 @@ import pytest from numba import cuda -import stumpy from stumpy import cache, config, core, fastmath +if cuda.is_available(): + from stumpy.gpu_stump import gpu_stump +else: # pragma: no cover + from stumpy.core import _gpu_stump_driver_not_found as gpu_stump # noqa: F401 +from stumpy.snippets import snippets + try: from numba.errors import NumbaPerformanceWarning except ModuleNotFoundError: @@ -46,7 +51,7 @@ def test_mpdist_snippets_s(): cmp_fractions, cmp_areas, cmp_regimes, - ) = stumpy.snippets(T, m, k, s=s) + ) = snippets(T, m, k, s=s) npt.assert_almost_equal( ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION @@ -146,7 +151,7 @@ def test_snippets(): cmp_fractions, cmp_areas, cmp_regimes, - ) = stumpy.snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func) + ) = snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func) if ( not np.allclose(ref_snippets, cmp_snippets) and not numba.config.DISABLE_JIT @@ -165,9 +170,7 @@ def test_snippets(): cmp_fractions, cmp_areas, cmp_regimes, - ) = stumpy.snippets( - T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func - ) + ) = snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func) npt.assert_almost_equal( ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION @@ -216,8 +219,8 @@ def test_distance_symmetry_property_in_gpu(): T_A = T[i : i + m] T_B = T[j : j + m] - mp_AB = stumpy.gpu_stump(T_A, m, T_B) - mp_BA = stumpy.gpu_stump(T_B, m, T_A) + mp_AB = gpu_stump(T_A, m, T_B) + mp_BA = gpu_stump(T_B, m, T_A) d_ij = mp_AB[0, 0] d_ji = mp_BA[0, 0] diff --git a/tests/test_ray.py b/tests/test_ray.py index 6f86426d9..58e752bea 100644 --- a/tests/test_ray.py +++ b/tests/test_ray.py @@ -9,7 +9,12 @@ RAY_IMPORTED = True except ImportError: # pragma: no cover RAY_IMPORTED = False -from stumpy import aamp_stimped, aamped, maamped, mstumped, stimped, stumped +from stumpy.aamp_stimp import aamp_stimped +from stumpy.aamped import aamped +from stumpy.maamped import maamped +from stumpy.mstumped import mstumped +from stumpy.stimp import stimped +from stumpy.stumped import stumped @pytest.fixture(scope="module") diff --git a/tests/test_scraamp.py b/tests/test_scraamp.py index 8f2c8337a..faccf0fa6 100644 --- a/tests/test_scraamp.py +++ b/tests/test_scraamp.py @@ -3,8 +3,9 @@ import numpy.testing as npt import pytest -from stumpy import aamp, config, scraamp -from stumpy.scraamp import prescraamp +from stumpy import config +from stumpy.aamp import aamp +from stumpy.scraamp import prescraamp, scraamp test_data = [ ( diff --git a/tests/test_scrump.py b/tests/test_scrump.py index b3cc70bf3..7c1ea76a6 100644 --- a/tests/test_scrump.py +++ b/tests/test_scrump.py @@ -5,8 +5,9 @@ import numpy.testing as npt import pytest -from stumpy import config, scrump, stump -from stumpy.scrump import prescrump +from stumpy import config +from stumpy.scrump import prescrump, scrump +from stumpy.stump import stump test_data = [ ( diff --git a/tests/test_snippets.py b/tests/test_snippets.py index 3f645c514..1aa893885 100644 --- a/tests/test_snippets.py +++ b/tests/test_snippets.py @@ -5,8 +5,8 @@ import numpy.testing as npt import pytest -from stumpy import config, snippets -from stumpy.snippets import _get_all_profiles +from stumpy import config +from stumpy.snippets import _get_all_profiles, snippets test_data = [np.random.uniform(-1000, 1000, [64]).astype(np.float64)] s = [3, 6, 7, 8] diff --git a/tests/test_stamp.py b/tests/test_stamp.py index 48cbae74b..3ec3e9b47 100644 --- a/tests/test_stamp.py +++ b/tests/test_stamp.py @@ -5,7 +5,8 @@ import numpy.testing as npt import pytest -from stumpy import core, stamp +from stumpy import core +from stumpy.stamp import _mass_PI, stamp test_data = [ ( @@ -32,14 +33,12 @@ def test_stamp_mass_PI(T_A, T_B): ref_P, ref_I, ref_left_I, ref_right_I = naive.mass_PI( Q, T_B, m, trivial_idx=trivial_idx, excl_zone=zone, ignore_trivial=True ) - comp_P, comp_I = stamp._mass_PI( - Q, T_B, M_T, Σ_T, trivial_idx=trivial_idx, excl_zone=zone - ) + comp_P, comp_I = _mass_PI(Q, T_B, M_T, Σ_T, trivial_idx=trivial_idx, excl_zone=zone) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) - comp_left_P, comp_left_I = stamp._mass_PI( + comp_left_P, comp_left_I = _mass_PI( Q, T_B, M_T, @@ -51,7 +50,7 @@ def test_stamp_mass_PI(T_A, T_B): npt.assert_almost_equal(ref_left_I, comp_left_I) - comp_right_P, comp_right_I = stamp._mass_PI( + comp_right_P, comp_right_I = _mass_PI( Q, T_B, M_T, @@ -75,7 +74,7 @@ def test_stamp_self_join(T_A, T_B): m = 3 zone = int(np.ceil(m / 2)) ref_mp = naive.stump(T_B, m, exclusion_zone=zone, row_wise=True) - comp_mp = stamp.stamp(T_B, T_B, m, ignore_trivial=True) + comp_mp = stamp(T_B, T_B, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp[:, :2], comp_mp) @@ -85,7 +84,7 @@ def test_stamp_self_join(T_A, T_B): def test_stamp_A_B_join(T_A, T_B): m = 3 ref_mp = naive.stump(T_A, m, T_B=T_B, row_wise=True) - comp_mp = stamp.stamp(T_A, T_B, m) + comp_mp = stamp(T_A, T_B, m) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp[:, :2], comp_mp) @@ -105,7 +104,7 @@ def test_stamp_nan_inf_self_join(T_A, T_B, substitute_B, substitution_locations) zone = int(np.ceil(m / 2)) ref_mp = naive.stump(T_B_sub, m, exclusion_zone=zone, row_wise=True) - comp_mp = stamp.stamp(T_B_sub, T_B_sub, m, ignore_trivial=True) + comp_mp = stamp(T_B_sub, T_B_sub, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp[:, :2], comp_mp) @@ -131,7 +130,7 @@ def test_stamp_nan_inf_A_B_join( T_B_sub[substitution_location_B] = substitute_B ref_mp = naive.stump(T_A_sub, m, T_B=T_B_sub, row_wise=True) - comp_mp = stamp.stamp(T_A_sub, T_B_sub, m) + comp_mp = stamp(T_A_sub, T_B_sub, m) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp[:, :2], comp_mp) @@ -143,7 +142,7 @@ def test_stamp_nan_zero_mean_self_join(): zone = int(np.ceil(m / 2)) ref_mp = naive.stump(T, m, exclusion_zone=zone, row_wise=True) - comp_mp = stamp.stamp(T, T, m, ignore_trivial=True) + comp_mp = stamp(T, T, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) @@ -176,7 +175,7 @@ def test_stamp_mass_PI_with_isconstant_case1(): T_subseq_isconstant=isconstant_custom_func, Q_subseq_isconstant=isconstant_custom_func, ) - comp_P, comp_I = stamp._mass_PI( + comp_P, comp_I = _mass_PI( Q, T_B, M_T, @@ -190,7 +189,7 @@ def test_stamp_mass_PI_with_isconstant_case1(): npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) - comp_left_P, comp_left_I = stamp._mass_PI( + comp_left_P, comp_left_I = _mass_PI( Q, T_B, M_T, @@ -204,7 +203,7 @@ def test_stamp_mass_PI_with_isconstant_case1(): npt.assert_almost_equal(ref_left_I, comp_left_I) - comp_right_P, comp_right_I = stamp._mass_PI( + comp_right_P, comp_right_I = _mass_PI( Q, T_B, M_T, @@ -245,7 +244,7 @@ def test_stamp_mass_PI_with_isconstant_case2(): T_subseq_isconstant=isconstant_custom_func, Q_subseq_isconstant=isconstant_custom_func, ) - comp_P, comp_I = stamp._mass_PI( + comp_P, comp_I = _mass_PI( Q, T_B, M_T, @@ -259,7 +258,7 @@ def test_stamp_mass_PI_with_isconstant_case2(): npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) - comp_left_P, comp_left_I = stamp._mass_PI( + comp_left_P, comp_left_I = _mass_PI( Q, T_B, M_T, @@ -273,7 +272,7 @@ def test_stamp_mass_PI_with_isconstant_case2(): npt.assert_almost_equal(ref_left_I, comp_left_I) - comp_right_P, comp_right_I = stamp._mass_PI( + comp_right_P, comp_right_I = _mass_PI( Q, T_B, M_T, @@ -303,7 +302,7 @@ def test_stamp_self_join_with_isconstant(T_A, T_B): row_wise=True, T_A_subseq_isconstant=isconstant_custom_func, ) - comp_mp = stamp.stamp( + comp_mp = stamp( T_B, T_B, m, diff --git a/tests/test_stimp.py b/tests/test_stimp.py index c5015c53d..932e6b9e7 100644 --- a/tests/test_stimp.py +++ b/tests/test_stimp.py @@ -6,7 +6,7 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import stimp, stimped +from stumpy.stimp import stimp, stimped T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), diff --git a/tests/test_stomp.py b/tests/test_stomp.py index 401811ed9..3ae67ce46 100644 --- a/tests/test_stomp.py +++ b/tests/test_stomp.py @@ -3,7 +3,7 @@ import numpy.testing as npt import pytest -from stumpy import stomp +from stumpy.stomp import _stomp test_data = [ ( @@ -23,7 +23,7 @@ def test_stomp_int_input(): with pytest.raises(TypeError): - stomp(np.arange(10), 5, ignore_trivial=True) + _stomp(np.arange(10), 5, ignore_trivial=True) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -31,7 +31,7 @@ def test_stomp_self_join(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) ref_mp = naive.stump(T_B, m, exclusion_zone=zone, row_wise=True) - comp_mp = stomp._stomp(T_B, m, ignore_trivial=True) + comp_mp = _stomp(T_B, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp, comp_mp) @@ -43,7 +43,7 @@ def test_stump_self_join_larger_window(T_A, T_B, m): if len(T_B) > m: zone = int(np.ceil(m / 4)) ref_mp = naive.stump(T_B, m, exclusion_zone=zone, row_wise=True) - comp_mp = stomp._stomp(T_B, m, ignore_trivial=True) + comp_mp = _stomp(T_B, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) @@ -54,7 +54,7 @@ def test_stump_self_join_larger_window(T_A, T_B, m): def test_stomp_A_B_join(T_A, T_B): m = 3 ref_mp = naive.stump(T_A, m, T_B=T_B, row_wise=True) - comp_mp = stomp._stomp(T_A, m, T_B, ignore_trivial=False) + comp_mp = _stomp(T_A, m, T_B, ignore_trivial=False) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp, comp_mp) @@ -74,7 +74,7 @@ def test_stomp_nan_inf_self_join(T_A, T_B, substitute_B, substitution_locations) zone = int(np.ceil(m / 4)) ref_mp = naive.stump(T_B_sub, m, exclusion_zone=zone, row_wise=True) - comp_mp = stomp._stomp(T_B_sub, m, ignore_trivial=True) + comp_mp = _stomp(T_B_sub, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp, comp_mp) @@ -100,7 +100,7 @@ def test_stomp_nan_inf_A_B_join( T_B_sub[substitution_location_B] = substitute_B ref_mp = naive.stump(T_A_sub, m, T_B=T_B_sub, row_wise=True) - comp_mp = stomp._stomp(T_A_sub, m, T_B_sub, ignore_trivial=False) + comp_mp = _stomp(T_A_sub, m, T_B_sub, ignore_trivial=False) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) npt.assert_almost_equal(ref_mp, comp_mp) @@ -112,7 +112,7 @@ def test_stomp_nan_zero_mean_self_join(): zone = int(np.ceil(m / 4)) ref_mp = naive.stump(T, m, exclusion_zone=zone, row_wise=True) - comp_mp = stomp._stomp(T, m, ignore_trivial=True) + comp_mp = _stomp(T, m, ignore_trivial=True) naive.replace_inf(ref_mp) naive.replace_inf(comp_mp) diff --git a/tests/test_stump.py b/tests/test_stump.py index fe35920cd..e26f5def8 100644 --- a/tests/test_stump.py +++ b/tests/test_stump.py @@ -7,7 +7,8 @@ import polars as pl import pytest -from stumpy import config, stump +from stumpy import config +from stumpy.stump import stump test_data = [ ( diff --git a/tests/test_stumped.py b/tests/test_stumped.py index 56d54d691..95ae7c916 100644 --- a/tests/test_stumped.py +++ b/tests/test_stumped.py @@ -8,7 +8,8 @@ import pytest from dask.distributed import Client, LocalCluster -from stumpy import config, stumped +from stumpy import config +from stumpy.stumped import stumped @pytest.fixture(scope="module") diff --git a/tests/test_stumpi.py b/tests/test_stumpi.py index ecb9148c9..09559f934 100644 --- a/tests/test_stumpi.py +++ b/tests/test_stumpi.py @@ -6,7 +6,8 @@ import pandas as pd import pytest -from stumpy import config, core, stumpi +from stumpy import config, core +from stumpy.stumpi import stumpi substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] substitution_values = [np.nan, np.inf]