Changelog
All notable changes to AMBER will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.4.4] - 2026-07-18
Honest execution lanes, operational contract wording, and opt-in private GPU
fast paths. Builds on the 0.4.3 placement API without overselling “one
unchanged step body” or schedule proofs.
Added
Lane hooks:
step_vectorized()for vectorized CPU/GPU runs andstep_oop()for CPU Agent-object runs. Legacystep()remains the fallback when a lane hook is not defined. GPU placement is vectorized-only; Python Agent objects usecpu(mode="oop").approve_fast_path(evidence)/revoke_fast_path_approval(): private model-specific GPU loops run only withcontract="off"and an explicit per-instance evidence label (caller-supplied provenance; not verified by AMBER). Without approval,gpu().run()uses the instrumented general path.Contract hazard
uncertified_mutable_borrowforagents.array(...).Benchmarks: native lane models, evidence-labeled GPU rows, and a cautionary
benchmarks/try_polars_gpu.pyprobe (not a product path).
Changed
Contract semantics: the snapshot-view contract is an operational monitor at instrumented seams — not a proof that arbitrary NumPy/CuPy or private kernels preserve an intended activation schedule.
cert.cleanmeans no monitored error/warning, not completeness.GPU teardown tracks dirty columns more carefully for host sync.
Docs / README: remove “same
stepbody only” oversell; document lanes,approve_fast_path, and honest benchmark claims.
Notes
Private GPU loops and
ambr.gpu_kernelsremain non-public internals.Polars Lazy
engine="gpu"is not AMBER’s agent GPU runtime.
[0.4.3] - 2026-07-17
Native GPU path and Keras-style device placement on one Model /
view-API step (wording refined in 0.4.4).
Added
Keras-style placement:
model.cpu(mode=...)/model.gpu(mode=...)(default modevectorized;run(mode=...)still overrides) viaambr.execution.Device-resident columns for the native view API under
Model.gpu()(device_columns, GPU sequence writes,DeviceRNG,scatter_add).Tests:
tests/test_execution_api.py; expanded GPU backend tests.
Changed
AMBER (GPU) benchmarks run vectorized models via
model.gpu().run()(main harness is not a separate public kernel path).Fused wealth throughput variant lives in
amber_fused_models.py.FLAME GPU 2 Schelling workload + GPU chart docs note.
[0.4.2] - 2026-07-11
Hygiene, CI quality, and docs release on top of 0.4.1.
Added
GPU ensemble CPU tests (
GPUEnsembleRunner/BatchedWellMixedSIR) and public package exports for the ensemble helpers.CI installs
ambr[perf]on Ubuntu + Python 3.12 (Numba scatter path).Canonical Schelling example +
docs/environments_schelling.rst.docs/deprecations.rst(removed in 1.0 table).Ruff + mypy CI job (gradual mypy module set).
pre-commit hooks: nbstripout + ruff.
Changed
Git history rewrite (drop paper drafts / notebook bloat from history).
Branch protection on
main/dev(required CI checks).Docs / README: public arXiv paper citation; manuscript drafts stay out of the package repository (
paper/ignored).Repo hygiene: stripped notebook outputs; no tracked benchmark JSON; tighter
.gitignore/MANIFEST.in.
[0.4.1] - 2026-07-11
Polish release on top of 0.4.0: AgentPy-shaped UX, progressive speed lanes (with Mac-friendly Numba), contract/write-path hardening, SMAC install reliability, and Schelling/grid helpers.
Added
UX / AgentPy lane:
RunResultsattribute access,agents.random(), defaultshow_progress=False, anddocs/from_agentpy.rst.Easier speed lanes:
am.print_status()/am.recommend(n),ArrayKernelModel,agents.update_where,docs/going_faster.rst,examples/gpu_quickstart.py.Optional Numba CPU path (
ambr[perf]): JITscatter_add/ subset writes; status reports Numba (useful on Mac without CUDA).Shared write helpers:
ambr._id_index(id→row cache) andperformance.apply_scatter_add/apply_scatter_write.Grid occupancy helpers on
GridEnvironmentfor Schelling-style models (get_random_empty_cell,get_agent_at_pos,add_agent_from_id,remove_agent_from_pos,get_empty_cells_in_radius,get_neighbors(..., radius=)). Restoresexamples/smac_calibration_advanced.py.MultiObjectiveSMAC CI smoke;
ambr[advanced]pinsscikit-learn>=1.6.1,<1.9for SMAC 2.4 compatibility.
Changed
Contract monitor extraction: runtime snapshot-view bookkeeping moved from
Modelintoambr.contract.ContractMonitor(Modelkeepscontract_certificates/_contract_modefor callers).Unified write/contract seam: whole-column view writes and tensor-lane commits report through
Model._set_frame(..., written_columns=...), so same-step double commits on the view path are visible undercontract="check"|"warn"|"raise".scatter_addremains the sanctioned multi-write reducer (not counted as ordinary multi-write).Cross-path detection: same-step OOP + lane/view writes on one column raise
cross_path_write.Atomic
agents.set(one frame update, one commit per column); saferNonedefaults formodel_reporters/agent_reporters/params.update_agent_data/batch_update_agentsuse the buffered and view write seams;Environment.dfuses realModel._set_framewhen available.Public package exports for
ContractMonitor,TensorLane,borrow_numeric,commit_columns, GPU helpers,RunResults,ArrayKernelModel, and lane helpers (status,print_status,recommend).Canonical-verb docs: select / write / scatter_add / borrow-commit surface (quickstart, sequences API, README); examples prefer
agents.at[...].setover deprecatedupdate_agent_data.Write-path performance: shared id→row scatter for filtered assigns and OOP flush; contiguous
0..N-1id layout cached per id-version.MultiObjectiveSMACrebuilt on per-objectiveSMACOptimizer.
Deprecated
Model.update_agent_data→agent.<col> = value/agents.at[id].setModel.batch_update_agents→agents.at[ids].setPopulation.set_agent_value/batch_update/batch_update_by_ids→ viewset/ column assign (until 1.0)Assigning
Population.data = ...→ view write path (setter warns; internalreplace_frameis the quiet Model seam)
[0.4.0] - 2026-06-27
The 0.4 release settles the public API on one canonical verb per task (legacy
spellings still work, emitting a DeprecationWarning and scheduled for
removal in 1.0; set AMBER_SUPPRESS_DEPRECATIONS=1 to silence them), and adds
the snapshot-view contract checker, a resident tensor lane, a CuPy GPU backend,
and SMAC 2.x-compatible optimization.
Added
Snapshot-view contract:
model.run(contract="check"|"warn"|"raise")records a per-stepContractCertificateof conflicts observed at instrumented API seams; inspectresults["contract"](modeoffis the zero-bookkeeping default). A clean record is not a proof for arbitrary array code.Tensor lane: zero-copy
agents.borrow(col)/agents.commit(**cols)over the Polars frame, routed through the contract.GPU backend:
ambr.gpuarray-module abstraction with NumPy fallback, andambr.gpu_ensemble(GPUEnsembleRunner,BatchedWellMixedSIR,smac_batch_calibrate) batching a(B × N)ensemble into one device pass.Declarative
model_reporters/agent_reportersandrecord_initial; typedparamsschema andAttrDict.get_int/get_float/get_bool.AgentListfaçadesby_id/numpy/set/borrow/commit/frame;add_agents(n, agent_class=...)tracks Python agent objects.Cross-framework calibration and scaling benchmarks (Agents.jl, mesa-frames, FLAME GPU) and a tensor-lane flocking example.
Changed
One canonical RNG:
self.rng(NumPyGenerator) andself.random(stdlib), both seeded fromseed; seeded runs no longer touch globalnp.random.Encapsulated write boundary (internal
Model._set_frame);agents.frameread accessor.update()is a pure hook (nosuper().update()needed); step advance and data finalize moved into the runner.Vectorized
SpaceEnvironment.get_neighbors(NumPy + scipy KD-tree);wrap=collapses totorus=. Examples migrated torng.
Fixed
optimization: explicitrngthreading (no global seed mutation) and SMAC 2.x compatibility forSMACOptimizer/bayesian_optimization.NetworkEnvironment.__init__no longer dropsnode_idwhen addingnetwork_distance;SpaceEnvironment.move_agentno longer raises a dtype error on object-typed position columns.
Deprecated
Legacy verbs kept until 1.0 (each warns toward the canonical form):
nprandom→rng;model.record→record_model/model_reporters;agents.select→agents.where;agents.record/agents.update_data→agents.set/agent.<col> = v;agents.agents/agents.agent_ids→ iterate /agents.by_id;GridEnvironment(wrap=)/.wrap→torus=.
[0.3.13] - 2026-06-04
Changed
Ignored root-level LaTeX paper build outputs so local manuscript compilation does not dirty package release branches.
Kept project metadata, runtime fallback version, documentation version, and changelogs aligned for the package release.
[0.3.12] - 2026-06-04
Changed
Tightened the source distribution surface so local-only directories such as tests, benchmark fixtures, documentation builds, GitHub metadata, assistant metadata, and paper drafts stay out of package archives.
Added release-workflow package-surface validation for the wheel and source distribution before creating the GitHub release.
Kept project metadata, runtime fallback version, documentation version, and changelogs aligned for the package release.
[0.3.11] - 2026-06-04
Changed
Cut a clean package release from an up-to-date
devbranch intomain.Kept release metadata, runtime fallback version, documentation version, and changelogs aligned for the wheel and source distribution.
Explicitly ignored local assistant metadata along with paper drafts and paper archives so package releases stay focused on the AMBER library.
[0.3.10] - 2026-06-04
Changed
Cut a main-anchored package release after synchronizing
dev,main, and their remotes.Kept package metadata, runtime fallback version, documentation version, and release notes aligned for the distribution artifacts.
Preserved local paper drafts and generated paper archives as ignored, non-package artifacts.
[0.3.9] - 2026-06-04
Changed
Added a root split-SIR benchmark runner with deterministic shared inputs, explicit sync/async schedules, Agents.jl fixtures, checked result artifacts, and declared async SimPy budget skips.
Added a root dynamic-graph coordination benchmark runner and checked result artifacts across AMBER, NumPy, Polars, a Python object loop, Mesa, AgentPy, and Agents.jl.
Clarified public benchmark wording so the schedule-mixed headline SIR row is not presented as an equivalent-trajectory AMBER-over-Julia claim.
[0.3.8] - 2026-06-04
Changed
Upgraded the all-framework benchmark runner to default to 10 full-run samples, preserve raw Agents.jl subprocess samples, and write raw sample counts, IQRs, and bootstrap median intervals into
benchmark_results_all.json.Regenerated the all-framework headline benchmark artifacts so all 63 framework/model/size rows carry 10 raw timing samples, including Agents.jl.
[0.3.7] - 2026-06-04
Fixed
Moved GitHub Actions workflows to current Node-24-ready action versions for release, checkout, setup-python, upload-artifact, and Codecov steps.
Corrected the Codecov upload input from
filetofiles.
[0.3.6] - 2026-06-04
Changed
Added a tag-driven GitHub release workflow that builds and validates wheel and source distributions before attaching them to the release.
Extended CI coverage to the
devbranch and Python 3.9, matching the declared package support floor.Added package metadata consistency checks so runtime, project, and documentation versions do not drift across releases.
Tightened release-package hygiene around generated paper outputs and source distribution contents.
[0.3.5] - 2026-06-04
Changed
Cut a package-only release with synchronized project metadata, runtime version, and Sphinx documentation version.
Kept local paper drafts and generated paper archives outside the tracked package release surface.
[0.3.4] - 2026-06-03
Fixed
Synchronized Sphinx documentation metadata with the package release version.
Kept runtime, project metadata, and generated documentation versions aligned for patch releases.
[0.3.3] - 2026-06-03
Changed
Package metadata now lives in
pyproject.tomland builds through the standard PEP 517/518 Python packaging flow.setup.pyis kept as a compatibility shim for older editable-install tooling.Wheel and source distributions now include package URLs and keyword metadata.
Fixed
Removed tracked coverage artifacts from the repository.
Tightened source-distribution hygiene so local paper drafts, caches, and coverage files stay out of release artifacts.
Corrected the
Makefilecoverage target to use thesrc/ambrpackage path.
[0.3.2] - 2026-06-03
Fixed
Model.run()andModel.run_step()now execute exactly the requested number of model steps after setup.Benchmark helpers now validate structural correctness before timing wealth transfer, random walk, and SIR runs.
Agents.jl benchmark parameters are routed through the master runner instead of hardcoded step counts.
Changed
Regenerated all-framework benchmark results with seeded timing, slowest-sample trimming, and documented SIR update-ordering caveats.
Preserved raw per-run timing samples for Python-hosted frameworks in the benchmark JSON.
Updated README benchmark tables and installation docs for the current Python support floor.
Stopped tracking draft paper files in the package repository.
[0.3.0] - 2026-05-09
Added
Agent.__setattr__now routes non-internal attribute writes throughmodel._queue_write(), keeping PythonAgentobjects and the columnar DataFrame in sync. Settingagent.wealth = 5automatically updates the DataFrame — no more silent desync between OOP-style and view-API access.Environment.dfis now a property that reads from and writes tomodel.population.data(ormodel.agents_dffor mock models), eliminating DataFrame staleness inGridEnvironment,SpaceEnvironment, andNetworkEnvironment.IntRangenow supports__contains__,__iter__, and__len__for better ergonomics with Python’s standard range semantics.SpaceEnvironmentinitialisation no longer drops thespace_positioncolumn when bothspace_positionandspace_distanceneed to be created.
Changed
IntRangesemantics are now consistently exclusive-end, matching Python’srange():IntRange(1, 10)yields values1..9. Previously the semantics varied acrossParameterSpace.sample()(inclusive) andSample._generate_combinations()(exclusive).Model.run()now delegates toModel.run_step(), removing 30 lines of duplicated setup/step/update/finalize logic.Model.add_agents(n, agent_class=..., **columns)now forwards PythonAgentattributes set duringsetup()into the batch DataFrame write, so columns declared viaself.wealth = 5insetup()appear in the population automatically.Population._align_and_concat()now emits aUserWarninginstead of silently casting mismatched column types toUtf8.__init__.pynamespace cleanup was removed; the aggressive module- level symbol deletion no longer hides legitimately imported names.Dependencies:
setup.pynow declarespython_requires=">=3.9"(was>=3.8, which is incompatible withnumpy>=1.20). Python 3.8 classifier removed.Test suite:
test_population.pymigrated fromunittest.TestCasetopyteststyle, consistent with every other test file.
Fixed
bayesian_optimization()is now backed by SMAC3 (RandomForest surrogate model + Expected Improvement acquisition) instead of being pure random search. Requiressmacto be installed. The simpleParameterSpaceis automatically converted to a SMAC3ConfigurationSpace.Environment.dfsetter correctly handles mock models (no longer trips onhasattrreturningTruefor auto-created Mock attrs).SpaceEnvironmentconstructor no longer overwrites thespace_positioncolumn when addingspace_distance.
[0.2.0] - 2026-04-10
Added
Vectorized view API on
AgentListas the primary vectorized interface.model.agents.where(predicate)/model.agents[mask]return filtered views;model.agents.at[ids]returns scatter views. Column attribute access on any view returns a Polars Series backed bymodel.agents_df, and column attribute assignment queues through the batched flush path.Model.add_agents(n, agent_class=None, **columns)— columnar bulk-create that delegates toPopulation.batch_add_agentsand, ifagent_classis supplied, also wires up lightweight PythonAgentinstances for per-agent method dispatch.view.scatter_add(**increments)— id-indexed accumulate for flow-of- resources updates. Correctly sums duplicate ids instead of last-write-wins.New
Model.get_agent_dataandModel.run_stepmethods, finally matching the signatures the tutorial and examples had been assuming.Population.batch_add_agentsnow acceptspl.Seriescolumn inputs alongside lists and numpy arrays.Full quickstart and tutorial rewrite showing the vectorized idiom as the default path. Docs now build strict (
sphinx-build -W).TestVectorizedWorkflowsintegration tests covering wealth-transfer, SIR transitions, scatter-add invariants, and mixed per-agent/view usage.
Changed (breaking)
AgentList.<col>attribute access now reads frommodel.agents_dfand returns a Polars Series. Previously it aggregated Python attributes from eachAgentinstance into a numpy array, which silently desynced from any DataFrame-level write (the biggest footgun in the library).Migration: if you set custom state via Python attributes on Agent objects and read it back as a numpy array, switch to:
# Before agent.custom = value arr = self.agents.custom # np.ndarray (Python attrs) # After — column lives in the DataFrame self.agents.custom = value_array # bulk write series = self.agents.custom # pl.Series (agents_df)
AgentList.__getattr__no longer forwards unknown names to per-agent method calls. Use the explicitagents.call('method_name', ...)entry point, which has been there since v0.1.4.
Deprecated
Population.create_batch_context()now emits aDeprecationWarning. Replace withmodel.agents.at[ids].col = valuesormodel.agents.at[ids].scatter_add(col=delta).
Fixed
Batched
Agent.record()path: per-call DataFrame clones are replaced by a hash-join flush. On a 10 000-agent wealth-transfer benchmark, step throughput improved by ~6300× over the previous per-callwith_columnspath (0.33 s vs. ~35 min projected for 100 steps).AgentList.record()/update_data()on a subset view now only touch rows inside the subset. Previously both methods accidentally broadcast their value to every agent in the population.Agent.record()/update_data()auto-create missing columns instead of raisingColumnNotFoundError.GridEnvironment.get_neighbors()with wrapping now deduplicates wrapped offsets and excludes the origin whendistance >= dim.MultiObjectiveSMACtarget-function lambdas now capture their objective by value (loop-closure bug).pytest.ini/MANIFEST.in/docs/api/population.rst: correctedsrc/amber→src/ambrpath typo that had been hiding coverage tracking onpopulation.pyand autodoc onPopulation.Sphinx docs now build under
sphinx-build -W --keep-goingwith zero warnings.
[0.1.5] - 2026-01-30
Fixed
Fixed regression in
Model.add_agent()making it defensive against users overwritingself.agents(critical for integration tests)
[0.1.4] - 2026-01-30
Added
Vectorized attribute access on
AgentList(returns numpy arrays)Advanced indexing/masking support for
AgentList(slices, list of indices, boolean masks)Concatenation support for
AgentListusing the+operatorModel.record()as an alias forrecord_model()(AgentPy compatibility)
Changed
AgentList.select()now supports boolean mask indexingAgentList.call()now returns a numpy array of results
[0.1.3] - 2026-01-28
Fixed
Fixed test suite to properly validate
AttrDictwrapper behavior
[0.1.2] - 2026-01-28
Added
AttrDictclass for AgentPy-compatible attribute-style parameter access (self.p.param_name)Method forwarding on
AgentListfor AgentPy-style syntax (agents.method()calls method on all agents)
Changed
AgentList.call()now returns list of results from each agent’s method callBaseModelandBaseAgentnow useAttrDictfor parameter storage
[0.1.1] - 2026-01-21
Fixed
Renamed stale amber imports to ambr in example notebooks and documentation (# <PR/Commit>)
Corrected version consistency across setup.py, __init__.py, and documentation
Changed
Bumped version to 0.1.1
Added
Comprehensive documentation with ReadTheDocs integration
Jupyter notebook examples converted to Python scripts
Tutorial and API reference documentation
Contributing guidelines and development workflow
[0.1.0] - 2024-06-19
Added
Initial release of AMBER framework
Core Model and Agent classes
GridEnvironment, SpaceEnvironment, and NetworkEnvironment
AgentList for managing agent collections
Optimization module with grid search, random search, and Bayesian optimization
Experiment framework for parameter sweeps
Comprehensive test suite with 100% pass rate
GitHub Actions CI/CD pipeline
Coverage reporting with Codecov
Example notebooks for various simulation types
Features
High-Performance Data Structures: Using Polars for fast DataFrame operations
Flexible Environments: Support for grid, continuous space, and network topologies
Built-in Optimization: Parameter tuning with multiple optimization algorithms
Comprehensive Testing: Full test coverage across all modules
Professional Documentation: Sphinx-based documentation with examples
Fixed
Model execution flow and data recording issues
Environment class compatibility with different input formats
Random number generation compatibility across numpy versions
DataFrame schema consistency in agent data management
Mock object compatibility in test environments
Changed
Moved from examples/ to docs/examples/ for better organization
Enhanced README with professional presentation
Improved error handling and user feedback
Technical Details
Dependencies: Polars, NumPy, NetworkX, Matplotlib, Seaborn
Python Support: 3.9+
Testing: pytest with comprehensive coverage
Documentation: Sphinx with ReadTheDocs theme
CI/CD: GitHub Actions with multi-OS and multi-Python testing