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.
Files changed (60) hide show
  1. {kernels-0.16.1 → kernels-0.16.2}/PKG-INFO +1 -1
  2. {kernels-0.16.1 → kernels-0.16.2}/pyproject.toml +1 -1
  3. kernels-0.16.2/src/kernels/minver.py +69 -0
  4. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/utils.py +2 -0
  5. {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/PKG-INFO +1 -1
  6. {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/SOURCES.txt +2 -0
  7. {kernels-0.16.1 → kernels-0.16.2}/tests/test_archs.py +2 -1
  8. kernels-0.16.2/tests/test_minver.py +112 -0
  9. {kernels-0.16.1 → kernels-0.16.2}/README.md +0 -0
  10. {kernels-0.16.1 → kernels-0.16.2}/setup.cfg +0 -0
  11. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/__init__.py +0 -0
  12. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/_system.py +0 -0
  13. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/_versions.py +0 -0
  14. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/_windows.py +0 -0
  15. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/archs.py +0 -0
  16. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/backends.py +0 -0
  17. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmark.py +0 -0
  18. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/__init__.py +0 -0
  19. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/activation.py +0 -0
  20. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/attention.py +0 -0
  21. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/benchmarks/layer_norm.py +0 -0
  22. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/__init__.py +0 -0
  23. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/benchmark.py +0 -0
  24. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/benchmark_graphics.py +0 -0
  25. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/verify_signature.py +0 -0
  26. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/cli/versions.py +0 -0
  27. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/compat.py +0 -0
  28. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/deps.py +0 -0
  29. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/__init__.py +0 -0
  30. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/_interval_tree.py +0 -0
  31. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/device.py +0 -0
  32. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/func.py +0 -0
  33. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/globals.py +0 -0
  34. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/kernelize.py +0 -0
  35. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/layer.py +0 -0
  36. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/mode.py +0 -0
  37. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/layer/repos.py +0 -0
  38. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/lockfile.py +0 -0
  39. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/python_depends.json +0 -0
  40. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/status.py +0 -0
  41. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/variants.py +0 -0
  42. {kernels-0.16.1 → kernels-0.16.2}/src/kernels/verify.py +0 -0
  43. {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/dependency_links.txt +0 -0
  44. {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/entry_points.txt +0 -0
  45. {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/requires.txt +0 -0
  46. {kernels-0.16.1 → kernels-0.16.2}/src/kernels.egg-info/top_level.txt +0 -0
  47. {kernels-0.16.1 → kernels-0.16.2}/tests/test_basic.py +0 -0
  48. {kernels-0.16.1 → kernels-0.16.2}/tests/test_benchmarks.py +0 -0
  49. {kernels-0.16.1 → kernels-0.16.2}/tests/test_deps.py +0 -0
  50. {kernels-0.16.1 → kernels-0.16.2}/tests/test_doctest.py +0 -0
  51. {kernels-0.16.1 → kernels-0.16.2}/tests/test_func.py +0 -0
  52. {kernels-0.16.1 → kernels-0.16.2}/tests/test_interval_tree.py +0 -0
  53. {kernels-0.16.1 → kernels-0.16.2}/tests/test_kernel_locking.py +0 -0
  54. {kernels-0.16.1 → kernels-0.16.2}/tests/test_layer.py +0 -0
  55. {kernels-0.16.1 → kernels-0.16.2}/tests/test_loaded_kernels.py +0 -0
  56. {kernels-0.16.1 → kernels-0.16.2}/tests/test_status.py +0 -0
  57. {kernels-0.16.1 → kernels-0.16.2}/tests/test_tvm_ffi.py +0 -0
  58. {kernels-0.16.1 → kernels-0.16.2}/tests/test_user_agent.py +0 -0
  59. {kernels-0.16.1 → kernels-0.16.2}/tests/test_variants.py +0 -0
  60. {kernels-0.16.1 → kernels-0.16.2}/tests/test_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kernels
3
- Version: 0.16.1
3
+ Version: 0.16.2
4
4
  Summary: Download compute kernels
5
5
  Author-email: Daniel de Kok <daniel@huggingface.co>, David Holtz <david@huggingface.co>
6
6
  License: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kernels"
3
- version = "0.16.1"
3
+ version = "0.16.2"
4
4
  description = "Download compute kernels"
5
5
  authors = [
6
6
  { name = "Daniel de Kok", email = "daniel@huggingface.co" },
@@ -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"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kernels
3
- Version: 0.16.1
3
+ Version: 0.16.2
4
4
  Summary: Download compute kernels
5
5
  Author-email: Daniel de Kok <daniel@huggingface.co>, David Holtz <david@huggingface.co>
6
6
  License: Apache-2.0
@@ -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
- monkeypatch.setattr(torch.cuda, "get_device_capability", lambda device=None: (99, 9))
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