Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9115044
docs: define distributed output ownership
VEZY Aug 23, 2026
2b6ac84
benchmark: establish distributed output baselines
VEZY Aug 23, 2026
6e7350d
feat: expose identities for compiled many bindings
VEZY Aug 23, 2026
657980d
benchmark: cover compiled many identity access
VEZY Aug 23, 2026
ef1436b
docs: explain identity-aware many inputs
VEZY Aug 23, 2026
5e59a73
feat: compile cross-object output targets
VEZY Aug 23, 2026
070497e
benchmark: cover distributed output compilation
VEZY Aug 23, 2026
7f802fd
docs: describe distributed output destinations
VEZY Aug 23, 2026
55f4db0
feat: schedule and retain distributed outputs
VEZY Aug 23, 2026
da6001e
feat: add keyed output assignment
VEZY Aug 23, 2026
840c31d
benchmark: cover distributed output execution
VEZY Aug 23, 2026
ab8df2e
docs: document keyed output assignment
VEZY Aug 23, 2026
55530eb
feat: resolve registered source object identities
VEZY Aug 23, 2026
6f8dcdd
perf: eliminate wide output alias allocations
VEZY Aug 23, 2026
f4930fe
benchmark: cover wide identified output assignment
VEZY Aug 23, 2026
e3568c0
perf: materialize heterogeneous temporal inputs without allocations
VEZY Aug 23, 2026
507a380
feat: allow authoritative dynamic-organ status initialization
VEZY Aug 25, 2026
c36b0b9
fix: resolve distributed-output runtime dispatch
VEZY Aug 25, 2026
cdcc82e
refactor: keep runtime status in model registry
VEZY Aug 26, 2026
b8fbfb2
feat: expose current execution target identity
VEZY Aug 26, 2026
e6aae3b
feat: validate scientific variable contracts
VEZY Aug 26, 2026
e43da4c
docs: document hard-call targets
VEZY Aug 26, 2026
5ccb49a
feat: initialize newly registered scheduled objects
VEZY Aug 26, 2026
a0cd558
fix: correct Beer extinction fitting
VEZY Aug 26, 2026
8efeffc
Add compile-time status type conversion
VEZY Aug 26, 2026
9956913
Add status conversion diagnostics and safe initialization
VEZY Aug 26, 2026
f673df1
Preserve converted types through runtime lifecycle
VEZY Aug 26, 2026
d2a4de6
Validate particle status propagation
VEZY Aug 26, 2026
5d5d56b
Cover status conversion in instances and hot paths
VEZY Aug 26, 2026
521cee9
Preserve temporal reducer result types
VEZY Aug 26, 2026
8338bd8
Preserve status policy in graph editor rebuilds
VEZY Aug 26, 2026
c1bfacc
Complete status conversion test matrix
VEZY Aug 26, 2026
ec63a97
Document scenario status type conversion
VEZY Aug 26, 2026
cd8dfbb
Prevent stale MTG runtime status columns
VEZY Aug 26, 2026
bfcd4fa
Preserve configuration exceptions
VEZY Aug 26, 2026
f6e5b6d
Qualify Beer fitting test API
VEZY Aug 26, 2026
8b47f11
Benchmark status registry lookup
VEZY Aug 27, 2026
696d8e6
Fix empty-plan structural refresh
VEZY Aug 27, 2026
c1d6de6
Benchmark organ lifecycle costs
VEZY Aug 27, 2026
90d151a
fix: reserve detached MTG node ids
VEZY Aug 27, 2026
2e3b471
Fix Julia 1.10 allocation test
VEZY Aug 28, 2026
1235499
Delete TEMP_IMMUTABLE_SCENARIO_PERFORMANCE_GOAL.md
VEZY Aug 28, 2026
775144f
Update Project.toml
VEZY Aug 28, 2026
f2b669d
Restore incremental lifecycle performance
VEZY Aug 30, 2026
984e289
Merge pull request #211 from VirtualPlantLab/codex/xpalm-performance-…
VEZY Aug 30, 2026
d8d2c55
Fix graph editor sample initialization metadata
VEZY Aug 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@
- `run_call!(context, name)` for the common execute-all operation while
retaining `run_call!(target::CallTarget)` for selective, per-target, and
iterative control.
- `add_organ!(...; use_status_adapter=false)` for topology engines whose new
node attributes already form the authoritative initialization payload. The
default remains `true`; opting out skips only the stored adapter status
initializer while preserving node attributes, explicit initial-value
precedence, node identity, object registration, and binding invalidation.

### Fixed

- Removed ambiguities in distributed-output runtime dispatch when temporal
streams are absent and output retention is either absent or compiled.
- Construct dynamic `Status` values directly from the final ordered payload,
preserving precedence and independent `Ref` storage without the generic
iterable-to-`NamedTuple` merge path.

## v0.14.1

Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ HTTP = "1, 2.0"
InteractiveUtils = "1.10"
JSON = "1.6.1"
Markdown = "1.10"
MultiScaleTreeGraph = "0.15.1"
PlantMeteo = "0.8.2"
MultiScaleTreeGraph = "0.16.0"
PlantMeteo = "0.9.0"
Random = "1.10"
Statistics = "1.10"
Tables = "1"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ A modeler writes generic kernels with:

