Repository navigation
Releases: RemiPelloux/Modelly
Releases · RemiPelloux/Modelly
Release list
Modelly 1.3.1
No score is slower than 1.2.0 any more: benchmarked against the 1.2.0 wheel with identical
dependencies (core operations, the playbooks and a research notebook, in paired alternating
runs; docs/performance.md, "No regression from release to release").
Performance
- Reading a
Columnattribute costs what it did in 1.2.0 again. 1.3.0's getter kept the
column's name for the error of a removed agent, which cost about 2.5% per read; it now looks
the name up only when the error is raised. The error is unchanged. - On regular (GIL) builds, the neighbourhood walk (
Cell.get_neighborhood) and the cell move
are 1.2.0's code again, without the free-threading safety 1.3.0 added to every call (a
reference count per neighbour, a cache-generation check per move). Free-threaded builds
keep their safe paths. FixedAgent.removereads its cell once.
Fixed
- A timing test of
modelly profile --sizescompares populations 16 times apart, so it no
longer fails on a slow runner.
Modelly 1.3.0
The research release: calibrate, explain, scale and publish a model, on Windows, macOS and
Linux. Everything from 1.2 keeps working; what 2.0 will change now warns (see
docs/deprecations.md). The plan behind it is in docs/roadmap/1.3.0.md.
Answers
modelly.experiments: a study as one object.ScenarioSpace(ranges, log and integer
ranges, choices, fixed values, checked against the model'sScenario), designs (full
factorial, Latin hypercube, Sobol, Halton, custom), replicates with one seed per run, a
Parquet results store with a DuckDB view that resumes after a crash, and executors:
serial, threads, processes, Dask, Ray, SLURM and PBS job arrays (pluggable through the
modelly.executorsentry points). The same experiment gives the same results on every
executor.modelly experiment run|status spec.toml.modelly.calibrate:ABCRejection,ABCSMC(adaptive tolerances, resumable),
SimulatedMomentsand a basicBayesOpt; priors, targets and distances; aPosterior
with summaries, HDIs, posterior predictive runs and plots. Verified by recovering the
parameters of SIR and predator-prey models from synthetic data.modelly calibrate.modelly.sensitivity: one-at-a-time, Morris, Sobol (Saltelli sampling, bootstrap intervals;
matches the Ishigami indices) and PAWN, on a model, a function or a Gaussian-process
emulator.modelly sensitivity.DataCollector.to_parquet,to_arrowandquery(DuckDB).
Trust
- Provenance:
modelly runwrites the outputs and a manifest (code hash, versions, compiled
or pure build, platform, scenario, seeds, input and output hashes);modelly verifyreruns
it and names the first differing output;modelly bundlepacks a byte-identical zip for
Zenodo;modelly oddwrites an ODD protocol skeleton from the code. modelly.timetravel:Recorderkeeps checkpoints within a memory or disk budget;
at(step)rewinds, a replay is bit-identical with a straight run,branchforks futures,
anddifffinds the first step, agent and attribute where two runs part.- A determinism suite: every example, compiled and pure-Python, straight and resumed from a
checkpoint, against stored digests that every platform must reproduce
(python -m modelly.dev golden). Property-based tests for columns, cohorts, cell spaces,
checkpoints and designs.
Reach
modelly.space.geo(extrageo):GeoSpacewith a coordinate reference system, regions,
contiguity and distance queries in metres, GeoParquet and GeoJSON export;RasterLayer
(GeoTIFF);RoadNetworkwith routing and travel times; synthetic populations by
iterative proportional fitting.modelly.space.networks: temporal networks (O(changed edges) updates), multilayer networks,
contact matrices, network collectors; NetworkX, igraph and CSV import.modelly.llm: language-model agents with a provider-agnostic client (Anthropic,
OpenAI-compatible and local endpoints, a fake provider), a deterministic SQLite response
cache with offline replay, token and cost budgets, retries, structured decisions with
schema validation, andLLMAgent. API keys never reach caches, checkpoints or logs.modelly.zoo: twelve validated reference models (age-structured SEIR, Nagel-Schreckenberg
traffic, Bass diffusion, Deffuant and Hegselmann-Krause opinions, Axelrod culture, kinetic
and Bouchaud-Mezard wealth, a double-auction order book, forest fire, an energy-budget
population, vector-borne transmission), each with a validation test against an analytic or
known result.modelly zoo list|info|copy,modelly new --from-zoo.- New examples: a commuting city and a three-layer epidemic (spatial), persona agents
deciding throughmodelly.llm.
Experience
- Modelly Studio:
modelly studio model.py:Modelopens a browser app with a parameter panel
built from the scenario, run controls, space and time-series views, an agent table, a
timeline scrubber on time travel with replay from any step, profiler and lint panels, and
exports (figures, data, checkpoints, GIF). modelly newwith grid, network, continuous and cohort templates (seeded, tested, linted).modelly lint --fixand--difffor MDL001, MDL002, MDL003 and MDL009; new rules MDL010
(a lambda or closure sent to spawned workers, which fails on Windows and macOS) and MDL012
(a network or LLM call that bypassesmodelly.llm).python -m modelly.dev gate: the local gate in Python, for contributors without bash.- Jupyter:
%load_ext modelly.ipythonfor%modelly lintand%modelly profile, and a rich
display of aModel. - Publication figures (
modelly.viz.styles.paper(), journal widths, colour-blind-safe
palettes) and GIF or MP4 export of any space view (extravideo). - Plugins: entry-point groups for spaces, executors, samplers, collectors, Studio views and
lint rules (modelly.plugins). modellylists its fourteen commands by task: start, run and explore, publish.- Docs: six domain tutorials, an eight-session course pack, a gallery, guides for every new
module, and the roadmap for 1.3 to 2.0.
Performance and platforms
fastset.c:AgentSettype filtering,select, attribute reads inaggand weak-set
listing in C (0.45 to 0.95 of the Python time on 20,000 agents), with Python twins.- The four compiled modules run on free-threaded CPython with the GIL off; free-threaded
wheels are built, as are Windows ARM64 wheels on a native runner. modelly bench: the playbooks in alternating rounds, CPU pinning where the OS allows it, a
JSON-lines history and a regression check (exit 1).- Memory baseline per agent recorded in
docs/performance.md. - Every text file is opened as UTF-8 (ruff
PLW1514), checkpoints are written atomically, and
hashed text outputs use LF line endings, so results and hashes match on every OS.
Changed
- Reading or writing a
Columnon a removed agent raisesColumnMissingError(an
AttributeError) instead of reading a stale row. Errors for a full cell, a missing agent
and a removed agent name the agent and the model time. - Deprecations raise
ModellyDeprecationWarning, both aDeprecationWarningand a
FutureWarning, naming the replacement and the removal in 2.0. - A checkpoint loads only into the Modelly minor version that wrote it: 1.2 checkpoints do not
load in 1.3. - Every public name has a stability level (
docs/api_stability.toml): what 1.2 had is stable,
what 1.3 adds is provisional.
Fixed
- The Epstein example's scenario declared
rng: int = 42, overriding any seed; the virus
network example built a different network in each process. Both are seeded from the model. - The Epstein, prisoner's dilemma and Sugarscape examples can be checkpointed.
- Browser tests bind free ports, so two test runs can share a machine.
Modelly 1.2.0
Added
- Checkpoints:
model.save(path),Model.load(path)andmodel.checkpoint_every(n, pattern).
A run resumed from a checkpoint, in a new process, gives exactly the run it would have been:
both random generators, the event scheduler, spaces, columns and collected data are saved.
A checkpoint made with the compiled random core loads into the pure-Python one and the other
way round. Loading runs pickle: only load files you trust. Lambdas and closures are refused
with an error naming them. - Versioned documentation:
/Modelly/is the latest release,/Modelly/dev/is main and
each minor release keeps its own folder (/1.0/,/1.1/,/1.2/), with a version switcher
in the navbar and a banner on older versions. modelly profile --sizes 1000,4000(andmodelly.profile.compare_sizes) profiles a model
at several population sizes and compares the cost per agent, so the MDL101 hint also works
for models whose population does not change during a run.MetaAgents.cache_build(score): scores each candidate group once across repeated
find_combinationscalls, withinvalidate()and an optionalmaxsize.- Windows wheels (x86-64) with the compiled modules.
Changed
modelly lint --help,modelly migrate --helpandmodelly profile --helpname the
command as it was run (modelly <cmd>, orpython -m modelly.<cmd>).- MDL107 follows imports of agent classes from other files in the linted tree, so models split
into several modules are checked. - A
CellCollectionbuilt without a generator takes its cells' or agents' model generator, so
the same seed gives the same draws. - The creation path of meta agents returns
MetaAgentinstead ofAny.
Performance
- Removing an agent that belongs to meta agents reads its own memberships instead of copying
the whole membership table: 2,000 removals among 10,000 agents went from 100 s to 0.16 s. fastcell.cuses only the public C API, with the same speed as 1.1.0.- The Sugarscape playbook ranks cells only when a forager's best cell is taken: 2.5x faster
than in 1.1.0, 32x faster than Mesa 2.3 (was 12x), same results.
Fixed
- A continuous space restored from a pickle kept a copy of the agent positions, so later moves
were lost; it now keeps a view. - The empty-cell index keeps its order through pickling, so a restored grid draws the same
empty cells. DataCollectorreporters are picklable.
Modelly 1.1.0
Added
modelly.profile: a runtime profiler.with Profiler(model) as prof: model.run_for(n), then
prof.report()orprof.to_dataframe(), gives the time of each step by agent class and
method (calls, agents per call, microseconds per agent), data collection and scheduled events,
with hints that point at the matching lint rule.python -m modelly.profile model.py:MyModel
runs it from the command line. Results are identical with and without the profiler, and the
instrumented methods are restored exactly on exit.python -m modellyand amodellyscript: one entry point forlint,migrateandprofile,
with--versionand a help page listing every command.AgentPortrayalStyle.filled(Altair backend); extra keywords todraw_agentsreach
mark_pointinstead of being dropped.- Three benchmark playbooks, each for Mesa 2.3 and Modelly with agreement and determinism
checks:schelling(27x),boltzmann_wealth(7.4x) andsugarscape(12x).
Linter
- New rules: MDL005 wall-clock or OS entropy in model code, MDL006 ordering by
id()or
hash(), MDL007 removing agents while looping over the population, MDL008globalstate in
a model method, MDL009 editingmodel.agentsdirectly, MDL106 DataFrames built insidestep,
MDL107 a per-agent loop that only writes columns. - MDL001 also catches unseeded
Random(),SystemRandomand numpy generators without a seed,
and resolves imports (default_rng(seed=7)is no longer flagged); MDL004 skips__slots__
andClassVar. # noqa: MDLxxxsuppression,[tool.modelly.lint]inpyproject.toml(select,ignore,
per-file-ignores),--explain CODEwith a bad and a fixed example,--statistics,
--format githuband--quiet.- Detailed
--helpforlintandmigrate, with examples and exit codes;docs/lint.md
lists every rule.
Performance
- Moving an agent between cells runs in a third compiled module (
modelly/_native/fastcell.c):
one move is 205 ns to 107 ns, the cell-list playbooks 7 to 14% faster, with the same results.
Subclasses that overrideadd_agentorremove_agentkeep their overrides; the pure-Python
twin is used when the module is not built. import modellyno longer walks the stack to name its loggers (about 30 ms less).
Fixed
- Matplotlib marker groups are drawn in first-seen order instead of set order, so the
layering no longer changes from run to run. run_batchno longer emits Python's multi-threaded forkDeprecationWarningfor closure
batches.
CI
- Release wheels are built on tags and manual runs only; superseded runs are cancelled;
docs-only changes skip the build; Dependabot groups its updates monthly; theexamplesjob,
which checked out a missing repository, is gone (the test matrix already runstests/examples).
Modelly 1.0.0
First release of Modelly with the domain package layout (core, space, time, data, behaviour, scenarios, batch, viz). See CHANGELOG.md.
On PyPI this code ships as modelly-abm 1.0.1, because PyPI does not accept a second upload of 1.0.0.