Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
236 commits
Select commit Hold shift + click to select a range
1b7f288
Update README.md
VEZY Mar 18, 2026
e7c861c
Merge branch 'main' into multi-plants
VEZY May 3, 2026
75954d1
Add domain simulations with hard-domain targets and microclimate support
VEZY Jun 3, 2026
62b7878
Update docstrings and doc
VEZY Jun 3, 2026
2e274c3
Remove backward compatibility
VEZY Jun 3, 2026
236534e
Another large cleanup
VEZY Jun 4, 2026
06c909d
Use true PlantBiophysics models in the examples
VEZY Jun 4, 2026
287187c
Use two layers for the soil in maespa example
VEZY Jun 4, 2026
38eef0b
Update maespa_domain_example.jl
VEZY Jun 4, 2026
ef8d5d1
MAESPA example: make the model a bit more process-based + scene LAI a…
VEZY Jun 4, 2026
6f7663e
Auto-detect mapped variables between domains (not required in the use…
VEZY Jun 4, 2026
89f0971
Update maespa_domain_example.jl
VEZY Jun 4, 2026
26df6a5
Split Route types and route materialization into different scripts
VEZY Jun 4, 2026
82d881c
Remove all references to ModelList
VEZY Jun 5, 2026
b377c9c
Starting implementing the new scene API
VEZY Jun 5, 2026
c460928
Add producer application metadata and selector validation in Inputs.
VEZY Jun 6, 2026
0b4e5f4
Better error catching for Inputs
VEZY Jun 6, 2026
df679dc
Implements default scope inference for compiled scene/object dependen…
VEZY Jun 6, 2026
07e958a
Implements the remaining "Phase 5" mechanics
VEZY Jun 6, 2026
42106a3
Implements the goal of multi-plants and spatial (mutable) microclimate
VEZY Jun 13, 2026
6f52c7e
Remove Domain, SimulationMapping, Route, AllDomains, HardDomains, and…
VEZY Jun 13, 2026
4286cf1
First end-to-end implementation of the new API
VEZY Jun 18, 2026
21a1cd6
Add `add_organ!` again for an easier high-level function
VEZY Jun 18, 2026
2144f5e
Adapt past tests and doc to the new API
VEZY Jun 19, 2026
f168992
Adapt the graph editor to the new API
VEZY Jun 20, 2026
9c3ffad
Simplify examples in docs -> use defaults when possible
VEZY Jun 20, 2026
b8fde7d
Harden a bit more the API
VEZY Jun 20, 2026
26250d0
Fix benchmarks
VEZY Jun 21, 2026
8a3c52b
Delete runtests.jl
VEZY Jun 21, 2026
e8a0cc9
Simplify examples in docs -> use ModelList equivalent whenever possible
VEZY Jun 22, 2026
4e17d3b
Rename Scene into CompositeModel
VEZY Jun 22, 2026
18705b8
Remove `call_target` and only use `call_targets` so we always expect …
VEZY Jun 25, 2026
69b80cb
Avoiding manual updates of statuses in Maespa
VEZY Jun 25, 2026
846e31b
Make variables use mapping instead of being called by their their sta…
VEZY Jun 25, 2026
2584e21
Add and use `with_environment!`
VEZY Jul 28, 2026
583559d
Stabilize CompositeModel runtime contracts
VEZY Jul 29, 2026
7e38354
Support explicit live status bindings
VEZY Jul 29, 2026
ce1bb0a
docs: add API and performance implementation goal
VEZY Jul 29, 2026
d3828d4
perf: add runtime metrics and incremental execution paths
VEZY Jul 29, 2026
7348cb5
fix: handle empty execution plans in runtime metrics
VEZY Jul 29, 2026
aefba2e
fix: execute staged performance benchmark callbacks
VEZY Jul 29, 2026
710da45
perf: warm and persist short XPalm profiles
VEZY Jul 29, 2026
4875ab3
perf: refresh execution plans by application delta
VEZY Jul 29, 2026
195a346
perf: preserve call bindings and streamline hot loops
VEZY Jul 29, 2026
aacbd25
perf: bound temporal dependency storage
VEZY Jul 29, 2026
844646d
perf: compile direct temporal source cells
VEZY Jul 29, 2026
b82c79a
perf: reuse scheduled run contexts
VEZY Jul 29, 2026
c1b8cc2
perf: precompile dependency output cells
VEZY Jul 29, 2026
ed08dd8
docs: record performance restoration progress
VEZY Jul 29, 2026
5964566
perf: index meteorology rows directly
VEZY Jul 29, 2026
4bf7575
perf: reuse current environment bindings
VEZY Jul 29, 2026
bb619c4
perf: defer targeted lifecycle call refreshes
VEZY Jul 29, 2026
70b0100
perf: persist lifecycle dependency deltas
VEZY Jul 29, 2026
96d9ed5
perf: compile XPalm full cycle under gate
VEZY Jul 29, 2026
52ab05c
fix: preserve lifecycle application completion
VEZY Jul 29, 2026
ea1b11a
docs: record corrected XPalm milestone
VEZY Jul 29, 2026
274666b
perf: cache compiled hard-call targets
VEZY Jul 29, 2026
b995f5f
docs: record hard-call cache milestone
VEZY Jul 29, 2026
9a00104
fix: preserve typed call environment overrides
VEZY Jul 29, 2026
5776044
perf: accumulate subtree selectors in place
VEZY Jul 29, 2026
43f08bd
perf: preallocate lifecycle input bindings
VEZY Jul 29, 2026
08b7132
perf: cache object ancestor paths
VEZY Jul 29, 2026
d60bac4
perf: synchronize hard-call views lazily
VEZY Jul 29, 2026
f7a7e12
docs: record XPalm lifecycle performance milestone
VEZY Jul 29, 2026
ebf76bc
perf: avoid full-scene lifecycle copies
VEZY Jul 29, 2026
95ec6ee
perf: cache dirty-topology call compilation
VEZY Jul 29, 2026
510e2d2
perf: update lifecycle indexes in place
VEZY Jul 29, 2026
e14c82d
perf: avoid routine status-view index copies
VEZY Jul 29, 2026
64ef6a6
perf: index lifecycle call-bundle propagation
VEZY Jul 29, 2026
19802a0
docs: record sub-ten-second XPalm milestone
VEZY Jul 29, 2026
3ad16d2
api: adopt five-argument model kernels
VEZY Jul 29, 2026
5db2f67
perf: remove obsolete model bundle cache
VEZY Jul 29, 2026
b7e5665
api: unify model environment vocabulary
VEZY Jul 29, 2026
1aa794f
docs: record downstream kernel migration
VEZY Jul 29, 2026
757649e
api: distinguish required inputs from defaults
VEZY Jul 30, 2026
143f07d
docs: explain explicit input initialization
VEZY Jul 30, 2026
03e0a5f
perf: keep input schema validation allocation free
VEZY Jul 30, 2026
5a2a2a4
docs: complete explicit input schema milestone
VEZY Jul 30, 2026
e00febd
api: collapse model specs onto direct keywords
VEZY Jul 30, 2026
2fcc3b1
docs: complete direct scenario configuration milestone
VEZY Jul 30, 2026
75a00b8
api: make selector criteria context aware
VEZY Jul 30, 2026
f22eddf
docs: complete selector API milestone
VEZY Jul 30, 2026
ef464b3
api: split focused public namespaces
VEZY Jul 30, 2026
98aa790
docs: complete public namespace milestone
VEZY Jul 30, 2026
e48cc3a
api: improve simulation result ergonomics
VEZY Jul 30, 2026
a794876
test: cover multi-object final state
VEZY Jul 30, 2026
9057c96
docs: complete simulation results milestone
VEZY Jul 30, 2026
11e1a86
api: remove compatibility aliases
VEZY Jul 30, 2026
781a744
perf: make benchmark evidence reproducible
VEZY Jul 30, 2026
9d6bcac
perf: complete runtime benchmark matrix
VEZY Jul 30, 2026
f5be409
docs: harden reusable example contracts
VEZY Jul 30, 2026
5e9a489
docs: add progressive start-here journey
VEZY Jul 30, 2026
cb6bac4
docs: add one-plant composition journey
VEZY Jul 30, 2026
54a6651
docs: add template and instance journey
VEZY Jul 30, 2026
68ad6b4
docs: add global and spatial environment journey
VEZY Jul 30, 2026
5bca336
docs: add multirate cadence journey
VEZY Jul 30, 2026
1269252
docs: add structural lifecycle journey
VEZY Jul 30, 2026
dfcbbb8
docs: add mutable environment journey
VEZY Jul 30, 2026
f9c84ae
docs: add advanced execution journey
VEZY Jul 30, 2026
e23fd1b
docs: add MAESPA synthesis journey
VEZY Jul 30, 2026
53c1c6d
docs: add progressive model-author journey
VEZY Jul 30, 2026
41ddaae
docs: enforce progressive journey contracts
VEZY Jul 30, 2026
29882d1
perf: make structural lifecycle refresh incremental
VEZY Jul 30, 2026
5e2e31a
ci: persist full XPalm performance runs
VEZY Jul 30, 2026
5187f80
fix: prefer scheduled output publishers
VEZY Jul 30, 2026
8b4068a
fix: preserve private output coupling
VEZY Jul 30, 2026
32d2189
docs: record final local validation matrix
VEZY Jul 30, 2026
346e616
perf: make structural lifecycle refresh delta-based
VEZY Jul 30, 2026
b0ee8e3
docs: record lifecycle performance restoration
VEZY Jul 30, 2026
a71f891
docs: fix whitespace validation
VEZY Jul 30, 2026
b9f399c
ci: repair benchmark workflow environments
VEZY Jul 30, 2026
0146646
ci: bootstrap full performance dispatch
VEZY Jul 30, 2026
d13d427
ci: prepare path-based performance environment
VEZY Jul 30, 2026
c73a7d2
ci: qualify benchmark object fixtures
VEZY Jul 30, 2026
f4d1bfa
ci: support legacy benchmark baselines
VEZY Jul 30, 2026
a715e2b
ci: pin PlantGeom for full performance runs
VEZY Jul 31, 2026
6abda6e
docs: record completed downstream performance gate
VEZY Jul 31, 2026
4dc257b
Merge origin/main into multi-plants
VEZY Jul 31, 2026
fc02a0a
fix: qualify graph editor E2E entry point
VEZY Jul 31, 2026
5c7e980
test: initialize Beer in graph editor E2E
VEZY Jul 31, 2026
87fb97c
fix: stabilize merged release validation
VEZY Jul 31, 2026
df0f074
fix: include environment ports in graph layout
VEZY Jul 31, 2026
adcaf83
fix: serialize empty graph ports as arrays
VEZY Jul 31, 2026
485f61d
fix: match parametric models in graph editor
VEZY Jul 31, 2026
e36ad62
test: target graph editor timestep controls
VEZY Jul 31, 2026
b0f335c
test: scope graph cycle edges by projection
VEZY Jul 31, 2026
71972fc
fix: serialize graph update rules as arrays
VEZY Jul 31, 2026
809094f
test: scope graph editor save action
VEZY Jul 31, 2026
375fdef
fix: stabilize Julia 1.10 validation
VEZY Jul 31, 2026
6f5543a
perf: specialize input schema validation
VEZY Jul 31, 2026
9830993
test: account for Julia 1.10 allocation floor
VEZY Jul 31, 2026
3b1cfc2
Update SKILL.md
VEZY Aug 6, 2026
16822f2
Merge branch 'main' into multi-plants
VEZY Aug 6, 2026
d9edff7
Add `model_object` for AMAPSim
VEZY Aug 10, 2026
8dd351c
Modernize graph editor model schema
VEZY Aug 10, 2026
38768d1
Add graph editor runtime catalogs
VEZY Aug 10, 2026
6e81a95
Build template and environment editor workflows
VEZY Aug 10, 2026
9bf8f8e
Document and exercise graph editor v2
VEZY Aug 10, 2026
aa2b241
Fix graph editor validation regressions
VEZY Aug 11, 2026
5437ed3
Sync model_object public API contract
VEZY Aug 11, 2026
b03502e
Fix GraphEditor extension dependency loading
VEZY Aug 11, 2026
c1340dc
Add realistic PlantBiophysics performance harness
VEZY Aug 11, 2026
695bc2c
Compile hard calls into typed execution batches
VEZY Aug 11, 2026
f3d2974
Add allocation-free hard-call fast APIs
VEZY Aug 11, 2026
e260458
Optimize previous-timestep input materialization
VEZY Aug 11, 2026
b5518fb
Document and automate downstream performance gates
VEZY Aug 11, 2026
d5480c5
Handle absent previous-step source streams
VEZY Aug 11, 2026
b0d70df
Record hard-call validation progress
VEZY Aug 11, 2026
1635a3d
Honor XPalm release benchmark sample count
VEZY Aug 11, 2026
a072803
Record downstream performance acceptance
VEZY Aug 11, 2026
355e143
Remove completed hard-call performance goal
VEZY Aug 11, 2026
eb87938
Add immutable scenario performance goal
VEZY Aug 11, 2026
4e9bbf6
Benchmark immutable scenario steady state
VEZY Aug 11, 2026
2fadc38
Skip unchanged output target refreshes
VEZY Aug 11, 2026
d07f75d
Use one runtime mutation revision
VEZY Aug 11, 2026
b871865
Track output request membership intervals
VEZY Aug 11, 2026
eb1d5da
Separate immutable application plans from targets
VEZY Aug 11, 2026
4ebdfc3
Compile immutable input and call plans
VEZY Aug 11, 2026
54d3bf8
Clarify lifecycle storage growth invariant
VEZY Aug 11, 2026
a94e3ab
Compile static scenario dependency graph
VEZY Aug 11, 2026
d94a999
Dispatch only due multirate applications
VEZY Aug 12, 2026
9a2544f
Journal shared lifecycle deltas
VEZY Aug 12, 2026
fa2821e
Compile selectors for lifecycle refresh
VEZY Aug 12, 2026
a63d835
Compile direct output publication sinks
VEZY Aug 12, 2026
21e0057
Compile immutable environment plans
VEZY Aug 12, 2026
eec09e3
Record dense slot evaluation
VEZY Aug 12, 2026
bda5ab8
Document immutable runtime phases
VEZY Aug 12, 2026
962afc2
Keep compiled runtime shell reference-backed
VEZY Aug 12, 2026
b0617ba
Avoid boxing immutable runtime plans
VEZY Aug 12, 2026
8fdc05e
Record immutable scenario performance acceptance
VEZY Aug 12, 2026
9a4ba77
Fix graph editor E2E teardown
VEZY Aug 12, 2026
676be76
Fix Julia 1.10 allocation regressions
VEZY Aug 12, 2026
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
771894c
Merge pull request #209 from VirtualPlantLab/distributed-output-targets
VEZY Aug 30, 2026
afc1b3e
Optimize dynamic organ lifecycle refresh
VEZY Aug 31, 2026
f521b8d
perf: accelerate dynamic organ lifecycle
VEZY Aug 31, 2026
492c521
perf: append stable many input sources in place
VEZY Aug 31, 2026
ce06cf2
perf: cache lifecycle targets and runtime contexts
VEZY Aug 31, 2026
d9ac84c
perf: reuse planned singleton input producers
VEZY Sep 1, 2026
503f7a7
perf: specialize uninstrumented execution groups
VEZY Sep 1, 2026
2dcedda
perf: index observed manual call owners
VEZY Sep 1, 2026
b053534
perf: index manual calls by exact callee target
VEZY Sep 1, 2026
ff1d0fb
Merge pull request #212 from VirtualPlantLab/codex/multi-plants-perfo…
VEZY Sep 1, 2026
82786fb
feat: improve model authoring for agents
VEZY Sep 1, 2026
a2ce183
fix: resolve parametric models in graph editor
VEZY Sep 2, 2026
8c24ac7
Update CHANGELOG.md
VEZY Sep 2, 2026
c664522
ci: test downstreams from local sources
VEZY Sep 3, 2026
0379891
Update Integration.yml
VEZY Sep 3, 2026
ba28b64
fix: preserve runtime snapshots and validate time configuration
VEZY Sep 5, 2026
7d5ffb3
fix: validate model kernels and compare output policies consistently
VEZY Sep 5, 2026
ac5c733
docs: clarify multirate integration and model authoring workflows
VEZY Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Generated bundles may preserve whitespace inside dependency template literals.
frontend/dist/assets/*.js -whitespace
100 changes: 100 additions & 0 deletions .github/scripts/configure_local_sources.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
module IntegrationSourceConfig

using TOML

export configure_local_sources!

const DIRECT_DEPENDENCY_SECTIONS = ("deps", "extras")

function _source_identity(source_root::AbstractString)
source_path = realpath(source_root)
project_file = joinpath(source_path, "Project.toml")
isfile(project_file) || error("Missing source project: $(project_file)")

project = TOML.parsefile(project_file)
name = get(project, "name", nothing)
uuid = get(project, "uuid", nothing)
name isa AbstractString || error("Missing package name in $(project_file)")
uuid isa AbstractString || error("Missing package UUID in $(project_file)")

return (; name=String(name), uuid=String(uuid), path=source_path)
end

function _declared_uuid(project, package_name::AbstractString)
declared_uuid = nothing
for section_name in DIRECT_DEPENDENCY_SECTIONS
section = get(project, section_name, nothing)
section isa AbstractDict || continue
haskey(section, package_name) || continue

uuid = String(section[package_name])
if declared_uuid !== nothing && declared_uuid != uuid
error("Conflicting UUIDs for $(package_name) in [deps] and [extras]")
end
declared_uuid = uuid
end
return declared_uuid
end

function _configured_project(project_file::AbstractString, source_identities)
project_path = realpath(project_file)
project = TOML.parsefile(project_path)
sources = get!(project, "sources", Dict{String,Any}())
matched = String[]
changed = String[]

for source in source_identities
declared_uuid = _declared_uuid(project, source.name)
declared_uuid === nothing && continue
declared_uuid == source.uuid || error(
"UUID mismatch for $(source.name) in $(project_path): " *
"expected $(source.uuid), found $(declared_uuid)",
)

push!(matched, source.name)
local_source = Dict{String,Any}("path" => source.path)
get(sources, source.name, nothing) == local_source && continue
sources[source.name] = local_source
push!(changed, source.name)
end

return (; path=project_path, contents=project, matched, changed)
end

"""
configure_local_sources!(project_files, source_roots)

Replace URL/revision source entries with absolute paths to exact local package
checkouts. A source is changed only when the target project declares the same
package UUID in `[deps]` or `[extras]`; weak dependencies are intentionally not
modified. Every requested source must match at least one target project.
"""
function configure_local_sources!(project_files, source_roots)
source_identities = map(_source_identity, source_roots)
source_names = getproperty.(source_identities, :name)
allunique(source_names) || error("Each local source package must be unique")

configured_projects = map(project_files) do project_file
isfile(project_file) || error("Missing target project: $(abspath(project_file))")
_configured_project(project_file, source_identities)
end

for source_name in source_names
any(source_name in project.matched for project in configured_projects) || error(
"Local source $(source_name) is not a direct dependency of any target project",
)
end

for project in configured_projects
isempty(project.changed) && continue
open(project.path, "w") do io
TOML.print(io, project.contents; sorted=true)
end
end

return map(configured_projects) do project
(; project=project.path, matched=project.matched, changed=project.changed)
end
end

end
155 changes: 155 additions & 0 deletions .github/scripts/test_configure_local_sources.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
using Test
using TOML

include(joinpath(@__DIR__, "configure_local_sources.jl"))

function write_project(path, project)
mkpath(dirname(path))
open(path, "w") do io
TOML.print(io, project; sorted=true)
end
end

function source_project(root, name, uuid)
write_project(
joinpath(root, "Project.toml"),
Dict{String,Any}("name" => name, "uuid" => uuid, "version" => "1.0.0"),
)
end

@testset "Configure local integration sources" begin
mktempdir() do tmp
pse_uuid = "9a576370-710b-4269-adf9-4f603a9c6423"
plantgeom_uuid = "5edaa67e-25db-4eb9-bf81-05d793b2238d"
xpalm_uuid = "6b523e1e-d512-416c-8e51-a8fbef0064e7"

pse_root = joinpath(tmp, "PlantSimEngine")
plantgeom_root = joinpath(tmp, "PlantGeom")
source_project(pse_root, "PlantSimEngine", pse_uuid)
source_project(plantgeom_root, "PlantGeom", plantgeom_uuid)

xpalm_root = joinpath(tmp, "XPalm")
root_project = joinpath(xpalm_root, "Project.toml")
test_project = joinpath(xpalm_root, "test", "Project.toml")
write_project(
root_project,
Dict{String,Any}(
"name" => "XPalm",
"uuid" => xpalm_uuid,
"deps" => Dict(
"PlantSimEngine" => pse_uuid,
"PlantGeom" => plantgeom_uuid,
),
"sources" => Dict(
"PlantSimEngine" => Dict("url" => "https://example.test/pse", "rev" => "old"),
"PlantGeom" => Dict("url" => "https://example.test/plantgeom", "rev" => "old"),
"Unrelated" => Dict("path" => "../Unrelated"),
),
),
)
write_project(
test_project,
Dict{String,Any}(
"deps" => Dict(
"XPalm" => xpalm_uuid,
"PlantSimEngine" => pse_uuid,
"PlantGeom" => plantgeom_uuid,
),
"sources" => Dict(
"XPalm" => Dict("path" => ".."),
"PlantSimEngine" => Dict("url" => "https://example.test/pse", "rev" => "old"),
"PlantGeom" => Dict("url" => "https://example.test/plantgeom", "rev" => "old"),
),
),
)

summaries = IntegrationSourceConfig.configure_local_sources!(
(root_project, test_project),
(pse_root, plantgeom_root),
)
@test all(summary.changed == ["PlantSimEngine", "PlantGeom"] for summary in summaries)

configured_root = TOML.parsefile(root_project)
configured_test = TOML.parsefile(test_project)
@test configured_root["sources"]["PlantSimEngine"] == Dict("path" => realpath(pse_root))
@test configured_root["sources"]["PlantGeom"] == Dict("path" => realpath(plantgeom_root))
@test configured_root["sources"]["Unrelated"] == Dict("path" => "../Unrelated")
@test configured_test["sources"]["XPalm"] == Dict("path" => "..")

repeated = IntegrationSourceConfig.configure_local_sources!(
(root_project, test_project),
(pse_root, plantgeom_root),
)
@test all(isempty(summary.changed) for summary in repeated)

weakdep_root = joinpath(plantgeom_root, "Project.toml")
weakdep_test = joinpath(plantgeom_root, "test", "Project.toml")
write_project(
weakdep_root,
Dict{String,Any}(
"name" => "PlantGeom",
"uuid" => plantgeom_uuid,
"weakdeps" => Dict("PlantSimEngine" => pse_uuid),
),
)
write_project(
weakdep_test,
Dict{String,Any}(
"deps" => Dict(
"PlantGeom" => plantgeom_uuid,
"PlantSimEngine" => pse_uuid,
),
"sources" => Dict("PlantGeom" => Dict("path" => "..")),
),
)

weakdep_summaries = IntegrationSourceConfig.configure_local_sources!(
(weakdep_root, weakdep_test),
(pse_root,),
)
@test isempty(weakdep_summaries[1].matched)
@test weakdep_summaries[2].changed == ["PlantSimEngine"]
@test !haskey(TOML.parsefile(weakdep_root), "sources")
@test TOML.parsefile(weakdep_test)["sources"]["PlantSimEngine"] ==
Dict("path" => realpath(pse_root))

extras_project = joinpath(tmp, "Extras", "Project.toml")
write_project(
extras_project,
Dict{String,Any}("extras" => Dict("PlantSimEngine" => pse_uuid)),
)
extras_summary = only(IntegrationSourceConfig.configure_local_sources!(
(extras_project,),
(pse_root,),
))
@test extras_summary.changed == ["PlantSimEngine"]
@test TOML.parsefile(extras_project)["sources"]["PlantSimEngine"] ==
Dict("path" => realpath(pse_root))

mismatched_project = joinpath(tmp, "Mismatch", "Project.toml")
write_project(
mismatched_project,
Dict{String,Any}(
"deps" => Dict("PlantSimEngine" => "00000000-0000-0000-0000-000000000000"),
),
)
transaction_project = joinpath(tmp, "Transaction", "Project.toml")
write_project(
transaction_project,
Dict{String,Any}(
"deps" => Dict("PlantSimEngine" => pse_uuid),
"sources" => Dict(
"PlantSimEngine" => Dict("url" => "https://example.test/pse", "rev" => "old"),
),
),
)
@test_throws ErrorException IntegrationSourceConfig.configure_local_sources!(
(transaction_project, mismatched_project),
(pse_root,),
)
@test haskey(
TOML.parsefile(transaction_project)["sources"]["PlantSimEngine"],
"url",
)
end
end
92 changes: 89 additions & 3 deletions .github/workflows/Benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,109 @@ on:
pull_request_target:
branches: [ main ]
workflow_dispatch:
inputs:
full_performance:
description: Run the complete downstream performance workflow
required: false
default: false
type: boolean
permissions:
pull-requests: write
contents: read
jobs:
bench:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}
if: ${{ github.event_name != 'workflow_dispatch' || !inputs.full_performance }}
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{
github.event_name }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
env:
PSE_BENCHMARK_INCLUDE_DOWNSTREAM: "false"
strategy:
fail-fast: false
matrix:
version:
- "1"
- "1.12.1"
os:
- ubuntu-latest
arch:
- x64
steps:
- uses: MilesCranmer/AirspeedVelocity.jl@action-v1
with:
julia-version: ${{ matrix.version }}
bench-on: ${{ github.event.pull_request.head.sha }}
extra-pkgs: https://github.com/PalmStudio/XPalm.jl,https://github.com/VEZY/PlantBiophysics.jl

plantbiophysics:
if: ${{ github.event_name != 'workflow_dispatch' || !inputs.full_performance }}
name: PlantBiophysics multi-timestep
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
env:
JULIA_NUM_THREADS: "1"
JULIA_PKG_PRECOMPILE_AUTO: "0"
PSE_PLANTBIOPHYSICS_BENCHMARK_STEPS: "1000"
PSE_PLANTBIOPHYSICS_BENCHMARK_SAMPLES: "5"
PSE_PLANTBIOPHYSICS_FANOUT_SCENES: "20"
steps:
- name: Check out PlantSimEngine
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- name: Check out PlantBiophysics
uses: actions/checkout@v7
with:
repository: VEZY/PlantBiophysics.jl
ref: multi-plant
path: downstream/PlantBiophysics

- name: Set up Julia
uses: julia-actions/setup-julia@v3
with:
version: "1.12.1"

- name: Cache Julia packages
uses: julia-actions/cache@v3

- name: Resolve the PlantBiophysics benchmark environment
shell: julia --project=benchmark --color=yes {0}
run: |
using Pkg

benchmark_project = joinpath(pwd(), "benchmark", "Project.toml")
include(joinpath(pwd(), "benchmark", "prepare_full_performance_project.jl"))
prepare_plantbiophysics_performance_project!(benchmark_project)
Pkg.activate(joinpath(pwd(), "benchmark"))
Pkg.develop([
PackageSpec(path=pwd()),
PackageSpec(path=joinpath(pwd(), "downstream", "PlantBiophysics")),
])
Pkg.resolve()
Pkg.instantiate()
Pkg.precompile()

- name: Run the warmed multi-timestep benchmark
run: >-
julia --project=benchmark --color=yes
benchmark/test/runtests.jl
"PlantBiophysics benchmark (API smoke|performance)"

- name: Persist measurements
if: always()
uses: actions/upload-artifact@v7
with:
name: plantbiophysics-performance-${{ github.run_id }}-${{ github.run_attempt }}
path: benchmark/results/plantbiophysics-full-latest.csv
if-no-files-found: warn
retention-days: 30

full-performance:
if: ${{ github.event_name == 'workflow_dispatch' && inputs.full_performance }}
uses: ./.github/workflows/FullPerformance.yml
with:
xpalm_ref: codex/xpalm-release-regression
plantbiophysics_ref: multi-plant
plantgeom_ref: plantsimengine-multi-plant
Loading
Loading