- `inputs_` declarations using `Required(T)` or `Default(value)`
- `outputs_`
- optional `dep`, `timespec`, `output_policy`, `environment_inputs_`, and
`environment_outputs_` traits
- optional `dep`, `timespec`, `output_policy`, `environment_inputs_`,
`environment_outputs_`, and `variable_contracts_` traits
- `run!(model, status, environment, constants, context)`

A simulation author assembles those kernels on objects with `CompositeModel`,
Expand Down
1,101 changes: 0 additions & 1,101 deletions TEMP_IMMUTABLE_SCENARIO_PERFORMANCE_GOAL.md

This file was deleted.

222 changes: 222 additions & 0 deletions benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,55 @@ end setup = (status = PlantSimEngine.Status(value=0.0))
if SUPPORTS_COMPOSITE_OBJECT_BENCHMARKS
# Composite-model benchmarks cannot be constructed while AirspeedVelocity
# evaluates this script against a pre-CompositeModel baseline revision.
include(joinpath(@__DIR__, "test-status-registry-benchmark.jl"))
for nobjects in (32, 256, 1_024)
SUITE[suite_name]["PSE_status_registry_lookup_$(nobjects)"] =
@benchmarkable benchmark_status_registry_lookup(
data.model,
data.lookup_status,
) setup = (data = setup_status_registry_benchmark($nobjects))
SUITE[suite_name]["PSE_status_registry_sweep_$(nobjects)"] =
@benchmarkable benchmark_status_registry_sweep_checksum(
data.model,
data.statuses,
) setup = (data = setup_status_registry_benchmark($nobjects))
end

include(joinpath(@__DIR__, "test-organ-lifecycle-benchmark.jl"))
for nobjects in (32, 256, 1_024)
SUITE[suite_name]["PSE_organ_adaptation_$(nobjects)"] =
@benchmarkable benchmark_adapt_organ_model(
topology,
) setup = (topology = setup_organ_topology_benchmark(
$nobjects,
)) evals = 1
SUITE[suite_name]["PSE_organ_add_$(nobjects)"] =
@benchmarkable benchmark_add_organ!(
data,
) setup = (data = setup_organ_lifecycle_benchmark(
$nobjects,
)) evals = 1
SUITE[suite_name]["PSE_organ_refresh_$(nobjects)"] =
@benchmarkable benchmark_refresh_after_add!(
data,
) setup = (data = setup_organ_refresh_benchmark(
$nobjects,
)) evals = 1
SUITE[suite_name]["PSE_organ_add_refresh_$(nobjects)"] =
@benchmarkable benchmark_add_and_refresh!(
data,
) setup = (data = setup_organ_lifecycle_benchmark(
$nobjects,
)) evals = 1
SUITE[suite_name]["PSE_organ_add_continue_$(nobjects)"] =
@benchmarkable benchmark_add_and_continue!(
data,
) setup = (data = setup_organ_lifecycle_benchmark(
$nobjects;
start_simulation=true,
)) evals = 1
end

include(joinpath(@__DIR__, "test-PSE-benchmark.jl"))
SUITE[suite_name]["PSE"] = @benchmarkable benchmark_heavier_scene(
model,
Expand Down Expand Up @@ -82,6 +131,179 @@ if SUPPORTS_COMPOSITE_OBJECT_BENCHMARKS
) setup = ((simulation, nsteps) =
setup_many_cadence_schedule_benchmark()) evals = 1

