sig-rust 0.1.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,28 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ groups:
8
+ actions:
9
+ patterns: ["*"]
10
+ open-pull-requests-limit: 5
11
+
12
+ - package-ecosystem: cargo
13
+ directory: /
14
+ schedule:
15
+ interval: weekly
16
+ groups:
17
+ rust-deps:
18
+ patterns: ["*"]
19
+ open-pull-requests-limit: 5
20
+
21
+ - package-ecosystem: pip
22
+ directory: /
23
+ schedule:
24
+ interval: weekly
25
+ groups:
26
+ python-deps:
27
+ patterns: ["*"]
28
+ open-pull-requests-limit: 5
@@ -0,0 +1,213 @@
1
+ name: CICD
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ rust:
13
+ name: Rust (${{ matrix.toolchain }})
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ toolchain: [stable, nightly]
19
+ steps:
20
+ - name: Checkout
21
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
22
+ with:
23
+ persist-credentials: false
24
+
25
+ - name: Install Rust toolchain
26
+ run: |
27
+ rustup toolchain install ${{ matrix.toolchain }} --profile minimal \
28
+ --component clippy,rustfmt,llvm-tools-preview
29
+ rustup default ${{ matrix.toolchain }}
30
+
31
+ - name: Cache cargo
32
+ uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
33
+
34
+ - name: Install cargo-llvm-cov
35
+ uses: taiki-e/install-action@80e6af7a2ec7f280fffe2d0a9d3a12a9d11d86e9 # v2.75.1
36
+ with:
37
+ tool: cargo-llvm-cov
38
+
39
+ - name: Format check
40
+ run: cargo fmt --check
41
+
42
+ - name: Clippy
43
+ run: cargo clippy --all-targets --all-features -- -D warnings
44
+
45
+ - name: Test with coverage
46
+ if: matrix.toolchain == 'stable'
47
+ run: cargo llvm-cov --lcov --output-path rust-lcov.info --ignore-filename-regex python
48
+
49
+ - name: Test (nightly)
50
+ if: matrix.toolchain == 'nightly'
51
+ run: cargo test
52
+
53
+ - name: Upload Rust coverage
54
+ if: matrix.toolchain == 'stable'
55
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
56
+ with:
57
+ name: rust-coverage
58
+ path: rust-lcov.info
59
+
60
+ python:
61
+ name: Python ${{ matrix.python-version }}
62
+ runs-on: ubuntu-latest
63
+ strategy:
64
+ fail-fast: false
65
+ matrix:
66
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
67
+ steps:
68
+ - name: Checkout
69
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
70
+ with:
71
+ persist-credentials: false
72
+
73
+ - name: Install Rust toolchain
74
+ run: rustup toolchain install stable --profile minimal
75
+
76
+ - name: Cache cargo
77
+ uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
78
+
79
+ - name: Install uv
80
+ uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
81
+ with:
82
+ python-version: ${{ matrix.python-version }}
83
+ enable-cache: true
84
+ cache-dependency-glob: |
85
+ **/pyproject.toml
86
+ **/uv.lock
87
+
88
+ - name: Install dependencies
89
+ run: uv sync --all-extras --group dev --group test
90
+
91
+ - name: Lint
92
+ run: uv run ruff check .
93
+
94
+ - name: Format check
95
+ run: uv run ruff format --check .
96
+
97
+ - name: Build extension
98
+ run: uv run maturin develop --release
99
+
100
+ - name: Type check
101
+ run: uv run ty check
102
+
103
+ - name: Run tests with coverage
104
+ run: uv run pytest -v --cov=python/sig_rust --cov-report=term-missing --cov-report=xml:python-coverage.xml
105
+
106
+ - name: Upload Python coverage
107
+ if: matrix.python-version == '3.14'
108
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
109
+ with:
110
+ name: python-coverage
111
+ path: python-coverage.xml
112
+
113
+ combined-coverage:
114
+ name: Combined coverage
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - name: Checkout
118
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
119
+ with:
120
+ persist-credentials: false
121
+
122
+ - name: Install Rust toolchain
123
+ run: |
124
+ rustup toolchain install stable --profile minimal \
125
+ --component llvm-tools-preview
126
+ rustup default stable
127
+
128
+ - name: Cache cargo
129
+ uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
130
+
131
+ - name: Install cargo-llvm-cov
132
+ uses: taiki-e/install-action@80e6af7a2ec7f280fffe2d0a9d3a12a9d11d86e9 # v2.75.1
133
+ with:
134
+ tool: cargo-llvm-cov
135
+
136
+ - name: Install uv
137
+ uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
138
+ with:
139
+ python-version: "3.14"
140
+ enable-cache: true
141
+ cache-dependency-glob: |
142
+ **/pyproject.toml
143
+ **/uv.lock
144
+
145
+ - name: Install dependencies
146
+ run: uv sync --all-extras --group dev --group test
147
+
148
+ - name: Instrument and run tests
149
+ run: |
150
+ eval "$(cargo llvm-cov show-env --export-prefix)"
151
+ export CARGO_TARGET_DIR="$CARGO_LLVM_COV_TARGET_DIR"
152
+ cargo llvm-cov clean --workspace
153
+ cargo test
154
+ uv run maturin develop
155
+ uv run pytest --cov=python/sig_rust --cov-report=xml:python-coverage.xml
156
+ cargo llvm-cov report --lcov --output-path combined-lcov.info
157
+
158
+ - name: Upload combined coverage
159
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
160
+ with:
161
+ name: combined-coverage
162
+ path: |
163
+ combined-lcov.info
164
+ python-coverage.xml
165
+
166
+ coverage:
167
+ name: Upload coverage
168
+ needs: [rust, python, combined-coverage]
169
+ runs-on: ubuntu-latest
170
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
171
+ environment: codecov
172
+ permissions:
173
+ contents: read
174
+ id-token: write
175
+ steps:
176
+ - name: Checkout
177
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
178
+ with:
179
+ persist-credentials: false
180
+
181
+ - name: Download Rust coverage
182
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
183
+ with:
184
+ name: rust-coverage
185
+
186
+ - name: Download combined coverage
187
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
188
+ with:
189
+ name: combined-coverage
190
+
191
+ - name: Upload Rust-only coverage to Codecov
192
+ uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
193
+ with:
194
+ token: ${{ secrets.CODECOV_TOKEN }}
195
+ files: rust-lcov.info
196
+ flags: rust
197
+ fail_ci_if_error: true
198
+
199
+ - name: Upload Python coverage to Codecov
200
+ uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
201
+ with:
202
+ token: ${{ secrets.CODECOV_TOKEN }}
203
+ files: python-coverage.xml
204
+ flags: python
205
+ fail_ci_if_error: true
206
+
207
+ - name: Upload combined coverage to Codecov
208
+ uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
209
+ with:
210
+ token: ${{ secrets.CODECOV_TOKEN }}
211
+ files: combined-lcov.info
212
+ flags: combined
213
+ fail_ci_if_error: true
@@ -0,0 +1,88 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ sdist:
12
+ name: Build sdist
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
17
+ with:
18
+ persist-credentials: false
19
+
20
+ - name: Build sdist
21
+ uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1.50.1
22
+ with:
23
+ command: sdist
24
+ args: --out dist
25
+
26
+ - name: Upload sdist
27
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
28
+ with:
29
+ name: dist-sdist
30
+ path: dist/*.tar.gz
31
+
32
+ wheels:
33
+ name: Build wheels (${{ matrix.target }} / ${{ matrix.os }})
34
+ runs-on: ${{ matrix.os }}
35
+ strategy:
36
+ fail-fast: false
37
+ matrix:
38
+ include:
39
+ - os: ubuntu-latest
40
+ target: x86_64
41
+ - os: ubuntu-latest
42
+ target: aarch64
43
+ - os: macos-latest
44
+ target: x86_64
45
+ - os: macos-latest
46
+ target: aarch64
47
+ - os: windows-latest
48
+ target: x86_64
49
+ steps:
50
+ - name: Checkout
51
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
52
+ with:
53
+ persist-credentials: false
54
+
55
+ - name: Build wheels
56
+ uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1.50.1
57
+ with:
58
+ target: ${{ matrix.target }}
59
+ args: --release --out dist --find-interpreter
60
+ manylinux: auto
61
+
62
+ - name: Upload wheels
63
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
64
+ with:
65
+ name: dist-${{ matrix.os }}-${{ matrix.target }}
66
+ path: dist/*.whl
67
+
68
+ publish:
69
+ name: Publish
70
+ needs: [sdist, wheels]
71
+ runs-on: ubuntu-latest
72
+ environment: pypi
73
+ permissions:
74
+ id-token: write
75
+ contents: read
76
+ steps:
77
+ - name: Download all artifacts
78
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
79
+ with:
80
+ pattern: dist-*
81
+ merge-multiple: true
82
+ path: dist
83
+
84
+ - name: Install uv
85
+ uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
86
+
87
+ - name: Publish to PyPI
88
+ run: uv publish dist/*
@@ -0,0 +1,81 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+ .python-version
29
+
30
+ # Unit test / coverage reports
31
+ htmlcov/
32
+ .tox/
33
+ .nox/
34
+ .coverage
35
+ .coverage.*
36
+ .cache
37
+ nosetests.xml
38
+ coverage.xml
39
+ *.cover
40
+ *.py.cover
41
+ .hypothesis/
42
+ .pytest_cache/
43
+ cover/
44
+
45
+ # Environments
46
+ .env
47
+ .envrc
48
+ .venv
49
+ env/
50
+ venv/
51
+ ENV/
52
+
53
+ # Ruff
54
+ .ruff_cache/
55
+
56
+ # mypy / type checkers
57
+ .mypy_cache/
58
+ .dmypy.json
59
+ dmypy.json
60
+ .pyre/
61
+ .pytype/
62
+
63
+ # Rust
64
+ /target
65
+ **/*.rs.bk
66
+ .cargo/
67
+
68
+ # IDE
69
+ .idea/
70
+ .vscode/
71
+ *.swp
72
+ *.swo
73
+ *~
74
+
75
+ # OS
76
+ .DS_Store
77
+ Thumbs.db
78
+
79
+ # PyPI
80
+ .pypirc
81
+
@@ -0,0 +1,73 @@
1
+ # sig-rust
2
+
3
+ Rust port of sig-light: path signature and log signature computation with PyO3 bindings.
4
+
5
+ ## Build Commands
6
+
7
+ Requires [just](https://github.com/casey/just) for task running.
8
+
9
+ ```bash
10
+ just sync # Install all dependencies
11
+ just build # Build native extension (maturin develop --release)
12
+ just check # Run all checks (Rust + Python)
13
+ just rust-check # Rust only: fmt, clippy, test
14
+ just python-check # Python only: ruff, ty, pytest
15
+ just format-all # Auto-format everything
16
+ just test-cov-all # Full coverage (Rust + Python)
17
+ just bench # Quick benchmark vs iisignature
18
+ just bench-full # Full profiling suite
19
+ ```
20
+
21
+ Individual commands:
22
+
23
+ ```bash
24
+ just rust-test # cargo test
25
+ just rust-lint # cargo clippy
26
+ just rust-fmt-check # cargo fmt --check
27
+ just rust-fmt # cargo fmt
28
+ just rust-test-cov # cargo llvm-cov
29
+
30
+ just build # maturin develop --release
31
+ just test # pytest
32
+ just lint # ruff check
33
+ just format-check # ruff format --check
34
+ just format # ruff format
35
+ just typecheck # ty check
36
+ just test-cov # pytest --cov
37
+ ```
38
+
39
+ ## Architecture
40
+
41
+ - `src/lib.rs` -- crate root, module declarations
42
+ - `src/error.rs` -- `SigError` enum (thiserror)
43
+ - `src/types.rs` -- `Dim`, `Depth`, `LevelList`, `BatchedLevelList` newtypes
44
+ - `src/algebra.rs` -- tensor algebra: multiply, unconcatenate, log, segment signatures, adjoints
45
+ - `src/lyndon.rs` -- Lyndon words, factorization, projection matrices (SVD)
46
+ - `src/signature.rs` -- `sig()`, `siglength()`, `sigcombine()`, binary tree reduction
47
+ - `src/logsignature.rs` -- `logsig()`, `prepare()`, `logsiglength()`, BCH heuristic
48
+ - `src/bch.rs` -- Baker-Campbell-Hausdorff compiled program: precomputes bracket structure constants and emits flat FMA instructions for fast log-signature evaluation
49
+ - `src/backprop.rs` -- `sigbackprop()`, `sigjacobian()`, `logsigbackprop()`, reversibility trick
50
+ - `src/rotational.rs` -- 2D rotation-invariant features
51
+ - `src/transforms.rs` -- `sigjoin()`, `sigscale()` + backprop
52
+ - `src/python.rs` -- PyO3 bindings with adaptive rayon parallelism
53
+
54
+ ## Key Design Decisions
55
+
56
+ - `LevelList`: flat `Vec<f64>` with offset-based level access for cache locality. All tensor algebra operates on this type.
57
+ - Reversibility trick in backprop: recovers prefix signatures via `tensor_unconcatenate_into` instead of storing all intermediates (O(siglength) vs O(n * siglength) memory).
58
+ - BCH vs S method: `logsignature.rs` selects BCH for small configs (d<=3, m<=4) where compiled FMA wins; S method (Horner tensor log) for larger configs.
59
+ - Rayon parallelism: `collect_par_or_seq` in `python.rs` uses a work-estimation heuristic (500K threshold, min 16 batch items) to avoid thread pool overhead on small batches.
60
+ - Release profile: fat LTO + single codegen unit for maximum optimization.
61
+
62
+ ## CI/CD
63
+
64
+ - **CI** (`.github/workflows/cicd.yml`): Rust stable+nightly (fmt, clippy, test+coverage), Python 3.10-3.14 (ruff, ty, pytest+coverage). Coverage uploaded to Codecov with `rust` and `python` flags.
65
+ - **Publish** (`.github/workflows/publish.yml`): On GitHub release, builds wheels for Linux/macOS/Windows (x86_64 + aarch64) via maturin-action, publishes to PyPI.
66
+ - **Dependabot**: Weekly grouped updates for GitHub Actions, Cargo, and pip.
67
+ - Codecov token lives in the `codecov` GitHub environment. PyPI uses trusted publishing via the `pypi` environment.
68
+
69
+ ## Testing
70
+
71
+ - Rust tests: `#[cfg(test)]` modules in `bch.rs` (bracket identities, BCH/S-method agreement, backprop agreement).
72
+ - Python tests: `python/tests/test_python_bindings.py` (105 tests) covering all public API functions, finite-difference gradient checks, and iisignature cross-validation.
73
+ - iisignature compatibility tests run when `iisignature` is installed (included in the `test` dependency group).