-
Notifications
You must be signed in to change notification settings - Fork 13
Navigation performance benchmark - implementing #49 #530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 16 commits
e008c6d
c3a6ebe
c36fd05
ec915f8
41f5062
b2b7953
4265481
9be7753
0f98dbf
5a725f5
0098522
f90ac28
d59f081
d9369d9
b6fe1da
a9611ca
813eb40
fd2ede2
2333c46
689fe97
33a8cd1
7e170e3
8e3b235
1b96530
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,233 @@ | ||
| (manual-geombench)= | ||
|
|
||
| # Geometry benchmarking | ||
|
|
||
| The `remage-geombench` command-line tool helps identify performance bottlenecks | ||
| in detector geometries during the design phase. It systematically samples points | ||
| on three grids of starting positions and simulates geantinos through the volume. | ||
| It returns the median simulation time per geantino. Based on these overview | ||
| plots and statistics are generated. | ||
|
|
||
| :::{tip} | ||
|
|
||
| Use this tool during geometry development to identify components that may slow | ||
| down simulations. Complex nested structures, boolean operations, and highly | ||
| detailed volumes can significantly increase navigation time. | ||
|
|
||
| ::: | ||
|
|
||
| ## Overview | ||
|
|
||
| The geometry benchmark works by: | ||
|
|
||
| 1. Loading a GDML geometry file | ||
| 2. Creating three 2D grids in XY, XZ, and YZ direction according to grid | ||
| specifications | ||
| 3. Sampling geantinos and estimating the median simulation time per grid point | ||
| 4. Generating statistics and visualizations showing where navigation is slow | ||
|
|
||
| This information helps you optimize geometries before running full physics | ||
| simulations, potentially saving significant computation time. | ||
|
|
||
| ## Basic usage | ||
|
|
||
| The simplest usage requires only a GDML file: | ||
|
|
||
| ```console | ||
| $ remage-geombench detector.gdml | ||
| ``` | ||
|
|
||
| This will: | ||
|
|
||
| - Benchmark the entire geometry | ||
| - Use default settings (10M events, 1 mm grid spacing, 25% buffer) | ||
| - Save results to `detector.lh5` in the current directory | ||
| - Print summary statistics to the console and generate overview plots in the | ||
| current directory | ||
|
|
||
| ## Command-line options | ||
|
|
||
| ### Geometry selection | ||
|
|
||
| **`geometry`** (required) : Path to the GDML geometry file to benchmark. | ||
|
|
||
| **`--logical-volume NAME`** (optional) : Extract and benchmark only a specific | ||
| logical volume including daughters from the geometry. Useful for isolating | ||
| performance issues in complex assemblies. | ||
|
|
||
| Example: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --logical-volume V0101 | ||
| ``` | ||
|
|
||
| ### Grid configuration | ||
|
|
||
| **`--grid-increment SPACING`** (default: `1`) : Uniform spacing between grid | ||
| points in millimeters for all dimensions. | ||
|
|
||
| Example (coarse grid for quick tests): | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --grid-increment 5 | ||
| ``` | ||
|
|
||
| **`--grid-increments DICT`** (optional) : Specify different spacing per | ||
| dimension using a Python dictionary literal. Overrides `--grid-increment` if | ||
| provided. | ||
|
|
||
| Example: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --grid-increments "{'x': 1.0, 'y': 2.0, 'z': 0.5}" | ||
| ``` | ||
|
|
||
| ### Buffer region | ||
|
|
||
| **`--buffer-fraction FRACTION`** (default: `0.25`) : Fractional buffer space | ||
| around the geometry. A value of 0.25 adds 12.5% extra space on each side, | ||
| creating a world volume large enough to contain the geometry with margin. | ||
|
|
||
| Example (tighter bounds): | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --buffer-fraction 0.1 | ||
| ``` | ||
|
|
||
| ### Simulation control | ||
|
|
||
| **`--num-events N`** (default: `10000000`) : Number of navigation events to | ||
| simulate. Higher values give more stable statistics but take longer. | ||
|
|
||
| Example (quick test): | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --num-events 1000000 | ||
| ``` | ||
|
|
||
| **`--output-dir PATH`** (default: `./`) : Directory to store output files. | ||
|
|
||
| Example: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --output-dir ./benchmark_results/ | ||
| ``` | ||
|
|
||
| **`--dry-run`** : Generate and display the macro file without running the | ||
| simulation. Useful for verifying configuration before long runs. | ||
|
|
||
| Example: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --dry-run | ||
| ``` | ||
|
|
||
| ## Interpreting results | ||
|
|
||
| The tool generates an LH5 output file containing spatial navigation performance | ||
| data and prints summary statistics: | ||
|
|
||
| ``` | ||
| Geometry Benchmark Analysis Results: | ||
| mean_navigation_time: 2.45 ns | ||
| median_navigation_time: 1.89 ns | ||
| std_navigation_time: 1.23 ns | ||
| max_navigation_time: 45.67 ns | ||
| min_navigation_time: 0.34 ns | ||
|
Comment on lines
+131
to
+136
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this the actual output? |
||
| ``` | ||
|
|
||
| In addition, the visualization of the data can help identify hotspots. | ||
|
|
||
| ### Key metrics | ||
|
|
||
| **Mean navigation time** : Average time spent navigating to each point. Lower is | ||
| better. | ||
|
|
||
| **Max navigation time** : Slowest navigation time encountered. High values | ||
| indicate geometry hotspots. | ||
|
|
||
| **Standard deviation** : Variability in navigation time. High values suggest | ||
| non-uniform complexity. | ||
|
Comment on lines
+141
to
+150
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can be removed. |
||
|
|
||
| :::{warning} | ||
|
|
||
| Navigation times are relative and depend on the hardware. Focus on identifying | ||
| spatial patterns and relative differences between geometric components rather | ||
| than absolute timing values. | ||
|
|
||
| In addition, these statistics also depend on the ratio of empty space to actual | ||
| material. If one is not interested in potential slowdowns far away from the | ||
| object, one should choose a small enough buffer to reduce the impact of the | ||
| empty space. | ||
|
|
||
| ::: | ||
|
|
||
| ## Workflow examples | ||
|
|
||
| ### Full detector benchmark | ||
|
|
||
| Benchmark an entire detector assembly with default settings: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --output-dir benchmarks/ | ||
| ``` | ||
|
|
||
| ### Component isolation | ||
|
|
||
| Test a specific problematic component: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml --logical-volume V0101 \ | ||
| --grid-increment 0.5 --output-dir component_tests/ | ||
| ``` | ||
|
|
||
| This generates a `part_{logical-volume}.lh5` and | ||
| `part_{logical-volume}_[...].pdf` files in the output directory. | ||
|
|
||
| ### Anisotropic sampling | ||
|
|
||
| For elongated geometries, use different grid spacing per dimension: | ||
|
|
||
| ```console | ||
| $ remage-geombench l1000.gdml \ | ||
| --grid-increments "{'x': 0.5, 'y': 0.5, 'z': 2.0}" | ||
| ``` | ||
|
|
||
| ## Performance optimization tips | ||
|
|
||
| Based on benchmark results, consider these optimization strategies: | ||
|
|
||
| 1. **Simplify boolean operations**: Multiple nested unions/subtractions are | ||
| expensive. Consider alternative representations. | ||
|
|
||
| 2. **Reduce tessellated solid complexity**: Decrease facet count where possible | ||
| without losing essential features. | ||
|
|
||
| 3. **Material boundaries**: Excessive material changes force more boundary | ||
| checks. Consolidate materials where physics allows. | ||
|
|
||
| 4. **Envelope optimization**: Proper envelope volumes can accelerate navigation | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you don't explain well what you mean here |
||
| in complex assemblies. | ||
|
|
||
| ## Technical details | ||
|
|
||
| The benchmark uses the `GeomBench` generator, which systematically steps through | ||
| three 2D grids and measures median simulation time per grid point. The geometry | ||
| is automatically wrapped in a world volume sized to contain it with the | ||
| specified buffer fraction. | ||
|
|
||
| When extracting a specific logical volume, the tool: | ||
|
|
||
| 1. Identifies the volume in the GDML registry | ||
| 2. Copies all dependent resources (materials, solids, daughter volumes) | ||
| 3. Creates a minimal world volume containing only the extracted component | ||
| 4. Applies the buffer and generates a temporary GDML file for benchmarking | ||
|
|
||
| This allows testing individual components without the overhead of the full | ||
| geometry. | ||
|
|
||
| ## See also | ||
|
|
||
| - {ref}`manual-geometry` – General geometry setup | ||
| - {ref}`manual-running` – Running simulations | ||
| - {ref}`manual-output` – Output data formats | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| // Copyright (C) 2025 Moritz Neuberger <https://orcid.org/0009-0001-8471-9076> | ||
| #ifndef _RMG_GENERATOR_GEOMBENCH_HH_ | ||
| #define _RMG_GENERATOR_GEOMBENCH_HH_ | ||
MoritzNeuberger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #include <chrono> | ||
| #include <memory> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "CLHEP/Units/SystemOfUnits.h" | ||
| #include "G4AnalysisManager.hh" | ||
| #include "G4GenericMessenger.hh" | ||
| #include "G4LogicalVolume.hh" | ||
| #include "G4ParticleGun.hh" | ||
| #include "G4VPhysicalVolume.hh" | ||
|
|
||
| #include "RMGGeomBenchOutputScheme.hh" | ||
| #include "RMGVGenerator.hh" | ||
|
|
||
| namespace u = CLHEP; | ||
|
|
||
| class RMGGeomBench : public RMGVGenerator { | ||
|
|
||
| public: | ||
|
|
||
| RMGGeomBench(); | ||
| ~RMGGeomBench(); | ||
|
|
||
| RMGGeomBench(RMGGeomBench const&) = delete; | ||
| RMGGeomBench& operator=(RMGGeomBench const&) = delete; | ||
| RMGGeomBench(RMGGeomBench&&) = delete; | ||
| RMGGeomBench& operator=(RMGGeomBench&&) = delete; | ||
|
|
||
| void GeneratePrimaries(G4Event* event) override; | ||
| void SetParticlePosition(G4ThreeVector) override{}; | ||
| void RecordBatchTime(size_t pixel_idx, double batch_time); | ||
| void SaveAllPixels(); | ||
|
|
||
| void BeginOfRunAction(const G4Run* r) override; | ||
| void EndOfRunAction(const G4Run* r) override; | ||
|
|
||
| private: | ||
|
|
||
| // Helper to find the benchmark output scheme if it's active | ||
| RMGGeomBenchOutputScheme* GetBenchmarkOutputScheme(); | ||
|
|
||
| std::unique_ptr<G4ParticleGun> fGun = nullptr; | ||
|
|
||
| std::unique_ptr<G4GenericMessenger> fMessenger = nullptr; | ||
| void DefineCommands(); | ||
|
|
||
| long totalnevents; | ||
| size_t totalnpixels; | ||
| int npixelsperrow; | ||
| int neventsperpixel; | ||
| double cubesize; | ||
|
|
||
| // Configurable sampling parameters (user-specified increments) | ||
| G4ThreeVector user_increment; | ||
| G4ThreeVector sampling_width; | ||
|
|
||
| // Calculated number of pixels based on increments and widths | ||
| size_t npixels_x; | ||
| size_t npixels_y; | ||
| size_t npixels_z; | ||
| size_t ID; | ||
|
|
||
| double starttime; | ||
| double currenttime; | ||
| double bunchstarttime; | ||
|
|
||
| // For tracking batches and calculating median | ||
| std::vector<std::vector<double>> pixel_batch_times; // One vector of batch times per pixel | ||
| int events_per_bunch; | ||
| int total_batch_rounds; | ||
| int current_batch_event; | ||
| int current_pixel_index; | ||
| int current_batch_round; | ||
|
|
||
| G4ThreeVector origin; | ||
| G4ThreeVector limit; | ||
| G4ThreeVector increment; | ||
| }; | ||
|
|
||
| #endif | ||
Uh oh!
There was an error while loading. Please reload this page.