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.
Files changed (39) hide show
  1. puggles-0.1.0/.github/workflows/ci.yml +73 -0
  2. puggles-0.1.0/.github/workflows/release.yml +148 -0
  3. puggles-0.1.0/.gitignore +27 -0
  4. puggles-0.1.0/Cargo.lock +1193 -0
  5. puggles-0.1.0/Cargo.toml +40 -0
  6. puggles-0.1.0/GUIDE.md +451 -0
  7. puggles-0.1.0/LICENSE-APACHE +202 -0
  8. puggles-0.1.0/LICENSE-MIT +25 -0
  9. puggles-0.1.0/PKG-INFO +139 -0
  10. puggles-0.1.0/README.md +173 -0
  11. puggles-0.1.0/pyproject.toml +35 -0
  12. puggles-0.1.0/python/Cargo.lock +1354 -0
  13. puggles-0.1.0/python/Cargo.toml +25 -0
  14. puggles-0.1.0/python/README.md +116 -0
  15. puggles-0.1.0/python/puggles.pyi +162 -0
  16. puggles-0.1.0/python/src/lib.rs +49 -0
  17. puggles-0.1.0/python/src/py_benchmarks.rs +128 -0
  18. puggles-0.1.0/python/src/py_gpu.rs +151 -0
  19. puggles-0.1.0/python/src/py_nsga3.rs +128 -0
  20. puggles-0.1.0/python/src/py_nsgaii.rs +362 -0
  21. puggles-0.1.0/python/src/py_operators.rs +135 -0
  22. puggles-0.1.0/python/src/py_problem.rs +291 -0
  23. puggles-0.1.0/python/src/py_solution.rs +43 -0
  24. puggles-0.1.0/python/src/py_types.rs +92 -0
  25. puggles-0.1.0/src/benchmark_objective_functions.rs +236 -0
  26. puggles-0.1.0/src/checkpoint.rs +61 -0
  27. puggles-0.1.0/src/core.rs +463 -0
  28. puggles-0.1.0/src/dominance.rs +676 -0
  29. puggles-0.1.0/src/gatypes.rs +144 -0
  30. puggles-0.1.0/src/genetic_algorithms_v2.rs +844 -0
  31. puggles-0.1.0/src/genetic_operators/crossover.rs +632 -0
  32. puggles-0.1.0/src/genetic_operators/mod.rs +3 -0
  33. puggles-0.1.0/src/genetic_operators/mutation.rs +409 -0
  34. puggles-0.1.0/src/genetic_operators/selectors.rs +82 -0
  35. puggles-0.1.0/src/gpu_evaluator.rs +301 -0
  36. puggles-0.1.0/src/lib.rs +14 -0
  37. puggles-0.1.0/src/metrics.rs +120 -0
  38. puggles-0.1.0/src/nsga3.rs +375 -0
  39. 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 }}
@@ -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/