simjecture 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. conjecture_solver/__init__.py +10 -0
  2. conjecture_solver/__main__.py +4 -0
  3. conjecture_solver/action_handlers.py +459 -0
  4. conjecture_solver/adapters/__init__.py +7 -0
  5. conjecture_solver/adapters/base.py +96 -0
  6. conjecture_solver/adapters/fake.py +155 -0
  7. conjecture_solver/adapters/pic.py +196 -0
  8. conjecture_solver/adapters/warpx.py +1375 -0
  9. conjecture_solver/autonomous_research.py +1071 -0
  10. conjecture_solver/benchmarks/__init__.py +6 -0
  11. conjecture_solver/benchmarks/electrostatic_pic.py +547 -0
  12. conjecture_solver/benchmarks/kinetic_sufficiency.py +318 -0
  13. conjecture_solver/builtin_skills/warpx/SKILL.md +151 -0
  14. conjecture_solver/builtin_skills/warpx/agents/openai.yaml +4 -0
  15. conjecture_solver/builtin_skills/warpx/examples/implicit_em_smoke.py +74 -0
  16. conjecture_solver/builtin_skills/warpx/examples/minimal_smoke.py +54 -0
  17. conjecture_solver/builtin_skills/warpx/examples/openpmd_field_smoke.py +87 -0
  18. conjecture_solver/builtin_skills/warpx/manifest.json +11 -0
  19. conjecture_solver/builtin_skills/warpx/references/2d-xz-commissioning.md +145 -0
  20. conjecture_solver/builtin_skills/warpx/references/cpu-launch-tuning.md +54 -0
  21. conjecture_solver/builtin_skills/warpx/references/diagnostics.md +139 -0
  22. conjecture_solver/builtin_skills/warpx/references/gpu-launch-tuning.md +79 -0
  23. conjecture_solver/builtin_skills/warpx/references/local-cuda-deployment.md +87 -0
  24. conjecture_solver/builtin_skills/warpx/references/numerical-risks.md +32 -0
  25. conjecture_solver/builtin_skills/warpx/references/picmi-interface.md +118 -0
  26. conjecture_solver/builtin_skills/warpx/references/resource-scaling.md +24 -0
  27. conjecture_solver/builtin_skills/warpx/references/time-integration.md +58 -0
  28. conjecture_solver/builtin_skills/warpx/scripts/benchmark_cpu_threads.py +207 -0
  29. conjecture_solver/builtin_skills/warpx/scripts/benchmark_gpu.py +242 -0
  30. conjecture_solver/builtin_skills/warpx/scripts/bootstrap_local_cuda.sh +82 -0
  31. conjecture_solver/builtin_skills/warpx/scripts/probe_local_cuda.py +110 -0
  32. conjecture_solver/builtin_skills/warpx/scripts/reduced_energy_budget.py +195 -0
  33. conjecture_solver/builtin_skills/warpx/scripts/run_local_cuda.sh +39 -0
  34. conjecture_solver/campaign.py +406 -0
  35. conjecture_solver/cli.py +963 -0
  36. conjecture_solver/confirmation.py +287 -0
  37. conjecture_solver/control.py +234 -0
  38. conjecture_solver/deployment.py +874 -0
  39. conjecture_solver/discovery.py +68 -0
  40. conjecture_solver/domains/__init__.py +40 -0
  41. conjecture_solver/domains/base.py +157 -0
  42. conjecture_solver/domains/kinetic_sufficiency.py +521 -0
  43. conjecture_solver/ledger.py +238 -0
  44. conjecture_solver/lifecycle.py +131 -0
  45. conjecture_solver/literature.py +494 -0
  46. conjecture_solver/llm.py +228 -0
  47. conjecture_solver/models.py +279 -0
  48. conjecture_solver/mvp_agent.py +3212 -0
  49. conjecture_solver/mvp_claims.py +1279 -0
  50. conjecture_solver/mvp_control.py +322 -0
  51. conjecture_solver/mvp_guidance.py +172 -0
  52. conjecture_solver/mvp_launch.py +1296 -0
  53. conjecture_solver/mvp_monitor.py +1487 -0
  54. conjecture_solver/mvp_skills.py +538 -0
  55. conjecture_solver/orchestration.py +578 -0
  56. conjecture_solver/outbox.py +526 -0
  57. conjecture_solver/parameters.py +394 -0
  58. conjecture_solver/proposals.py +427 -0
  59. conjecture_solver/research_tools.py +278 -0
  60. conjecture_solver/schema_export.py +246 -0
  61. conjecture_solver/search.py +1047 -0
  62. conjecture_solver/semantics.py +146 -0
  63. conjecture_solver/tui/__init__.py +7 -0
  64. conjecture_solver/tui/app.py +202 -0
  65. conjecture_solver/tui/claim_views.py +213 -0
  66. conjecture_solver/tui/screens.py +1014 -0
  67. conjecture_solver/warpx_analysis.py +184 -0
  68. conjecture_solver/warpx_campaign.py +148 -0
  69. conjecture_solver/warpx_confirmation.py +617 -0
  70. simjecture-0.1.0.dist-info/METADATA +400 -0
  71. simjecture-0.1.0.dist-info/RECORD +75 -0
  72. simjecture-0.1.0.dist-info/WHEEL +4 -0
  73. simjecture-0.1.0.dist-info/entry_points.txt +4 -0
  74. simjecture-0.1.0.dist-info/licenses/LICENSE +202 -0
  75. simjecture-0.1.0.dist-info/licenses/NOTICE +6 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "capability_names": [
3
+ "warpx-cpu-26.07",
4
+ "warpx-cuda-openpmd-26.07"
5
+ ],
6
+ "description": "General guidance for authoring, commissioning, and diagnosing WarpX PICMI simulations",
7
+ "entrypoint": "SKILL.md",
8
+ "name": "warpx",
9
+ "schema_version": "0.1.0",
10
+ "version": "26.07.26"
11
+ }
@@ -0,0 +1,145 @@
1
+ # Cartesian 2D XZ commissioning
2
+
3
+ Read this resource before authoring any two-dimensional Cartesian WarpX run.
4
+ It records instrument semantics and generic validity checks; it does not choose
5
+ an equilibrium, experiment, or conclusion.
6
+
7
+ ## Coordinate contract
8
+
9
+ - Treat `Cartesian2DGrid` vectors as `[x, z]`: `number_of_cells=[Nx,Nz]`,
10
+ `lower_bound=[xmin,zmin]`, and `upper_bound=[xmax,zmax]`. The second physical
11
+ axis is `z`, even though some inherited PICMI signatures and internal WarpX
12
+ controls call their second array entry `y`.
13
+ - Use physical parser variables `x` and `z` in 2D analytic distributions and
14
+ fields. Retain three velocity and vector components `x,y,z`; `y` is the
15
+ ignorable spatial direction, not the second grid coordinate.
16
+ - Never infer the physical location of a feature from an array index alone.
17
+ Obtain coordinate meshes with `mf.mesh("x")` and `mf.mesh("z")`, inspect
18
+ centering and ghost cells for each component, and test the extraction on an
19
+ asymmetric analytic field whose expected axis dependence is known.
20
+ - MultiFab vector directions remain physical component directions `x=0`,
21
+ `y=1`, `z=2`; they are not array-axis numbers. Use the runtime's `Direction`
22
+ enum when available.
23
+ - `MultiFabWrapper.to_numpy()` returns a list, one array per local box, and can
24
+ include guard cells and singleton component dimensions. Do not assume a
25
+ global contiguous array, silently select box zero, or reuse one component's
26
+ slice for another staggered component. Record box bounds, meshes, shapes,
27
+ centering, and the interior slice used by every estimator.
28
+
29
+ ## Preflight the represented object
30
+
31
+ Derive checks from the active claim and emit them in a small JSON summary.
32
+ Evaluate the analytic initialization independently before stepping, then
33
+ confirm the realized WarpX state after initialization. Include the checks that
34
+ can invalidate the proposed observable, such as:
35
+
36
+ - every required zero, reversal, extremum, interface, resonance, or source lies
37
+ strictly inside the intended domain with stated boundary clearance;
38
+ - all required regions exist on both sides of an interior structure;
39
+ - sampled signs and extrema have the intended ordering, rather than merely
40
+ matching a plotted shape;
41
+ - discrete divergence, charge neutrality, current balance, force or pressure
42
+ balance, and boundary compatibility meet prospectively chosen tolerances;
43
+ - component orientation and current/drift signs satisfy the governing
44
+ equations under the chosen coordinate convention;
45
+ - every density is reported in SI units and labeled as electron, ion,
46
+ per-species, or total density. Convert a supplied density in `cm^-3` to
47
+ `m^-3` exactly once by multiplying by `1e6`; do not silently reinterpret its
48
+ population meaning;
49
+ - every parser-function argument is dimensionless where required. Independently
50
+ check the dimensions of every expression and the physical scale represented
51
+ by any normalized coordinate or wave number;
52
+ - every field assigned a periodic boundary has matching values and required
53
+ derivatives on paired faces. A profile with unequal limiting values cannot
54
+ be made periodic merely by moving its transition away from the seam. Select
55
+ a compatible topology or nonperiodic boundary and independently check paired
56
+ faces, interior structures, and applicable integral constraints;
57
+ - the realized species proper velocities reproduce both the sign and magnitude
58
+ of any required current. Evaluate `curl(B)/mu0` under the declared coordinate
59
+ and sign convention and compare it with `sum_s(q_s n_s v_s)`. Remember that
60
+ PICMI analytic momentum expressions are `gamma*v`, not `m*gamma*v`. First
61
+ derive the physical drift `v` required by the represented state and reject it
62
+ if `abs(v) >= c`; only then convert it to proper velocity `gamma*v` for a
63
+ relativistic distribution;
64
+ - pressure or force balance sums the pressure of every represented species.
65
+ Do not use a one-species pressure coefficient for a pair or electron-ion
66
+ population without showing why;
67
+ - temperature, energy, velocity, and field conversions are dimensionally
68
+ checked and preserved as metrics. Do not divide a temperature in kelvin by
69
+ elementary charge and label the result electron-volts; convert its energy
70
+ `k_B*T` to eV, or compute the kinetic-energy convention directly in joules
71
+ before dividing by `e`;
72
+ - the smallest relevant scale spans a prospectively chosen number of cells and
73
+ particles, with the diagnostic estimator operating above its grid and noise
74
+ floors; and
75
+ - the realized native input contains the intended geometry, boundary strings,
76
+ distributions, fields, collisions, diagnostics, timestep, and seed policy.
77
+
78
+ When collisions, drive, injection, external forcing, or another physical
79
+ mechanism is essential to the claim, register at least one
80
+ `physics_controls` validation check. Verify both the realized native control
81
+ and a quantitative consequence when feasible (for example measured collision
82
+ rate, momentum relaxation, injected flux, or maintained field). A collision
83
+ object in source code, an arbitrary `CoulombLog`, an initial perturbation, or a
84
+ periodic/open boundary label is not by itself evidence that the required
85
+ collisional or driven regime exists.
86
+
87
+ For threshold rules, write both the metric and a named boolean, for example
88
+ `{"metrics":{"boundary_clearance_cells":8.0},"checks":{"interior":true}}`.
89
+ Register an exact validation check on `checks.interior`. The harness checks the
90
+ JSON value; preserve the code that computed it so the calculation remains
91
+ auditable.
92
+
93
+ Do not qualify an experiment when a required structure touches a lossy
94
+ boundary, a one-sided profile substitutes for a two-sided object, a width is at
95
+ the grid floor, or the diagnostic selects an unconstrained global noise
96
+ maximum. Close commissioning as unresolved or instrument-limited and redesign.
97
+
98
+ ## Field-source distinctions
99
+
100
+ - `AnalyticInitialField` initializes grid fields through WarpX external-grid
101
+ initialization controls. Use it for an initial mesh field and inspect the
102
+ realized native input. Pass component strings as `Ex_expression`,
103
+ `Ey_expression`, `Ez_expression`, `Bx_expression`, `By_expression`, and
104
+ `Bz_expression` only. In the pinned runtime this path invokes initial
105
+ divergence cleaning; the observed MLMG projection rejects `open` field
106
+ boundaries, and the PICMI `AnalyticInitialField` constructor does not expose
107
+ a `do_initial_div_cleaning` keyword (use `warpx_do_initial_div_cleaning` when
108
+ needed). Do not respond by silently switching to periodic boundaries. Select
109
+ a boundary-compatible field topology or another supported initialization
110
+ path, then recommission the changed model under a new prospective evidence
111
+ contract.
112
+ - `ConstantAppliedField` and `AnalyticAppliedField` configure external fields
113
+ gathered by particles (`E_ext_particle_*` and `B_ext_particle_*`). Use numeric
114
+ `Ex`/`Ey`/`Ez`/`Bx`/`By`/`Bz` for constants and `*_expression` strings for
115
+ analytic applied fields. Their bounds are ignored by this WarpX
116
+ implementation. They are not automatically part of the self-consistent mesh
117
+ field and are not equivalent to a boundary inflow or boundary electromotive
118
+ force.
119
+ - A particle-applied field may directly drive the current being measured. If
120
+ it is used, define whether the observable requires the self-consistent field,
121
+ applied field, or their total, and obtain both contributions consistently.
122
+ - Do not describe periodic, reflecting, absorbing, open, or Silver-Mueller
123
+ boundaries as a physical drive. Demonstrate the actual flux, source, or
124
+ boundary mechanism that maintains the proposed state.
125
+ - Do not describe an initial seed perturbation as continuing drive. If the
126
+ hypothesis requires a driven state, commission an actual sustained source or
127
+ bound the tested claim to freely evolving initial-value dynamics.
128
+
129
+ ## Diagnostic triangulation
130
+
131
+ For an evidentiary multidimensional run, derive the primary observable by two
132
+ independent paths when feasible. Examples include a local field estimator and
133
+ a time derivative of an integral or flux. Commission their sign, units,
134
+ normalization, coordinates, time alignment, and agreement before interpreting
135
+ the physics. Track a structure continuously from its commissioned location;
136
+ do not redefine its position independently at every output by a global maximum.
137
+
138
+ ## Numerical comparisons
139
+
140
+ Change one fidelity axis at a time. A resolution comparison is not a convergence
141
+ test if physical parameters, forcing, perturbation, particle count, collision
142
+ strength, estimator, or runtime also change. Measure realized collisionality,
143
+ resistivity, temperature, density, and characteristic times when they enter the
144
+ hypothesis; input labels such as a nominal dimensionless number are not measured
145
+ controls.
@@ -0,0 +1,54 @@
1
+ # Local CPU launch tuning
2
+
3
+ Use this resource only to tune execution of an already authored program. It
4
+ must not supply physical parameters, expected outcomes, acceptance thresholds,
5
+ or a benchmark problem. Benchmark the exact frozen program and argument list
6
+ selected within the active campaign.
7
+
8
+ ## Guard MPI first
9
+
10
+ Query the loaded AMReX library:
11
+
12
+ ```bash
13
+ python -c "import amrex.space2d as a; print(a.Config.have_mpi, a.Config.have_omp)"
14
+ ```
15
+
16
+ Use `mpiexec` only when `have_mpi` is true. The presence of an MPI launcher or
17
+ MPI environment variables is insufficient. With a non-MPI AMReX wheel,
18
+ `mpiexec -n N python run.py` starts independent simulations that can waste
19
+ resources and overwrite the same files.
20
+
21
+ ## Benchmark contract
22
+
23
+ - Pass the candidate program's complete argument list after `--`. The harness
24
+ forwards it unchanged and varies only the OpenMP environment.
25
+ - Require at least one nonempty, program-produced completion or validation
26
+ artifact with `--required-path`. Choose that artifact in the active campaign;
27
+ the tuning harness does not define scientific success.
28
+ - Use enough work to make initialization a small fraction of elapsed time.
29
+ - Hold program source, arguments, random-seed policy, output cadence, and input
30
+ data fixed across thread cases.
31
+ - Set math-library threads to one to prevent nested oversubscription.
32
+ - Treat a zero exit status as necessary but not sufficient; inspect the
33
+ required validation artifacts before adopting a launch configuration.
34
+
35
+ Run from the repository root with a fresh output directory:
36
+
37
+ ```bash
38
+ .runtime/warpx-cpu/bin/python skills/warpx/scripts/benchmark_cpu_threads.py \
39
+ --python .runtime/warpx-cpu/bin/python \
40
+ --program /absolute/path/to/candidate.py \
41
+ --output artifacts/warpx-cpu-scaling-YYYYMMDD \
42
+ --threads 1,4,8 --repeats 2 --affinity close --places cores \
43
+ --required-path relative/program/completion.json \
44
+ -- <exact candidate-program arguments>
45
+ ```
46
+
47
+ Everything after `--` belongs to the candidate program. The harness writes
48
+ per-run logs, `runs.csv`, and `summary.json`, including the exact argv and
49
+ required-path checks.
50
+
51
+ There is no portable default thread count, affinity, or AMReX block size.
52
+ Rebenchmark after changing the executable, program, arguments, grid,
53
+ distributions, interactions, diagnostics, host, or runtime build. Prefer the
54
+ fastest case that preserves the candidate program's own validation results.
@@ -0,0 +1,139 @@
1
+ # Diagnostics and analysis
2
+
3
+ WarpX PICMI supplies several output routes:
4
+
5
+ - `FieldDiagnostic` for selected mesh quantities such as electric and magnetic
6
+ fields, current, and charge density;
7
+ - `ParticleDiagnostic` for selected particle position, momentum, and weighting
8
+ records;
9
+ - `ReducedDiagnostic` for compact time series such as field or particle
10
+ energy; and
11
+ - checkpoint diagnostics for restart rather than scientific interpretation.
12
+
13
+ For the pinned runtime, select mesh records with the PICMI keyword
14
+ `data_list`, for example `FieldDiagnostic(..., data_list=["E", "B", "J",
15
+ "rho"])`. `field_data` is not accepted by the installed PICMI standard.
16
+
17
+ Field and particle diagnostics can use openPMD output. The installed WarpX
18
+ runtime includes `openpmd_api`; analysis programs executed with the capability
19
+ can read those records. Ordinary sandbox Python may be used for portable array
20
+ analysis if data are first exported to formats available there.
21
+
22
+ The exact pinned PICMI keywords are WarpX-prefixed. For file-based HDF5 output
23
+ use, for example:
24
+
25
+ ```python
26
+ picmi.FieldDiagnostic(
27
+ name="fields",
28
+ grid=grid,
29
+ period=diagnostic_period,
30
+ data_list=["E", "B", "J", "rho"],
31
+ write_dir="openpmd_diags",
32
+ warpx_format="openpmd",
33
+ warpx_openpmd_backend="h5",
34
+ warpx_openpmd_encoding="f",
35
+ )
36
+ ```
37
+
38
+ The generic keyword `format="openpmd"` is rejected by the installed
39
+ `picmistandard` constructor, while omitting `warpx_format` silently selects the
40
+ default AMReX plotfile format. Inspect the used-inputs record for
41
+ `<name>.format = "openpmd"` and `<name>.openpmd_backend = "h5"`, and verify
42
+ that nonempty `.h5` records can actually be opened before qualifying the
43
+ diagnostic path. Read `examples/openpmd_field_smoke.py` for a bounded wiring
44
+ and readback example.
45
+
46
+ Iterate records with `for index in series.iterations` and use that `index` as
47
+ the iteration number. The installed `openpmd_api` `Iteration` object has
48
+ `time` and `meshes` but **no** `.iteration` attribute; `int(it.iteration)`
49
+ raises `AttributeError` after a successful WarpX write. See
50
+ `examples/openpmd_field_smoke.py`.
51
+
52
+ openPMD Python reads are deferred. Materialize each requested array before
53
+ closing its series:
54
+
55
+ ```python
56
+ pending = component.load_chunk()
57
+ series.flush()
58
+ array = np.asarray(pending).copy()
59
+ series.close()
60
+ ```
61
+
62
+ Do not close the series before `flush()`. Converting an unflushed pending read
63
+ can yield uninitialized values without a useful exception.
64
+
65
+ Choose outputs prospectively from the observable and falsifier. Record units,
66
+ component names, spatial selection, mode projection, time window, filtering,
67
+ normalization, and uncertainty calculation. A visually plausible plot is not a
68
+ defined estimator. When practical, derive the same physical quantity through
69
+ two genuinely different diagnostic paths and test their agreement.
70
+
71
+ Output completeness, finite values, expected iteration indices, and nonempty
72
+ particle/mesh records are execution-health checks. Conservation, convergence,
73
+ statistical reproducibility, and agreement with an analytic limit are
74
+ scientific commissioning checks. Neither category should be inferred from a
75
+ zero process exit code.
76
+
77
+ ## Reduced energy accounting
78
+
79
+ Read and preserve the header of every reduced-diagnostic text file before
80
+ selecting columns. In the pinned single-level runtime, `FieldEnergy` writes the
81
+ total grid-field energy in column 2 (`total_lev0(J)`), while `ParticleEnergy`
82
+ writes total particle kinetic energy in column 2 (`total(J)`), followed by
83
+ per-species totals and then mean-energy columns. Do not sum the species totals
84
+ again with `total(J)`, and do not mistake a decline in field energy alone for
85
+ loss of total energy.
86
+
87
+ For the pinned single-level schema, materialize
88
+ `scripts/reduced_energy_budget.py` and run it with the field and particle files
89
+ instead of reimplementing column selection. The script selects totals by exact
90
+ realized header labels, verifies aligned step/time rows and finite values, and
91
+ fails on an unknown schema. Never replace its selection with slices such as
92
+ `field[:, 2:].sum(...)` or `particle[:, 2:].sum(...)`; those silently add total
93
+ columns to the components they already contain.
94
+
95
+ For a closed, source-free calculation, first assert that the field and particle
96
+ rows have identical step/time coordinates, then form the budget explicitly:
97
+
98
+ ```python
99
+ field = np.atleast_2d(np.loadtxt("reduced/field_energy.txt"))
100
+ particle = np.atleast_2d(np.loadtxt("reduced/particle_energy.txt"))
101
+ assert np.array_equal(field[:, 0], particle[:, 0])
102
+ assert np.allclose(field[:, 1], particle[:, 1], rtol=0.0, atol=1.0e-30)
103
+ total = field[:, 2] + particle[:, 2]
104
+ relative_drift = (total[-1] - total[0]) / abs(total[0])
105
+ ```
106
+
107
+ Report the field, particle, and combined histories together so energy transfer
108
+ cannot be confused with non-conservation. If the model has absorbing or open
109
+ boundaries, external fields or sources, collisions, radiation, particle
110
+ injection/removal, or another energy channel, add the corresponding boundary
111
+ flux/work/source terms before calling the result a total-energy balance. For
112
+ AMR or a different diagnostic schema, derive the non-overlapping total from the
113
+ realized headers and documented semantics instead of assuming column 2 has the
114
+ same meaning. The bundled script intentionally rejects those schemas until their
115
+ non-overlap semantics are explicit. Preserve the analysis program and its
116
+ component table; a prose claim of conservation is not a commissioning check.
117
+
118
+ For in-situ access in the pinned runtime, `simulation.fields` exposes the
119
+ MultiFab registry. Fetch vector fields by registry name, physical component
120
+ direction, and level; the physical component direction is distinct from the
121
+ 2D array axes. In a 2D build use, for example,
122
+ `from pywarpx.warpx_pybind_2d import Direction` followed by
123
+ `simulation.fields.get("Efield_fp", dir=Direction.y, level=0)`. Registry names
124
+ include `Efield_fp`, `Bfield_fp`, `current_fp`, and `rho_fp`. A returned
125
+ MultiFab provides coordinate meshes with `mesh("x")` and `mesh("z")`; its
126
+ staggering makes component shapes differ. Record centering, box layout, valid
127
+ slices, and guard-cell handling before combining arrays. Read
128
+ `2d-xz-commissioning.md` before using in-situ arrays in any 2D estimator.
129
+
130
+ Do not delay an experiment to reverse-engineer in-situ particle containers.
131
+ Use `ParticleDiagnostic` plus openPMD for portable particle positions,
132
+ momenta, and weights unless the observable truly requires an in-step callback.
133
+ The legacy `pywarpx.particle_containers.ParticleContainerWrapper` and
134
+ `pywarpx.fields.*Wrapper` helpers are deprecated in this runtime.
135
+
136
+ When imposed particle fields coexist with self-consistent fields, a diagnostic
137
+ of `Efield_fp` alone need not be the total field gathered by particles. Preserve
138
+ and analyze the external contribution separately, and define the observable's
139
+ field source prospectively.
@@ -0,0 +1,79 @@
1
+ # Local CUDA launch and tuning
2
+
3
+ Use this resource only to deploy and tune an already authored program. It must
4
+ not supply physical parameters, expected outcomes, acceptance thresholds, or a
5
+ benchmark problem.
6
+
7
+ ## Prove the whole stack
8
+
9
+ The repository has a local, non-MPI, 2D CUDA WarpX 26.07 runtime with HDF5
10
+ openPMD diagnostics for the WSL host's NVIDIA RTX 4000 Ada Generation. Inside
11
+ the autonomous sandbox, invoke it through the
12
+ `warpx-cuda-openpmd-26.07` capability.
13
+
14
+ Do not infer GPU execution from `nvidia-smi` alone. Verify all three layers:
15
+
16
+ 1. `nvidia-smi` reports a device and usable driver.
17
+ 2. A real CUDA allocation and kernel complete.
18
+ 3. The loaded AMReX binding reports `have_gpu=true` and `gpu_backend=CUDA`.
19
+
20
+ On this WSL host, `/usr/lib/wsl/lib` must be first in `LD_LIBRARY_PATH`.
21
+ Otherwise an incompatible `libcuda` can be selected even though `nvidia-smi`
22
+ works.
23
+
24
+ Set `warpx_amrex_the_arena_init_size` explicitly on every GPU
25
+ `picmi.Simulation`. A 256 MiB initial arena is a safe commissioning allocation
26
+ for this host; it is an allocator setting, not a scientific memory cap. Measure
27
+ peak use and retain headroom before increasing the workload.
28
+
29
+ The reusable host launcher repairs the source-built wheel's nested Python path:
30
+
31
+ ```bash
32
+ skills/warpx/scripts/run_local_cuda.sh -c \
33
+ "import amrex.space2d as a; print(a.Config.have_gpu, a.Config.gpu_backend)"
34
+ ```
35
+
36
+ Expected output is `True CUDA`. See `local-cuda-deployment.md` to install or
37
+ repair the runtime and `examples/openpmd_field_smoke.py` to verify the producer
38
+ and reader path. These checks establish instrument availability only.
39
+
40
+ ## Benchmark contract
41
+
42
+ GPU performance depends strongly on the exact program and decomposition. Build
43
+ a campaign-local JSON file whose cases contain complete candidate-program
44
+ argument lists. Change only the launch parameter being tuned; keep all
45
+ scientific inputs and diagnostics fixed.
46
+
47
+ ```json
48
+ {
49
+ "cases": [
50
+ {"label": "case-a", "argv": ["--max-grid-size", "64"]},
51
+ {"label": "case-b", "argv": ["--max-grid-size", "0"]}
52
+ ]
53
+ }
54
+ ```
55
+
56
+ The example values illustrate argument passthrough only; they are not defaults.
57
+ Include the complete real argv for each case in the campaign-local file.
58
+
59
+ Run a fresh sweep from the repository root:
60
+
61
+ ```bash
62
+ skills/warpx/scripts/run_local_cuda.sh \
63
+ skills/warpx/scripts/benchmark_gpu.py \
64
+ --python .runtime/warpx-cuda-openpmd/bin/python \
65
+ --program /absolute/path/to/candidate.py \
66
+ --cases /absolute/path/to/campaign-cases.json \
67
+ --output artifacts/warpx-gpu-scaling-YYYYMMDD \
68
+ --repeats 2 \
69
+ --required-path relative/program/completion.json
70
+ ```
71
+
72
+ The harness refuses a non-CUDA AMReX build, runs every case in an isolated
73
+ directory, checks required nonempty artifacts, and records exact argv,
74
+ end-to-end wall time, optional WarpX evolve time, GPU identity, and summaries.
75
+ It does not decide whether a scientific result is valid.
76
+
77
+ Do not assume the GPU is faster than the CPU, and do not transfer a launch
78
+ choice between workloads. Rebenchmark after changing the program, arguments,
79
+ diagnostics, runtime, or device.
@@ -0,0 +1,87 @@
1
+ # Deploy the local CUDA instrument
2
+
3
+ Use this procedure to reproduce the WarpX 26.07 non-MPI, 2D CUDA instrument
4
+ with HDF5 openPMD diagnostics on a Linux or WSL machine.
5
+
6
+ ## Preconditions
7
+
8
+ - Pin an audited WarpX source checkout. The tested release is 26.07 at commit
9
+ `312d507407a1bf6f01ae43fb41b5c3a3700d053c`.
10
+ - Install an NVIDIA driver visible to Linux or WSL, `nvidia-smi`, Miniforge or
11
+ Mambaforge, `mamba`, Python 3.12 development headers, Git, and build tools.
12
+ - On WSL, confirm `/dev/dxg` and `/usr/lib/wsl/lib/libcuda.so` exist.
13
+ - Budget roughly 15 GB of RAM, several GB of disk, network access for source
14
+ dependencies, and 10--30 minutes for compilation.
15
+
16
+ Run the bootstrap from the repository root:
17
+
18
+ ```bash
19
+ skills/warpx/scripts/bootstrap_local_cuda.sh \
20
+ --source /absolute/path/to/pinned/warpx-26.07 --jobs 8
21
+ ```
22
+
23
+ The script detects the GPU compute capability unless `--arch` is supplied. It
24
+ creates project-local environments under `.runtime/`, builds only the 2D CUDA
25
+ Python binding, installs openPMD/HDF5 support, and runs a post-install probe.
26
+ It does not mutate the supplied WarpX source.
27
+
28
+ ## Why the bootstrap is strict
29
+
30
+ - WarpX 26.07 rejects CUDA 12.0; use CUDA 12.2 or newer. The pinned toolkit is
31
+ CUDA 12.4.
32
+ - A minimal `cuda-nvcc` package is insufficient. AMReX/WarpX also requires the
33
+ development packages for CUDA runtime, cuBLAS, cuRAND, cuSPARSE, profiler
34
+ API, and NVTX.
35
+ - On WSL, put `/usr/lib/wsl/lib` before Ubuntu CUDA stubs in
36
+ `LD_LIBRARY_PATH`; otherwise a CUDA allocation can report no device even
37
+ when `nvidia-smi` succeeds.
38
+ - Restrict the build `PATH` and set `HDF5_ROOT`/`CMAKE_PREFIX_PATH` to the
39
+ project-local non-MPI Linux HDF5 prefix. A Windows Miniconda
40
+ `hdf5-config.cmake` can otherwise be discovered through WSL and incorrectly
41
+ require MPI.
42
+ - Set `CPATH=/usr/include` during compilation. With the conda host compiler,
43
+ `nvcc` otherwise fails to resolve Ubuntu's multiarch Python `pyconfig.h`.
44
+ - Compile for the actual device architecture. This host's RTX 4000 Ada is
45
+ compute capability 8.9, expressed to CMake as `89`.
46
+
47
+ ## Validate after deployment
48
+
49
+ Run the reusable launcher and require both CUDA and openPMD HDF5:
50
+
51
+ ```bash
52
+ skills/warpx/scripts/run_local_cuda.sh \
53
+ skills/warpx/scripts/probe_local_cuda.py --require-openpmd
54
+ ```
55
+
56
+ The probe must report `cuda_warpx`, `openpmd_hdf5_reader`, and
57
+ `openpmd_hdf5_roundtrip` as true. This proves GPU-aware AMReX was loaded and
58
+ that openPMD can create and read an HDF5 series. It does not replace the WarpX
59
+ field-diagnostic smoke test, which proves the producer path.
60
+
61
+ Then execute `examples/openpmd_field_smoke.py` in a fresh directory and verify
62
+ every boolean in `openpmd_capability_smoke.json`. Finally run a representative
63
+ scientific program and inspect both its realized input and openPMD records.
64
+
65
+ Set `WARPX_CUDA_RUNTIME` to select an alternate installed runtime while keeping
66
+ the same launcher:
67
+
68
+ ```bash
69
+ WARPX_CUDA_RUNTIME=/absolute/path/to/runtime \
70
+ skills/warpx/scripts/run_local_cuda.sh program.py
71
+ ```
72
+
73
+ ## Failure signatures
74
+
75
+ | Failure | Meaning and remedy |
76
+ |---|---|
77
+ | WarpX/AMReX requires CUDA 12.2+ | System `nvcc` is too old; use the pinned project-local toolkit. |
78
+ | `cudaErrorNoDevice` while `nvidia-smi` works | Wrong `libcuda` was loaded; put the WSL driver directory first. |
79
+ | Missing `CUDA::curand` or `CUDA::cusparse` | Install their development packages, not runtime libraries alone. |
80
+ | Missing `cuda_profiler_api.h` | Install `cuda-profiler-api`. |
81
+ | Missing `nvToolsExt.h` | Install `cuda-nvtx-dev`. |
82
+ | HDF5 config under `/mnt/c/...` requests MPI | Windows CMake contamination; restrict `PATH` and point HDF5 discovery to the Linux non-MPI prefix. |
83
+ | Missing `x86_64-linux-gnu/python*/pyconfig.h` | Add `/usr/include` to `CPATH`; do not add only the multiarch leaf because that mixes libc sysroots. |
84
+ | C++20 filesystem test fails after adding the multiarch leaf | Remove that leaf from `CPATH` and use `/usr/include`. |
85
+
86
+ Preserve the build log and package lists with deployment artifacts. Re-run the
87
+ probe after driver, CUDA, Python, WarpX, HDF5, or openPMD changes.
@@ -0,0 +1,32 @@
1
+ # Numerical risks to challenge
2
+
3
+ The relevant risks depend on the proposed experiment. Consider at least those
4
+ that could change its discriminating observable:
5
+
6
+ - grid resolution relative to Debye, skin-depth, gyroradius, wavelength,
7
+ gradient, sheath, or interface scales;
8
+ - timestep relative to plasma, cyclotron, collision, crossing, bounce, growth,
9
+ and diagnostic timescales;
10
+ - finite-particle noise, loading correlations, random-seed sensitivity, and
11
+ the noise floor of fitted rates;
12
+ - particle shape, deposition, field gathering, filtering, smoothing, and
13
+ numerical heating;
14
+ - finite box size, periodic recurrences, boundary reflections, and unavailable
15
+ wavelengths;
16
+ - velocity or momentum convention errors and incorrectly realized thermal or
17
+ drift distributions;
18
+ - inconsistent dimensional normalization or species charge/mass;
19
+ - diagnostic aliasing, phase cancellation, post-selected fit windows, and an
20
+ estimator that changes meaning between cases;
21
+ - a completed run whose conservation, charge balance, or solver residual is
22
+ unacceptable;
23
+ - a nominal control parameter inferred only from input values when collisions,
24
+ transport, temperature, density, or effective coefficients evolve;
25
+ - a claimed convergence comparison that changes physical parameters or the
26
+ estimator together with resolution; and
27
+ - too little evolution in the relevant crossing, bounce, growth, collision, or
28
+ transport time to establish the regime assumed by the claim.
29
+
30
+ Use a small number of targeted challenges tied to explicit auxiliary
31
+ subhypotheses. Do not scan every numerical knob without a reason, and do not
32
+ promote a failed numerical attempt as physical evidence.