Skip to content

Commit c488974

Browse files
initial commit with compiling bench
0 parents  commit c488974

File tree

16 files changed

+795
-0
lines changed

16 files changed

+795
-0
lines changed

.bash_aliases

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# framework-testbench specific bash aliases for within the denv
2+
3+
# need the home install path added to various PATHs
4+
export PATH=${HOME}/.local/bin:${PATH}
5+
export LD_LIBRARY_PATH=${HOME}/.local/lib:${LD_LIBRARY_PATH}
6+
export PYTHONPATH=${HOME}/.local/python:${HOME}/.local/lib:${HOME}/.local/lib/python:${PYTHONPATH}
7+

.denv/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# ignore everything in this directory
2+
*
3+
# except the config which folks might want to share
4+
# across many computers
5+
!config

.denv/config

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
denv_name="framework-testbench"
2+
denv_image="ldmx/dev:latest"
3+
denv_shell="/bin/bash -i"
4+
denv_mounts=""

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# HOME-like stuff from having denv here
2+
.bash_logout
3+
.bash_history
4+
.bashrc
5+
.local
6+
.profile
7+
8+
# build directory to ignore
9+
build

.gitmodules

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "Framework"]
2+
path = Framework
3+
url = [email protected]:LDMX-Software/Framework.git
4+
[submodule "cmake"]
5+
path = cmake
6+
url = [email protected]:LDMX-Software/cmake.git

Bench/CMakeLists.txt

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
# Set the minimum version of CMake that's required
3+
cmake_minimum_required(VERSION 3.12)
4+
5+
# Set the project name
6+
project(Bench DESCRIPTION "Benchmarking and Testing Framework" LANGUAGES CXX)
7+
8+
option(BUILD_EVENT_ONLY "Build the event library." ON)
9+
if(BUILD_EVENT_ONLY)
10+
# Search and configure ROOT
11+
find_package(ROOT CONFIG REQUIRED)
12+
13+
register_event_object(module_path "Bench/Event" namespace "bench"
14+
class "Hit" type "collection" )
15+
16+
setup_library(module Bench name Event
17+
dependencies ROOT::Core
18+
register_target)
19+
20+
return()
21+
endif()
22+
23+
setup_library(module Bench
24+
dependencies Framework::Framework Bench::Event)

Bench/README.md

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Bench
2+
3+
Benchmark testing between ROOT-based fire and HDF5-based fire.
4+
5+
The actual compiling and running of this module is done in the
6+
[benchmark GitHub action](../.github/workflows/bench.yml).
7+
8+
In short, after compiling whichever version of the framework we are
9+
using against this module, we run the command
10+
11+
```bash
12+
ldmx time fire config.py <num-events>
13+
```
14+
15+
To time how long the processing takes, and then
16+
17+
```bash
18+
stat output/output_<num-events>.<ext>
19+
```
20+
21+
To obtain how large the output data file is.
22+
23+
## Run Locally
24+
25+
If you want to run this benchmarking test on your own machine,
26+
you can use the script that the GitHub workflow uses.
27+
You will need to provide the number of trials per test point
28+
and the event number points to test.
29+
```
30+
source env.sh
31+
source Bench/run.sh
32+
bench 10 1 10 42
33+
```
34+
35+
The plotting script assumes you have `matplotlib` and `pandas` available.
36+
You can install them quickly with `pip`.
37+
```
38+
python3 -m pip install matplotlib pandas
39+
```
40+
41+
And then you can generate plots from the data the `bench` command generated.
42+
```
43+
python3 Bench/plot.py data.csv
44+
```
45+
46+
## Results
47+
The latest results were generated with a GitHub action.
48+
This limits the number of events we can sample because of the 6 hour time limit.
49+
We still are able to compare up to 100k events being written and read.
50+
The results generated with a GitHub action using docker as the container runner.
51+
52+
![Production Mode](results/production_data.png)
53+
![Reconstruction Mode](results/recon_data.png)
54+
55+
Results generated manually up to 1M events being written/read were done on a computer
56+
at UMN using singularity.
57+
58+
![Production Mode](results/umn_production_data.png)
59+
![Reconstruction Mode](results/umn_recon_data.png)

