Skip to content

fix(population): compile the Ensemble solver template lazily - #50

Merged
HugoFara merged 1 commit into
mainfrom
fix/lazy-ensemble-template
Sep 12, 2026
Merged

HugoFara merged 1 commit into
mainfrom
fix/lazy-ensemble-template

Conversation

@HugoFara

Copy link
Copy Markdown
Owner

Summary

Two release blockers found while testing the 1.2.0 tree against released consumers. Neither is in 1.1.1's public behaviour; both would have shipped.

Optimizers refused linkages the numba solver cannot represent

Since 6fd257a, linkage_to_solver_data() raises NotImplementedError for a dyad it cannot type, instead of mistyping it into NaN. That is right for the solver — but Ensemble.__init__ compiled the solver template eagerly, and an Ensemble is what every optimizer returns. So on this tree:

particle_swarm_optimization(fitness, linkage_with_a_PPDyad, ...)
# NotImplementedError: The numba solver cannot represent PPDyad ...

for any linkage holding a PPDyad, a cam follower, or leggedsnake's Walker (a duck-typed container whose parts are mechanism joints). On 1.1.1 all of those optimize. Released leggedsnake 0.6.0 against this tree: 5 failures (multi_objective_optimization, chain_optimizers, NSGA walking optimization), all this.

The template is now compiled on first use — Ensemble.template, which simulate(), simulate_member() and topology_key go through. n_joints comes from the positions array; from_agents() / from_pareto_front() count the linkage's parts. An Ensemble of an unsupported linkage holds its members and scores exactly as before, and only batch simulation raises, with the same message. Slices share the compiled template.

pip install pylinkage failed on Python 3.10

mechanism.builder imports Self from typing_extensions below 3.11; the package never declared it. A bare install on 3.10 could not import pylinkage at all. Present in 1.1.1 too. Now declared with a python_version < '3.11' marker.

Verification

  • pylinkage: 2554 passed under -W error::DeprecationWarning; ruff, mypy clean. Two regression tests added.
  • Released leggedsnake 0.6.0 (PyPI) against the wheel from this branch: 627 passed (was 5 failed), no DeprecationWarning from pylinkage.
  • leggedsnake Add a GUI #9 against this tree: 627 passed.
  • Wheel installed with no extras on a fresh Python 3.10 venv: imports; no optional dependency loaded at import.

Since 6fd257a, linkage_to_solver_data() refuses dyads the numba solver
cannot represent instead of mistyping them. Ensemble compiled that
template in __init__, and an Ensemble is what every optimizer returns,
so particle_swarm_optimization() and multi_objective_optimization()
raised NotImplementedError for any linkage holding a PPDyad, a cam
follower, or a duck-typed container such as leggedsnake's Walker --
mechanisms 1.1.1 optimized without complaint, because the optimizer
never touches the solver.

The template is now compiled on first access (Ensemble.template), which
simulate(), simulate_member() and topology_key go through. n_joints
comes from the positions array and from_agents()/from_pareto_front()
count the linkage's parts, so an Ensemble of an unsupported linkage
holds its members and scores as before; only batch simulation raises,
with the same message. Slices share the compiled template.

Also declares typing_extensions for Python < 3.11: mechanism.builder
imports Self from it, so a bare install on 3.10 could not import the
package at all (present in 1.1.1).

Released leggedsnake 0.6.0 against this tree: 627 passed, was 5 failed.
@HugoFara HugoFara added the bug Something isn't working label Sep 12, 2026
@HugoFara
HugoFara merged commit ba12985 into main Sep 12, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant