laco-torch 1.0.0__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.
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: laco-torch
3
+ Version: 1.0.0
4
+ Summary: PyTorch optimizer and scheduler configurables for laco.
5
+ Author-email: Kurt Stolle <kurt@khws.io>
6
+ Requires-Python: >=3.13
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: laco>=1.0.0
9
+ Requires-Dist: torch>=2.0
10
+
11
+ # Laco-Torch
12
+
13
+ PyTorch optimizer and scheduler configurables for laco.
14
+
15
+ Part of the [laco](https://github.com/khwstolle/laco) project — see the [root README](../../README.md) for an overview.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install laco-torch
21
+ ```
22
+
23
+ ## Features
24
+
25
+ Auto-registers all `torch.optim` and `lr_scheduler` classes as `@L.configurable`; `register()`, `registered_names()`
26
+
27
+ ## Usage
28
+
29
+ See [`docs/index.md`](docs/index.md) for the full guide.
@@ -0,0 +1,19 @@
1
+ # Laco-Torch
2
+
3
+ PyTorch optimizer and scheduler configurables for laco.
4
+
5
+ Part of the [laco](https://github.com/khwstolle/laco) project — see the [root README](../../README.md) for an overview.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install laco-torch
11
+ ```
12
+
13
+ ## Features
14
+
15
+ Auto-registers all `torch.optim` and `lr_scheduler` classes as `@L.configurable`; `register()`, `registered_names()`
16
+
17
+ ## Usage
18
+
19
+ See [`docs/index.md`](docs/index.md) for the full guide.
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=75", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "laco-torch"
7
+ version = "1.0.0"
8
+ description = "PyTorch optimizer and scheduler configurables for laco."
9
+ readme = "README.md"
10
+ requires-python = ">=3.13"
11
+ authors = [{ name = "Kurt Stolle", email = "kurt@khws.io" }]
12
+ dependencies = ["laco>=1.0.0", "torch>=2.0"]
13
+
14
+ [project.entry-points."laco.plugins"]
15
+ torch = "laco.integrations.torch:_bootstrap"
16
+
17
+ [tool.setuptools.packages.find]
18
+ where = ["sources"]
19
+ namespaces = true
20
+
21
+ [tool.uv.sources]
22
+ laco = { workspace = true }
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,33 @@
1
+ """PyTorch optimizer and scheduler configurables for laco.
2
+
3
+ Importing this module registers all ``torch.optim`` optimizers and
4
+ ``torch.optim.lr_scheduler`` schedulers as ``@L.configurable`` so they
5
+ can be used inside ``L.trace()`` and composed as laco config nodes.
6
+
7
+ Examples
8
+ --------
9
+ ::
10
+
11
+ import laco.language as L
12
+ import laco.integrations.torch # registers configurables
13
+
14
+ # Record a config without constructing anything:
15
+ cfg = L.trace(lambda: torch.optim.AdamW(lr=1e-3, weight_decay=0.01))
16
+
17
+ # Instantiate later with model parameters:
18
+ optimizer = laco.instantiate(cfg, params=model.parameters())
19
+
20
+ # Schedulers work the same way:
21
+ sched_cfg = L.trace(lambda: torch.optim.lr_scheduler.CosineAnnealingLR(T_max=100))
22
+ scheduler = laco.instantiate(sched_cfg, optimizer=optimizer)
23
+
24
+ All public optimizer and scheduler classes found in those namespaces at
25
+ import time are registered. Third-party optimizers can be registered
26
+ manually via :func:`register`.
27
+ """
28
+
29
+ from laco.integrations.torch._core import _bootstrap as _bootstrap
30
+ from laco.integrations.torch._core import register as register
31
+ from laco.integrations.torch._core import registered_names as registered_names
32
+
33
+ __all__ = ["_bootstrap", "register", "registered_names"]
@@ -0,0 +1,81 @@
1
+ """Implementation for laco-torch."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typing
6
+
7
+ _REGISTRY: dict[str, type] = {}
8
+
9
+
10
+ def register(cls: type) -> type:
11
+ """Register *cls* as an ``@L.configurable`` target.
12
+
13
+ Called automatically for all ``torch.optim`` and
14
+ ``torch.optim.lr_scheduler`` classes when ``laco.integrations.torch`` is
15
+ imported. Call it manually to register third-party optimizer classes.
16
+
17
+ Parameters
18
+ ----------
19
+ cls : type
20
+ A class to make traceable via ``L.trace()``.
21
+
22
+ Returns
23
+ -------
24
+ type
25
+ The class unchanged (usable as a decorator).
26
+ """
27
+ from laco.language import configurable
28
+
29
+ wrapped = configurable(cls)
30
+ _REGISTRY[f"{cls.__module__}.{cls.__qualname__}"] = wrapped
31
+ # Patch the class into its own module so existing references pick it up.
32
+ module = typing.cast(
33
+ typing.Any, __import__(cls.__module__, fromlist=[cls.__qualname__])
34
+ )
35
+ setattr(module, cls.__qualname__, wrapped)
36
+ return wrapped
37
+
38
+
39
+ def registered_names() -> list[str]:
40
+ """Return the sorted fully-qualified names of all registered configurables.
41
+
42
+ Returns
43
+ -------
44
+ list[str]
45
+ Sorted list of ``"module.ClassName"`` strings.
46
+ """
47
+ return sorted(_REGISTRY)
48
+
49
+
50
+ def _register_namespace(module: typing.Any) -> None:
51
+ import inspect
52
+
53
+ for name, obj in inspect.getmembers(module, inspect.isclass):
54
+ if name.startswith("_"):
55
+ continue
56
+ if obj.__module__ is None or not obj.__module__.startswith(module.__name__):
57
+ # Skip re-exports from other packages (e.g. numpy classes).
58
+ continue
59
+ try:
60
+ register(obj)
61
+ except Exception: # noqa: BLE001
62
+ pass
63
+
64
+
65
+ def _bootstrap() -> None:
66
+ """Register all ``torch.optim`` and ``lr_scheduler`` classes.
67
+
68
+ Called automatically via the ``laco.plugins`` entry point when
69
+ ``laco-torch`` is installed. Silently does nothing if ``torch`` is not
70
+ importable.
71
+ """
72
+ try:
73
+ import torch.optim as _optim
74
+ import torch.optim.lr_scheduler as _sched
75
+ except ImportError:
76
+ return
77
+ _register_namespace(_optim)
78
+ _register_namespace(_sched)
79
+
80
+
81
+ _bootstrap()
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: laco-torch
3
+ Version: 1.0.0
4
+ Summary: PyTorch optimizer and scheduler configurables for laco.
5
+ Author-email: Kurt Stolle <kurt@khws.io>
6
+ Requires-Python: >=3.13
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: laco>=1.0.0
9
+ Requires-Dist: torch>=2.0
10
+
11
+ # Laco-Torch
12
+
13
+ PyTorch optimizer and scheduler configurables for laco.
14
+
15
+ Part of the [laco](https://github.com/khwstolle/laco) project — see the [root README](../../README.md) for an overview.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install laco-torch
21
+ ```
22
+
23
+ ## Features
24
+
25
+ Auto-registers all `torch.optim` and `lr_scheduler` classes as `@L.configurable`; `register()`, `registered_names()`
26
+
27
+ ## Usage
28
+
29
+ See [`docs/index.md`](docs/index.md) for the full guide.
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ sources/laco/integrations/torch/__init__.py
4
+ sources/laco/integrations/torch/_core.py
5
+ sources/laco_torch.egg-info/PKG-INFO
6
+ sources/laco_torch.egg-info/SOURCES.txt
7
+ sources/laco_torch.egg-info/dependency_links.txt
8
+ sources/laco_torch.egg-info/entry_points.txt
9
+ sources/laco_torch.egg-info/requires.txt
10
+ sources/laco_torch.egg-info/top_level.txt
11
+ tests/test_laco_torch.py
@@ -0,0 +1,2 @@
1
+ [laco.plugins]
2
+ torch = laco.integrations.torch:_bootstrap
@@ -0,0 +1,2 @@
1
+ laco>=1.0.0
2
+ torch>=2.0
@@ -0,0 +1,72 @@
1
+ """Tests for laco-torch."""
2
+
3
+ import pytest
4
+
5
+
6
+ def test_import():
7
+ import laco.integrations.torch # noqa: F401
8
+
9
+
10
+ def test_public_api():
11
+ import laco.integrations.torch as laco_torch
12
+
13
+ assert hasattr(laco_torch, "register")
14
+ assert hasattr(laco_torch, "registered_names")
15
+ assert hasattr(laco_torch, "_bootstrap")
16
+
17
+
18
+ def test_registered_names_returns_sorted_list():
19
+ import laco.integrations.torch as laco_torch
20
+
21
+ names = laco_torch.registered_names()
22
+
23
+ assert isinstance(names, list)
24
+ assert names == sorted(names)
25
+
26
+
27
+ def test_registered_names_contains_torch_optimizers():
28
+ pytest.importorskip("torch")
29
+
30
+ import laco.integrations.torch as laco_torch
31
+
32
+ names = laco_torch.registered_names()
33
+
34
+ assert any("Adam" in n for n in names), (
35
+ f"Expected Adam in registered names, got: {names[:5]}"
36
+ )
37
+ assert any("SGD" in n for n in names), (
38
+ f"Expected SGD in registered names, got: {names[:5]}"
39
+ )
40
+
41
+
42
+ def test_register_is_callable():
43
+ import laco.integrations.torch as laco_torch
44
+
45
+ assert callable(laco_torch.register)
46
+
47
+
48
+ def test_register_custom_class():
49
+ pytest.importorskip("torch")
50
+
51
+ import laco.integrations.torch as laco_torch
52
+ from laco.integrations.torch._core import _REGISTRY
53
+
54
+ class _FakeOptimizer:
55
+ __module__ = "laco.integrations.torch"
56
+ __qualname__ = "_FakeOptimizer"
57
+
58
+ before = set(_REGISTRY.keys())
59
+ laco_torch.register(_FakeOptimizer)
60
+ after = set(_REGISTRY.keys())
61
+
62
+ assert after - before == {"laco.integrations.torch._FakeOptimizer"}
63
+
64
+
65
+ def test_bootstrap_is_idempotent():
66
+ import laco.integrations.torch as laco_torch
67
+
68
+ names_before = set(laco_torch.registered_names())
69
+ laco_torch._bootstrap()
70
+ names_after = set(laco_torch.registered_names())
71
+
72
+ assert names_after >= names_before