Bench/include/Bench/Event/Hit.h

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#ifndef BENCH_EVENT_HIT_H_
2+
#define BENCH_EVENT_HIT_H_
3+
4+
// STL
5+
#include <iostream>
6+
7+
// ROOT
8+
#include "TObject.h" //For ClassDef
9+
10+
namespace bench {
11+
12+
/**
13+
* @class Hit
14+
* @brief Represents a simulated tracker hit in the simulation
15+
*/
16+
class Hit {
17+
public:
18+
/**
19+
* Class constructor.
20+
*/
21+
Hit();
22+
23+
/**
24+
* Class destructor.
25+
*/
26+
virtual ~Hit();
27+
28+
/**
29+
* Print a description of this object.
30+
*/
31+
void Print() const;
32+
33+
/**
34+
* Reset the Hit object.
35+
*/
36+
void Clear();
37+
38+
/**
39+
* Get the geometric layer ID of the hit.
40+
* @return The layer ID of the hit.
41+
*/
42+
int getLayerID() const { return layerID_; };
43+
44+
/**
45+
* Get the module ID associated with a hit. This is used to
46+
* uniquely identify a sensor within a layer.
47+
* @return The module ID associated with a hit.
48+
*/
49+
int getModuleID() const { return moduleID_; };
50+
51+
/**
52+
* Get the XYZ position of the hit [mm].
53+
* @return The position of the hit.
54+
*/
55+
std::vector<float> getPosition() const { return {x_, y_, z_}; };
56+
57+
/**
58+
* Get the energy
59+
* @return The energy of the hit.
60+
*/
61+
float getEnergy() const { return energy_; };
62+
63+
/**
64+
* Get the global time of the hit [ns].
65+
* @return The global time of the hit.
66+
*/
67+
float getTime() const { return time_; };
68+
69+
/**
70+
* Get the XYZ momentum of the particle at the position at which
71+
* the hit took place [MeV].
72+
* @return The momentum of the particle.
73+
*/
74+
std::vector<double> getMomentum() const { return {px_, py_, pz_}; };
75+
76+
/**
77+
* Get the Sim particle track ID of the hit.
78+
* @return The Sim particle track ID of the hit.
79+
*/
80+
int getTrackID() const { return trackID_; };
81+
82+
/**
83+
* Get the Sim particle track ID of the hit.
84+
* @return The Sim particle track ID of the hit.
85+
*/
86+
int getPdgID() const { return pdgID_; };
87+
88+
/**
89+
* Set the geometric layer ID of the hit.
90+
* @param layerID The layer ID of the hit.
91+
*/
92+
void setLayerID(const int layerID) { this->layerID_ = layerID; };
93+
94+
/**
95+
* Set the module ID associated with a hit. This is used to
96+
* uniquely identify a sensor within a layer.
97+
* @return moduleID The module ID associated with a hit.
98+
*/
99+
void setModuleID(const int moduleID) { this->moduleID_ = moduleID; };
100+
101+
/**
102+
* Set the position of the hit [mm].
103+
* @param x The X position.
104+
* @param y The Y position.
105+
* @param z The Z position.
106+
*/
107+
void setPosition(const float x, const float y, const float z);
108+
109+
/**
110+
* Set the energy of the hit.
111+
* @param e The energy of the hit.
112+
*/
113+
void setEnergy(const float energy) { energy_ = energy; };
114+
115+
/**
116+
* Set the global time of the hit [ns].
117+
* @param time The global time of the hit.
118+
*/
119+
void setTime(const float time) { this->time_ = time; };
120+
121+
/**
122+
* Set the momentum of the particle at the position at which
123+
* the hit took place [GeV].
124+
* @param px The X momentum.
125+
* @param py The Y momentum.
126+
* @param pz The Z momentum.
127+
*/
128+
void setMomentum(const float px, const float py, const float pz);
129+
130+
/**
131+
* Set the Sim particle track ID of the hit.
132+
* @return The Sim particle track ID of the hit.
133+
*/
134+
void setTrackID(const int simTrackID) { this->trackID_ = simTrackID; };
135+
136+
/**
137+
* Set the Sim particle track ID of the hit.
138+
* @return The Sim particle track ID of the hit.
139+
*/
140+
void setPdgID(const int simPdgID) { this->pdgID_ = simPdgID; };
141+
142+
/**
143+
* Sort by time of hit
144+
*/
145+
bool operator<(const bench::Hit &rhs) const {
146+
return this->getTime() < rhs.getTime();
147+
}
148+
149+
/**
150+
* The layer ID.
151+
*/
152+
int layerID_{0};
153+
154+
/** The module ID. */
155+
int moduleID_{0};
156+
157+
/**
158+
* The global time of the hit.
159+
*/
160+
float time_{0};
161+
162+
/**
163+
* The X momentum.
164+
*/
165+
float px_{0};
166+
167+
/**
168+
* The Y momentum.
169+
*/
170+
float py_{0};
171+
172+
/**
173+
* The Z momentum.
174+
*/
175+
float pz_{0};
176+
177+
/**
178+
* The total energy.
179+
*/
180+
float energy_{0};
181+
182+
/**
183+
* The X position.
184+
*/
185+
float x_{0};
186+
187+
/**
188+
* The Y position.
189+
*/
190+
float y_{0};
191+
192+
/**
193+
* The Z position.
194+
*/
195+
float z_{0};
196+
197+
/**
198+
* The Sim Track ID.
199+
*/
200+
int trackID_{0};
201+
202+
/**
203+
* The Sim PDG ID.
204+
*/
205+
int pdgID_{0};
206+
207+
/**
208+
* The ROOT class definition.
209+
*/
210+
ClassDef(Hit, 1);
211+
212+
}; // Hit
213+
} // namespace bench
214+
215+
#endif

0 commit comments

Comments
 (0)