puggles 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.
- puggles-0.1.0/.github/workflows/ci.yml +73 -0
- puggles-0.1.0/.github/workflows/release.yml +148 -0
- puggles-0.1.0/.gitignore +27 -0
- puggles-0.1.0/Cargo.lock +1193 -0
- puggles-0.1.0/Cargo.toml +40 -0
- puggles-0.1.0/GUIDE.md +451 -0
- puggles-0.1.0/LICENSE-APACHE +202 -0
- puggles-0.1.0/LICENSE-MIT +25 -0
- puggles-0.1.0/PKG-INFO +139 -0
- puggles-0.1.0/README.md +173 -0
- puggles-0.1.0/pyproject.toml +35 -0
- puggles-0.1.0/python/Cargo.lock +1354 -0
- puggles-0.1.0/python/Cargo.toml +25 -0
- puggles-0.1.0/python/README.md +116 -0
- puggles-0.1.0/python/puggles.pyi +162 -0
- puggles-0.1.0/python/src/lib.rs +49 -0
- puggles-0.1.0/python/src/py_benchmarks.rs +128 -0
- puggles-0.1.0/python/src/py_gpu.rs +151 -0
- puggles-0.1.0/python/src/py_nsga3.rs +128 -0
- puggles-0.1.0/python/src/py_nsgaii.rs +362 -0
- puggles-0.1.0/python/src/py_operators.rs +135 -0
- puggles-0.1.0/python/src/py_problem.rs +291 -0
- puggles-0.1.0/python/src/py_solution.rs +43 -0
- puggles-0.1.0/python/src/py_types.rs +92 -0
- puggles-0.1.0/src/benchmark_objective_functions.rs +236 -0
- puggles-0.1.0/src/checkpoint.rs +61 -0
- puggles-0.1.0/src/core.rs +463 -0
- puggles-0.1.0/src/dominance.rs +676 -0
- puggles-0.1.0/src/gatypes.rs +144 -0
- puggles-0.1.0/src/genetic_algorithms_v2.rs +844 -0
- puggles-0.1.0/src/genetic_operators/crossover.rs +632 -0
- puggles-0.1.0/src/genetic_operators/mod.rs +3 -0
- puggles-0.1.0/src/genetic_operators/mutation.rs +409 -0
- puggles-0.1.0/src/genetic_operators/selectors.rs +82 -0
- puggles-0.1.0/src/gpu_evaluator.rs +301 -0
- puggles-0.1.0/src/lib.rs +14 -0
- puggles-0.1.0/src/metrics.rs +120 -0
- puggles-0.1.0/src/nsga3.rs +375 -0
- puggles-0.1.0/tests/encodings_and_constraints.rs +234 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, python-library]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_call: # so release.yml can gate publishing on a green run
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: test (${{ matrix.os }})
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
23
|
+
with:
|
|
24
|
+
components: clippy, rustfmt
|
|
25
|
+
- uses: Swatinem/rust-cache@v2
|
|
26
|
+
- name: Build
|
|
27
|
+
run: cargo build --all-targets
|
|
28
|
+
- name: Test
|
|
29
|
+
run: cargo test --all-targets
|
|
30
|
+
# The GPU feature is compile-checked only: CI runners have no usable adapter.
|
|
31
|
+
- name: Check GPU feature
|
|
32
|
+
run: cargo check --features gpu --all-targets
|
|
33
|
+
- name: Clippy
|
|
34
|
+
run: cargo clippy --all-targets
|
|
35
|
+
|
|
36
|
+
python:
|
|
37
|
+
name: python bindings
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
- uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.12"
|
|
44
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
45
|
+
- uses: Swatinem/rust-cache@v2
|
|
46
|
+
- name: Build and install
|
|
47
|
+
run: pip install maturin && maturin build --release --manifest-path python/Cargo.toml --out dist && pip install --find-links dist puggles
|
|
48
|
+
- name: Smoke test
|
|
49
|
+
run: |
|
|
50
|
+
python - <<'SMOKE'
|
|
51
|
+
import puggles as pg
|
|
52
|
+
|
|
53
|
+
problem = pg.Problem(
|
|
54
|
+
solution_length=10,
|
|
55
|
+
number_of_objectives=2,
|
|
56
|
+
solution_data_types=[pg.Real(0.0, 1.0)] * 10,
|
|
57
|
+
objective_function=lambda x: [x[0], 1.0 - x[0]],
|
|
58
|
+
direction=[-1, -1],
|
|
59
|
+
)
|
|
60
|
+
def front(**kw):
|
|
61
|
+
ga = pg.NSGAII(problem, population_size=50, execution_mode="sequential", **kw)
|
|
62
|
+
ga.run(2000)
|
|
63
|
+
return [tuple(s.objectives) for s in ga.get_archive()]
|
|
64
|
+
|
|
65
|
+
assert front(), "empty archive"
|
|
66
|
+
|
|
67
|
+
# Seeding must reproduce a run exactly, and must not silently pin unseeded runs.
|
|
68
|
+
assert front(seed=1) == front(seed=1), "seeded runs are not reproducible"
|
|
69
|
+
assert front(seed=1) != front(seed=2), "different seeds gave identical runs"
|
|
70
|
+
assert front() != front(), "unseeded runs are deterministic — seed leaked in"
|
|
71
|
+
|
|
72
|
+
print("ok", len(front(seed=1)), "solutions; seeding verified")
|
|
73
|
+
SMOKE
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Two ways to publish:
|
|
2
|
+
#
|
|
3
|
+
# Staged (use this for a first release) — Actions > Release > Run workflow, and pick a target:
|
|
4
|
+
# testpypi rehearsal upload to test.pypi.org; nothing on real PyPI is consumed
|
|
5
|
+
# pypi wheels for 5 platforms + sdist -> PyPI
|
|
6
|
+
# crates-io the Rust crate -> crates.io
|
|
7
|
+
#
|
|
8
|
+
# All at once — push a version tag: `git tag v0.1.0 && git push origin v0.1.0`
|
|
9
|
+
# (a tag ignores the selector and publishes to BOTH registries).
|
|
10
|
+
#
|
|
11
|
+
# PyPI auth: repository secrets TEST_PYPI_API_TOKEN (rehearsals) and PYPI_API_TOKEN (real).
|
|
12
|
+
# Generate at <host>/manage/account/token/ and add under Settings > Secrets > Actions.
|
|
13
|
+
# The two registries are separate accounts, so each needs its own token.
|
|
14
|
+
# Alternatively, leave the secret unset to use Trusted Publishing instead — register a
|
|
15
|
+
# publisher on that host matching owner/repo/workflow/environment exactly.
|
|
16
|
+
# crates.io auth: repository secret CARGO_REGISTRY_TOKEN.
|
|
17
|
+
name: Release
|
|
18
|
+
|
|
19
|
+
on:
|
|
20
|
+
push:
|
|
21
|
+
tags: ["v*"]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
inputs:
|
|
24
|
+
targets:
|
|
25
|
+
description: "Which registries to publish to"
|
|
26
|
+
type: choice
|
|
27
|
+
default: testpypi
|
|
28
|
+
options: [testpypi, pypi, crates-io, both]
|
|
29
|
+
|
|
30
|
+
permissions:
|
|
31
|
+
contents: read
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
# Gate everything on a green test run: a bad crates.io publish cannot be undone, only yanked.
|
|
35
|
+
test:
|
|
36
|
+
uses: ./.github/workflows/ci.yml
|
|
37
|
+
|
|
38
|
+
crates-io:
|
|
39
|
+
needs: test
|
|
40
|
+
# A tag publishes everywhere; a manual run publishes only what you picked.
|
|
41
|
+
if: github.event_name == 'push' || contains(fromJSON('["crates-io","both"]'), inputs.targets)
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
46
|
+
- run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
47
|
+
|
|
48
|
+
wheels:
|
|
49
|
+
needs: test
|
|
50
|
+
if: github.event_name == 'push' || contains(fromJSON('["testpypi","pypi","both"]'), inputs.targets)
|
|
51
|
+
name: wheels (${{ matrix.platform.target }} on ${{ matrix.platform.os }})
|
|
52
|
+
runs-on: ${{ matrix.platform.os }}
|
|
53
|
+
strategy:
|
|
54
|
+
fail-fast: false
|
|
55
|
+
matrix:
|
|
56
|
+
platform:
|
|
57
|
+
- { os: ubuntu-latest, target: x86_64 }
|
|
58
|
+
- { os: ubuntu-latest, target: aarch64 }
|
|
59
|
+
- { os: macos-latest, target: x86_64 }
|
|
60
|
+
- { os: macos-latest, target: aarch64 }
|
|
61
|
+
- { os: windows-latest, target: x64 }
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
- uses: actions/setup-python@v5
|
|
65
|
+
with:
|
|
66
|
+
python-version: "3.12"
|
|
67
|
+
# abi3-py39 means one wheel per platform covers every Python from 3.9 up.
|
|
68
|
+
- uses: PyO3/maturin-action@v1
|
|
69
|
+
with:
|
|
70
|
+
target: ${{ matrix.platform.target }}
|
|
71
|
+
args: --release --out dist --manifest-path python/Cargo.toml
|
|
72
|
+
manylinux: auto
|
|
73
|
+
- uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: wheels-${{ matrix.platform.os }}-${{ matrix.platform.target }}
|
|
76
|
+
path: dist
|
|
77
|
+
|
|
78
|
+
sdist:
|
|
79
|
+
needs: test
|
|
80
|
+
if: github.event_name == 'push' || contains(fromJSON('["testpypi","pypi","both"]'), inputs.targets)
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
- uses: PyO3/maturin-action@v1
|
|
85
|
+
with:
|
|
86
|
+
command: sdist
|
|
87
|
+
args: --out dist --manifest-path python/Cargo.toml
|
|
88
|
+
- uses: actions/upload-artifact@v4
|
|
89
|
+
with:
|
|
90
|
+
name: wheels-sdist
|
|
91
|
+
path: dist
|
|
92
|
+
|
|
93
|
+
pypi:
|
|
94
|
+
needs: [wheels, sdist]
|
|
95
|
+
# `targets: testpypi` uploads to test.pypi.org instead — a throwaway rehearsal, since a real
|
|
96
|
+
# PyPI version number can never be reused once published, even after deleting it.
|
|
97
|
+
name: publish (${{ inputs.targets == 'testpypi' && 'TestPyPI' || 'PyPI' }})
|
|
98
|
+
runs-on: ubuntu-latest
|
|
99
|
+
environment: release
|
|
100
|
+
permissions:
|
|
101
|
+
id-token: write # for Trusted Publishing
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/download-artifact@v4
|
|
104
|
+
with:
|
|
105
|
+
pattern: wheels-*
|
|
106
|
+
merge-multiple: true
|
|
107
|
+
path: dist
|
|
108
|
+
- name: List artifacts
|
|
109
|
+
run: ls -la dist
|
|
110
|
+
- name: Check the upload token is present
|
|
111
|
+
env:
|
|
112
|
+
TOKEN: ${{ inputs.targets == 'testpypi' && secrets.TEST_PYPI_API_TOKEN || secrets.PYPI_API_TOKEN }}
|
|
113
|
+
run: |
|
|
114
|
+
NAME=${{ inputs.targets == 'testpypi' && 'TEST_PYPI_API_TOKEN' || 'PYPI_API_TOKEN' }}
|
|
115
|
+
if [ -z "$TOKEN" ]; then
|
|
116
|
+
echo "::error::Repository secret $NAME is empty or unset."
|
|
117
|
+
echo "The publish step would fall back to Trusted Publishing and fail with a"
|
|
118
|
+
echo "confusing 'invalid-publisher' error. Add the secret at:"
|
|
119
|
+
echo " Settings > Secrets and variables > Actions > New repository secret"
|
|
120
|
+
echo " Name: $NAME (exact, case-sensitive)"
|
|
121
|
+
echo "Generate the value at the matching host's /manage/account/token/ page."
|
|
122
|
+
exit 1
|
|
123
|
+
fi
|
|
124
|
+
# Never print the token; length alone confirms it arrived.
|
|
125
|
+
echo "$NAME is set (${#TOKEN} characters)."
|
|
126
|
+
case "$TOKEN" in
|
|
127
|
+
pypi-*) echo "Prefix looks correct." ;;
|
|
128
|
+
*) echo "::warning::Token does not start with 'pypi-' — check you copied the whole value." ;;
|
|
129
|
+
esac
|
|
130
|
+
- name: Show the identity this job will claim
|
|
131
|
+
run: |
|
|
132
|
+
echo "Register a Trusted Publisher matching EXACTLY these values:"
|
|
133
|
+
echo " Owner: ${{ github.repository_owner }}"
|
|
134
|
+
echo " Repository name: ${{ github.event.repository.name }}"
|
|
135
|
+
echo " Workflow name: release.yml"
|
|
136
|
+
echo " Environment name: release"
|
|
137
|
+
echo
|
|
138
|
+
echo "Uploading to: ${{ inputs.targets == 'testpypi' && 'https://test.pypi.org/legacy/' || 'https://upload.pypi.org/legacy/' }}"
|
|
139
|
+
echo " -> the publisher must be registered on THAT host; pypi.org and test.pypi.org are separate."
|
|
140
|
+
echo
|
|
141
|
+
echo "full workflow ref: ${{ github.workflow_ref }}"
|
|
142
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
143
|
+
with:
|
|
144
|
+
repository-url: ${{ inputs.targets == 'testpypi' && 'https://test.pypi.org/legacy/' || 'https://upload.pypi.org/legacy/' }}
|
|
145
|
+
# API token auth. Leave the matching secret unset to fall back to Trusted
|
|
146
|
+
# Publishing (which needs a publisher registered on that host whose
|
|
147
|
+
# owner/repo/workflow/environment match this job's OIDC claims exactly).
|
|
148
|
+
password: ${{ inputs.targets == 'testpypi' && secrets.TEST_PYPI_API_TOKEN || secrets.PYPI_API_TOKEN }}
|
puggles-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/target
|
|
2
|
+
target/
|
|
3
|
+
# sandbox/
|
|
4
|
+
.DS_Store
|
|
5
|
+
.vscode/*
|
|
6
|
+
.vscode
|
|
7
|
+
.vscode/settings.json
|
|
8
|
+
.vscode/settings.json
|
|
9
|
+
.venv/
|
|
10
|
+
*.ipynb
|
|
11
|
+
.ipynb_checkpoints/
|
|
12
|
+
.claude/*
|
|
13
|
+
|
|
14
|
+
# Python bindings build/packaging artifacts (python/ crate)
|
|
15
|
+
__pycache__/
|
|
16
|
+
*.py[cod]
|
|
17
|
+
*.so
|
|
18
|
+
*.egg-info/
|
|
19
|
+
build/
|
|
20
|
+
dist/
|
|
21
|
+
*.whl
|
|
22
|
+
|
|
23
|
+
# Datasets
|
|
24
|
+
*.csv
|
|
25
|
+
# Build artifacts
|
|
26
|
+
python/target/
|
|
27
|
+
dist/
|