include(joinpath(@__DIR__, "test-distributed-output-benchmark.jl"))
for nobjects in (1_000, 100_000)
SUITE[suite_name]["PSE_refvector_sum_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_sum(
values,
) setup = (values = setup_distributed_output_benchmark(
$nobjects,
).ref_values)
SUITE[suite_name]["PSE_bound_many_sum_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_sum(
values,
) setup = (values = setup_distributed_output_benchmark(
$nobjects,
).bound_values)
SUITE[suite_name]["PSE_objectref_sum_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_sum(
values,
) setup = (values = setup_distributed_output_benchmark(
$nobjects,
).heterogeneous_values)
SUITE[suite_name]["PSE_bound_objectref_sum_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_sum(
values,
) setup = (values = setup_distributed_output_benchmark(
$nobjects,
).bound_heterogeneous_values)
end
for nobjects in (10, 1_000, 10_000, 100_000)
SUITE[suite_name]["PSE_distributed_assign_exact_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_outputs_exact!(
data.exact_targets,
data.exact_values,
) setup = (data = setup_distributed_output_benchmark($nobjects))
SUITE[suite_name]["PSE_distributed_assign_permuted_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_outputs_permuted!(
data.permuted_targets,
data.permuted_values,
data.result_to_destination,
) setup = (data = setup_distributed_output_benchmark($nobjects))
end
for nobjects in (10, 1_000, 10_000)
SUITE[suite_name]["PSE_distributed_assign_status_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_outputs_statuses_exact!(
data.statuses,
data.exact_values,
) setup = (data = setup_distributed_output_benchmark($nobjects))
SUITE[suite_name]["PSE_distributed_assign_broadcast_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_outputs_broadcast!(
data.status_targets,
data.exact_values,
) setup = (data = setup_distributed_output_benchmark($nobjects))
SUITE[suite_name]["PSE_distributed_assign_columns_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_output_columns_exact!(
data.column_targets,
data.column_values,
) setup = (data = setup_distributed_output_benchmark($nobjects))
SUITE[suite_name]["PSE_distributed_assign_sparse_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_outputs_permuted!(
data.sparse_targets,
data.sparse_values,
data.sparse_result_to_destination,
) setup = (data = setup_distributed_output_benchmark($nobjects))
SUITE[suite_name]["PSE_distributed_assign_heterogeneous_$(nobjects)"] =
@benchmarkable benchmark_assign_distributed_outputs_exact!(
data.heterogeneous_targets,
data.exact_values,
) setup = (data = setup_distributed_output_benchmark($nobjects))
SUITE[suite_name]["PSE_distributed_mapping_refresh_$(nobjects)"] =
@benchmarkable benchmark_refresh_distributed_output_assignment_mapping(
destination_ids,
result_ids,
) setup = ((destination_ids, result_ids) =
setup_distributed_output_mapping_refresh_benchmark($nobjects))
SUITE[suite_name]["PSE_assign_outputs_control_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_public_assignment_step(
simulation,
) setup = (simulation =
setup_distributed_output_assignment_control_benchmark(
$nobjects,
)) evals = 1
end
if isdefined(PlantSimEngine, :output_targets) &&
isdefined(PlantSimEngine, :assign_outputs!)
for nobjects in (10, 1_000, 10_000), order in (:exact, :permuted)
assignment_paths = order === :exact ?
(:table, :columns, :ref_loop, :broadcast) :
(:table, :columns)
for path in assignment_paths
SUITE[suite_name]["PSE_assign_outputs_$(path)_$(order)_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_public_assignment_step(
simulation,
) setup = (simulation =
setup_distributed_output_public_assignment_benchmark(
$nobjects;
order=$order,
path=$path,
)) evals = 1
end
end
for nobjects in (10, 1_000, 10_000), order in (:exact, :permuted)
assignment_paths = order === :exact ?
(:table, :columns, :ref_loop) :
(:table, :columns)
for path in assignment_paths
SUITE[suite_name]["PSE_assign_outputs_$(path)_2columns_$(order)_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_public_assignment_step(
simulation,
) setup = (simulation =
setup_distributed_output_public_assignment_benchmark(
$nobjects;
order=$order,
path=$path,
ncolumns=2,
)) evals = 1
end
end
for nobjects in (10, 1_000, 10_000), path in (:columns, :ref_loop)
SUITE[suite_name]["PSE_assign_outputs_$(path)_heterogeneous_exact_$(nobjects)"] =
@benchmarkable benchmark_distributed_output_public_assignment_step(
simulation,
) setup = (simulation =
setup_distributed_output_public_assignment_benchmark(
$nobjects;
order=:exact,
path=$path,
heterogeneous=true,
)) evals = 1
end
for ncolumns in (7, 19)
SUITE[suite_name]["PSE_assign_outputs_columns_$(ncolumns)columns_exact_1000"] =
@benchmarkable benchmark_distributed_output_public_assignment_step(
simulation,
) setup = (simulation =
setup_distributed_output_wide_assignment_benchmark(
1_000;
ncolumns=$ncolumns,
)) evals = 1
end
end
SUITE[suite_name]["PSE_distributed_compile_permutation_1000"] =
@benchmarkable compile_distributed_output_benchmark_permutation(
data.object_ids,
data.permuted_result_ids,
) setup = (data = setup_distributed_output_benchmark(1_000))
for distributed in (false, true)
compile_kind = distributed ? "active" : "none"
SUITE[suite_name]["PSE_distributed_compile_$(compile_kind)_1000"] =
@benchmarkable benchmark_compile_distributed_output_model(
model,
) setup = (model = setup_distributed_output_compilation_benchmark(
1_000;
distributed=$distributed,
)) evals = 1
end
SUITE[suite_name]["PSE_distributed_lifecycle_add_1000"] =
@benchmarkable benchmark_refresh_distributed_output_lifecycle!(
model,
new_index,
) setup = ((model, new_index) =
setup_distributed_output_lifecycle_benchmark(1_000)) evals = 1
for identity_aware in (false, true)
input_kind = identity_aware ? "bound" : "status"
SUITE[suite_name]["PSE_$(input_kind)_many_input_steps_1000"] =
@benchmarkable benchmark_distributed_output_input_steps(
simulation,
nsteps,
) setup = ((simulation, nsteps) =
setup_distributed_output_input_step_benchmark(
1_000;
identity_aware=$identity_aware,
)) evals = 1
end

include(joinpath(@__DIR__, "test-hard-call-path-benchmark.jl"))
for usage in (:zero, :sparse, :dense)
SUITE[suite_name]["PSE_hard_calls_$(usage)"] =
Expand Down
Loading
Loading