kernels 0.16.1__tar.gz → 0.16.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kernels-0.16.1 → kernels-0.16.2}/PKG-INFO +1 -1
- {kernels-0.16.1 → kernels-0.16.2}/pyproject.toml +1 -1
- kernels-0.16.2/src/kernels/minver.py +69 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/utils.py +2 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/PKG-INFO +1 -1
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/SOURCES.txt +2 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_archs.py +2 -1
- kernels-0.16.2/tests/test_minver.py +112 -0
- {kernels-0.16.1 → kernels-0.16.2}/README.md +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/setup.cfg +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/__init__.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/_system.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/_versions.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/_windows.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/archs.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/backends.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmark.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/__init__.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/activation.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/attention.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/layer_norm.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/__init__.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/benchmark.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/benchmark_graphics.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/verify_signature.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/versions.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/compat.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/deps.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/__init__.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/_interval_tree.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/device.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/func.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/globals.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/kernelize.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/layer.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/mode.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/repos.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/lockfile.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/python_depends.json +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/status.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/variants.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels/verify.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/dependency_links.txt +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/entry_points.txt +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/requires.txt +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/top_level.txt +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_basic.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_benchmarks.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_deps.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_doctest.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_func.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_interval_tree.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_kernel_locking.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_layer.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_loaded_kernels.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_status.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_tvm_ffi.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_user_agent.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_variants.py +0 -0
- {kernels-0.16.1 → kernels-0.16.2}/tests/test_verify.py +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import warnings
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from kernels_data import Metadata, Version
|
|
6
|
+
from packaging.version import InvalidVersion, parse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _read_kernels_minver(variant_path: Path) -> Version | None:
|
|
10
|
+
"""The minimum `kernels` version required by a build variant."""
|
|
11
|
+
|
|
12
|
+
# Note, for kernels >= 0.17, we read the version from the metadata,
|
|
13
|
+
# but to minimize the impact in the backport, we are reading from
|
|
14
|
+
# metadata.json here directly.
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
with open(variant_path / "metadata.json", "rb") as f:
|
|
18
|
+
minver = json.load(f).get("kernels-minver")
|
|
19
|
+
except (OSError, ValueError):
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
if not isinstance(minver, str):
|
|
23
|
+
return None
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
return Version.from_str(minver)
|
|
27
|
+
except ValueError:
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _installed_version() -> Version | None:
|
|
32
|
+
"""The installed `kernels` version as a numeric version."""
|
|
33
|
+
# Avoid an import cycle.
|
|
34
|
+
from kernels import __version__
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
release = parse(__version__).release
|
|
38
|
+
except InvalidVersion:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
# packaging < 22 returns a LegacyVersion with `release = None` for
|
|
42
|
+
# non-PEP 440 versions instead of raising `InvalidVersion`.
|
|
43
|
+
if release is None:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
return Version.from_str(".".join(str(part) for part in release))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _warn_if_below_minver(metadata: Metadata, variant_path: Path) -> None:
|
|
50
|
+
"""Warn when the installed `kernels` library is older than the minimum
|
|
51
|
+
version required by a kernel.
|
|
52
|
+
"""
|
|
53
|
+
minver = _read_kernels_minver(variant_path)
|
|
54
|
+
if minver is None:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
installed = _installed_version()
|
|
58
|
+
if installed is not None and installed < minver:
|
|
59
|
+
# Report the verbatim installed version, not the normalized one used
|
|
60
|
+
# for comparison, so the message matches what `pip show` reports.
|
|
61
|
+
from kernels import __version__
|
|
62
|
+
|
|
63
|
+
warnings.warn(
|
|
64
|
+
f"Kernel '{metadata.name}' variant '{variant_path.name}' requires "
|
|
65
|
+
f"kernels>={minver}, but version {__version__} is installed. "
|
|
66
|
+
"The kernel may not load or work correctly; upgrade with: "
|
|
67
|
+
"pip install --upgrade kernels",
|
|
68
|
+
stacklevel=3,
|
|
69
|
+
)
|
|
@@ -24,6 +24,7 @@ from kernels.backends import _backend, _select_backend
|
|
|
24
24
|
from kernels.compat import has_torch, has_tvm_ffi
|
|
25
25
|
from kernels.deps import validate_dependencies
|
|
26
26
|
from kernels.lockfile import KernelLock, VariantLock
|
|
27
|
+
from kernels.minver import _warn_if_below_minver
|
|
27
28
|
from kernels.status import resolve_status
|
|
28
29
|
from kernels.variants import (
|
|
29
30
|
Decision,
|
|
@@ -210,6 +211,7 @@ def _import_from_path(variant_path: Path, repo_info: RepoInfo | None = None) ->
|
|
|
210
211
|
return loaded_kernel.module
|
|
211
212
|
|
|
212
213
|
metadata = Metadata.read_from_file(variant_path / "metadata.json")
|
|
214
|
+
_warn_if_below_minver(metadata, variant_path)
|
|
213
215
|
module_name = metadata.name.python_name
|
|
214
216
|
|
|
215
217
|
file_path = variant_path / "__init__.py"
|
|
@@ -10,6 +10,7 @@ src/kernels/benchmark.py
|
|
|
10
10
|
src/kernels/compat.py
|
|
11
11
|
src/kernels/deps.py
|
|
12
12
|
src/kernels/lockfile.py
|
|
13
|
+
src/kernels/minver.py
|
|
13
14
|
src/kernels/python_depends.json
|
|
14
15
|
src/kernels/status.py
|
|
15
16
|
src/kernels/utils.py
|
|
@@ -49,6 +50,7 @@ tests/test_interval_tree.py
|
|
|
49
50
|
tests/test_kernel_locking.py
|
|
50
51
|
tests/test_layer.py
|
|
51
52
|
tests/test_loaded_kernels.py
|
|
53
|
+
tests/test_minver.py
|
|
52
54
|
tests/test_status.py
|
|
53
55
|
tests/test_tvm_ffi.py
|
|
54
56
|
tests/test_user_agent.py
|
|
@@ -145,7 +145,8 @@ def test_get_kernel_rejects_unsupported_capability(monkeypatch):
|
|
|
145
145
|
if not metadata.backend.archs:
|
|
146
146
|
pytest.skip("kernel build does not declare archs")
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
# ReLU kernel supports PTX, so we need an old version.
|
|
149
|
+
monkeypatch.setattr(torch.cuda, "get_device_capability", lambda device=None: (1, 0))
|
|
149
150
|
|
|
150
151
|
with pytest.raises(RuntimeError, match="does not support the current device"):
|
|
151
152
|
get_kernel("kernels-community/relu", version=1)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from kernels_data import Metadata, Version
|
|
6
|
+
|
|
7
|
+
import kernels
|
|
8
|
+
from kernels.minver import _installed_version, _warn_if_below_minver
|
|
9
|
+
from kernels.utils import _import_from_path, _loaded_kernels
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _write_variant(tmp_path, minver):
|
|
13
|
+
variant_dir = tmp_path / "build" / "torch28-cxx11-cu128-x86_64-linux"
|
|
14
|
+
variant_dir.mkdir(parents=True)
|
|
15
|
+
metadata = {
|
|
16
|
+
"id": "activation_1_cuda",
|
|
17
|
+
"name": "activation",
|
|
18
|
+
"version": 1,
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"python-depends": ["torch"],
|
|
21
|
+
"backend": {"type": "cuda"},
|
|
22
|
+
}
|
|
23
|
+
if minver is not None:
|
|
24
|
+
metadata["kernels-minver"] = minver
|
|
25
|
+
(variant_dir / "metadata.json").write_text(json.dumps(metadata))
|
|
26
|
+
return variant_dir
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.mark.parametrize("minver", [None, "0.0.1"])
|
|
30
|
+
def test_no_warning_when_minver_met(tmp_path, recwarn, minver):
|
|
31
|
+
variant_dir = _write_variant(tmp_path, minver)
|
|
32
|
+
metadata = Metadata.read_from_file(variant_dir / "metadata.json")
|
|
33
|
+
_warn_if_below_minver(metadata, variant_dir)
|
|
34
|
+
assert len(recwarn) == 0
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_no_warning_for_dev_version_of_required_release(tmp_path, recwarn, monkeypatch):
|
|
38
|
+
# A development version implements the release it leads up to, so
|
|
39
|
+
# `0.17.0.dev0` must satisfy a `0.17.0` requirement.
|
|
40
|
+
monkeypatch.setattr(kernels, "__version__", "0.17.0.dev0")
|
|
41
|
+
variant_dir = _write_variant(tmp_path, "0.17.0")
|
|
42
|
+
metadata = Metadata.read_from_file(variant_dir / "metadata.json")
|
|
43
|
+
_warn_if_below_minver(metadata, variant_dir)
|
|
44
|
+
assert len(recwarn) == 0
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@pytest.mark.parametrize(
|
|
48
|
+
"installed",
|
|
49
|
+
["0.17.0.dev0", "0.17.0rc1", "0.17.0.post1", "0.17.0+cu121", "0.17"],
|
|
50
|
+
)
|
|
51
|
+
def test_installed_version_uses_release_segment(monkeypatch, installed):
|
|
52
|
+
monkeypatch.setattr(kernels, "__version__", installed)
|
|
53
|
+
assert _installed_version() == Version.from_str("0.17.0")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_installed_version_is_none_for_non_pep440_version(monkeypatch):
|
|
57
|
+
monkeypatch.setattr(kernels, "__version__", "0.17.0-dirty")
|
|
58
|
+
assert _installed_version() is None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_unparseable_installed_version_does_not_fail_load(tmp_path, recwarn, monkeypatch):
|
|
62
|
+
# A version that cannot be compared must not turn this advisory check into
|
|
63
|
+
# a hard failure.
|
|
64
|
+
monkeypatch.setattr(kernels, "__version__", "0.17.0-dirty")
|
|
65
|
+
variant_dir = _write_variant(tmp_path, "999.1.0")
|
|
66
|
+
metadata = Metadata.read_from_file(variant_dir / "metadata.json")
|
|
67
|
+
_warn_if_below_minver(metadata, variant_dir)
|
|
68
|
+
assert len(recwarn) == 0
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@pytest.mark.parametrize("minver", [42, "", "not-a-version"])
|
|
72
|
+
def test_invalid_minver_is_ignored(tmp_path, recwarn, minver):
|
|
73
|
+
# A `kernels-minver` that cannot be parsed (e.g. written by a future
|
|
74
|
+
# version that changed the format) must not fail the load.
|
|
75
|
+
variant_dir = _write_variant(tmp_path, minver)
|
|
76
|
+
metadata = Metadata.read_from_file(variant_dir / "metadata.json")
|
|
77
|
+
_warn_if_below_minver(metadata, variant_dir)
|
|
78
|
+
assert len(recwarn) == 0
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_version_ordering_is_numeric_not_lexicographic():
|
|
82
|
+
# `0.9 < 0.10` only holds for numeric comparison; string comparison would
|
|
83
|
+
# get this backwards.
|
|
84
|
+
assert Version.from_str("0.9") < Version.from_str("0.10")
|
|
85
|
+
assert Version.from_str("0.14") == Version.from_str("0.14.0")
|
|
86
|
+
assert Version.from_str("0.14.0") < Version.from_str("0.14.1")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_warns_when_minver_not_met(tmp_path):
|
|
90
|
+
variant_dir = _write_variant(tmp_path, "999.1.0")
|
|
91
|
+
metadata = Metadata.read_from_file(variant_dir / "metadata.json")
|
|
92
|
+
with pytest.warns(UserWarning, match="requires kernels>=999.1"):
|
|
93
|
+
_warn_if_below_minver(metadata, variant_dir)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_warning_mentions_installed_version(tmp_path):
|
|
97
|
+
variant_dir = _write_variant(tmp_path, "999.1.0")
|
|
98
|
+
metadata = Metadata.read_from_file(variant_dir / "metadata.json")
|
|
99
|
+
with pytest.warns(UserWarning, match=f"version {re.escape(kernels.__version__)} is installed"):
|
|
100
|
+
_warn_if_below_minver(metadata, variant_dir)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_import_from_path_warns_on_unmet_minver(tmp_path):
|
|
104
|
+
variant_dir = _write_variant(tmp_path, "999.1.0")
|
|
105
|
+
(variant_dir / "__init__.py").write_text("value = 42\n")
|
|
106
|
+
_loaded_kernels.pop(variant_dir, None)
|
|
107
|
+
try:
|
|
108
|
+
with pytest.warns(UserWarning, match="requires kernels>=999.1"):
|
|
109
|
+
module = _import_from_path(variant_dir)
|
|
110
|
+
assert module.value == 42
|
|
111
|
+
finally:
|
|
112
|
+
_loaded_kernels.pop(variant_dir, None)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|