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.
- laco_torch-1.0.0/PKG-INFO +29 -0
- laco_torch-1.0.0/README.md +19 -0
- laco_torch-1.0.0/pyproject.toml +22 -0
- laco_torch-1.0.0/setup.cfg +4 -0
- laco_torch-1.0.0/sources/laco/integrations/torch/__init__.py +33 -0
- laco_torch-1.0.0/sources/laco/integrations/torch/_core.py +81 -0
- laco_torch-1.0.0/sources/laco_torch.egg-info/PKG-INFO +29 -0
- laco_torch-1.0.0/sources/laco_torch.egg-info/SOURCES.txt +11 -0
- laco_torch-1.0.0/sources/laco_torch.egg-info/dependency_links.txt +1 -0
- laco_torch-1.0.0/sources/laco_torch.egg-info/entry_points.txt +2 -0
- laco_torch-1.0.0/sources/laco_torch.egg-info/requires.txt +2 -0
- laco_torch-1.0.0/sources/laco_torch.egg-info/top_level.txt +1 -0
- laco_torch-1.0.0/tests/test_laco_torch.py +72 -0
|
@@ -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,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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
laco
|
|
@@ -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
|