Skip to content

Commit e4a5400

Browse files
First performance improvements (#27)
Contains some very fist performance improvements, many of which can easily be improved further: * use vectorized NDArray concatenation * allow distinct merging and output directories (useful when fast scratch storage is shared across workers) * add (temporary) batch submission scripts * dedicated example for simple impacting shower (to be used later for validation)
1 parent c49021c commit e4a5400

18 files changed

+342
-103
lines changed

examples/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ add_subdirectory(point_charge_coulomb)
88
add_subdirectory(point_charge_cherenkov)
99
add_subdirectory(point_charge_askaryan)
1010
add_subdirectory(shower_profile)
11+
add_subdirectory(impacting_shower)

examples/dipole_ice/dipole_ice.cxx

+6-8
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ int main(int argc, char* argv[]) {
2626
std::string wf_path = argv[1];
2727

2828
auto eps = [](scalar_t r, scalar_t z) {
29-
30-
return 1.0;
3129

3230
scalar_t z_m = z / 3.0;
3331
if(z_m > 0.0) {
@@ -58,14 +56,14 @@ int main(int argc, char* argv[]) {
5856

5957
// CylinderGeometry geom(20, -15, 15, eps);
6058
// InfEDipoleAntenna dipole(0.0, 10.0, 0.0, impulse_response);
59+
// scalar_t t_end = 250;
60+
61+
CylinderGeometry geom(300, -300, 300, eps);
62+
InfEDipoleAntenna dipole(0.0, 10.0, -100.0, impulse_response);
63+
scalar_t t_end = 450;
6164

62-
CylinderGeometry geom(70, -150, 150, eps);
63-
InfEDipoleAntenna dipole(0.0, 10.0, 0.0, impulse_response);
64-
65-
scalar_t t_end = 150;
66-
//scalar_t t_end = 25;
6765
CylindricalWeightingFieldCalculator wfc(geom, dipole, t_end);
68-
wfc.Calculate(wf_path);
66+
wfc.Calculate(wf_path, "/scratch/midway3/windischhofer/eisvogel/");
6967

7068
return 0;
7169
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
#SBATCH --job-name=dipole_ice
3+
#SBATCH --output=/home/windischhofer/data/windischhofer/eisvogel/dipole_ice.out
4+
#SBATCH --error=/home/windischhofer/data/windischhofer/eisvogel/dipole_ice.err
5+
#SBATCH --account=pi-avieregg
6+
#SBATCH --time=24:00:00
7+
#SBATCH --partition=avieregg
8+
#SBATCH --nodes=1
9+
#SBATCH --exclusive
10+
#SBATCH --ntasks-per-node=64
11+
#SBATCH --mem=257660
12+
#SBATCH --mail-type=NONE
13+
#SBATCH --mail-user=None
14+
15+
sh /home/windischhofer/Eisvogel/examples/dipole_ice/run_dipole_ice.sh

examples/dipole_ice/run_dipole_ice.sh

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
export EISVOGELDIR=/home/windischhofer/Eisvogel/
4+
source ${EISVOGELDIR}/setup_mdwy.sh
5+
6+
cd ${EISVOGELDIR}/build/
7+
source ./setup.sh
8+
mpirun --mca orte_base_help_aggregate 0 -np 64 examples/dipole_ice/dipole_ice /home/windischhofer/data/windischhofer/eisvogel/wf_dipole_ice_deep_meep_exp_ratio_20_300
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set(CMAKE_CXX_STANDARD 20)
2+
set(CMAKE_CXX_STANDARD_REQUIRED YES)
3+
4+
add_executable(impacting_shower impacting_shower.cxx)
5+
target_link_libraries(impacting_shower eisvogel)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <vector>
4+
#include <cmath>
5+
6+
#include "Eisvogel/Common.hh"
7+
#include "Eisvogel/SignalCalculator.hh"
8+
#include "Eisvogel/Current0D.hh"
9+
#include "Eisvogel/SignalExport.hh"
10+
11+
int main(int argc, char* argv[]) {
12+
13+
if(argc < 2) {
14+
throw;
15+
}
16+
17+
std::string wf_path = argv[1];
18+
SignalCalculator calc(wf_path);
19+
20+
// test trajectory: a point charge moving parallel to the z-axis
21+
// with a constant impact parameter of 'b' along the z-axis
22+
scalar_t b = 100;
23+
scalar_t zmax = 0.0;
24+
scalar_t zscale = 10;
25+
scalar_t tstart = -40, tend = 40;
26+
scalar_t beta = 1.0; // for in-ice shower
27+
scalar_t qmax = 1e3;
28+
auto charge = [&](scalar_t z){
29+
scalar_t cur_charge = qmax * std::exp(-std::pow((z - zmax) / zscale, 2.0));
30+
if(cur_charge < 1) {
31+
cur_charge = 0;
32+
}
33+
return cur_charge;
34+
};
35+
36+
std::cout << "Building trajectory ..." << std::endl;
37+
38+
std::vector<CoordVector> points;
39+
std::vector<scalar_t> charges;
40+
41+
for(scalar_t cur_t = tstart; cur_t < tend; cur_t += 0.1) {
42+
scalar_t cur_z = -beta * cur_t;
43+
scalar_t cur_charge = -charge(cur_z);
44+
45+
std::cout << "z = " << cur_z << ", q = " << cur_charge << std::endl;
46+
47+
points.push_back(CoordUtils::MakeCoordVectorTXYZ(cur_t, b, 0, cur_z));
48+
charges.push_back(cur_charge);
49+
}
50+
points.push_back(CoordUtils::MakeCoordVectorTXYZ(tend, b, 0, beta * tend));
51+
Current0D track(std::move(points), std::move(charges));
52+
53+
std::cout << "Computing signal ..." << std::endl;
54+
std::vector<scalar_t> signal_times, signal_values;
55+
for(scalar_t cur_t = 170; cur_t < 280; cur_t += 0.1) {
56+
std::cout << "calculating signal for t = " << cur_t << std::endl;
57+
scalar_t cur_signal = calc.ComputeSignal(track, cur_t);
58+
signal_times.push_back(cur_t);
59+
signal_values.push_back(cur_signal);
60+
}
61+
62+
ExportSignal(signal_times, signal_values, "./impacting_shower_signal.csv");
63+
64+
return 0;
65+
}

examples/point_charge_cherenkov/point_charge_cherenkov.cxx

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,23 @@ int main(int argc, char* argv[]) {
1818
// test trajectory: a point charge moving parallel to the z-axis
1919
// with a constant impact parameter of 'b' along the x-axis
2020
scalar_t b = 50;
21-
scalar_t tstart = -100, tend = 100;
21+
scalar_t tstart = -120, tend = -1;
2222
scalar_t charge = 1;
23-
scalar_t beta = 1.2;
23+
scalar_t beta = 0.99;
2424

2525
std::cout << "Building trajectory ..." << std::endl;
2626
Current0D track({
27-
CoordUtils::MakeCoordVectorTXYZ(tstart, b, 0, beta * tstart),
28-
CoordUtils::MakeCoordVectorTXYZ(tend, b, 0, beta * tend)
27+
CoordUtils::MakeCoordVectorTXYZ(tstart, b, 0, -beta * tstart),
28+
CoordUtils::MakeCoordVectorTXYZ(tend, b, 0, -beta * tend)
2929
},
3030
{charge}
3131
);
3232

3333
std::cout << "Computing signal ..." << std::endl;
3434

3535
std::vector<scalar_t> signal_times, signal_values;
36-
for(scalar_t cur_t = 10; cur_t < 45; cur_t += 0.1) {
36+
//for(scalar_t cur_t = 10; cur_t < 45; cur_t += 0.1) {
37+
for(scalar_t cur_t = 40; cur_t < 110; cur_t += 0.1) {
3738
scalar_t cur_signal = calc.ComputeSignal(track, cur_t);
3839
signal_times.push_back(cur_t);
3940
signal_values.push_back(cur_signal);

include/Eisvogel/CylindricalWeightingFieldCalculator.hh

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class CylindricalWeightingFieldCalculator {
1313
public:
1414
CylindricalWeightingFieldCalculator(CylinderGeometry& geom, const Antenna& antenna, scalar_t t_end,
1515
double courant_factor = 0.5, double resolution = 12, double pml_width = 1.0);
16-
void Calculate(std::filesystem::path outdir, std::filesystem::path tmpdir = "");
16+
void Calculate(std::filesystem::path outdir, std::filesystem::path mergedir = "", std::filesystem::path tmpdir = "");
1717

1818
private:
1919

include/Eisvogel/WeightingField.hh

+16
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ public:
6060

6161
template <typename KernelT = DefaultKernel>
6262
scalar_t E_phi(CoordVector pos);
63+
64+
// // Vectorized accessors for field components
65+
// template <typename KernelT = DefaultKernel>
66+
// std::vector<scalar_t> E_r(std::vector<CoordVector>& pos);
67+
68+
// template <typename KernelT = DefaultKernel>
69+
// std::vector<scalar_t> E_z(std::vector<CoordVector>& pos);
70+
71+
// template <typename KernelT = DefaultKernel>
72+
// std::vector<scalar_t> E_phi(std::vector<CoordVector>& pos);
73+
74+
// template <typename KernelT = DefaultKernel>
75+
// scalar_t Eip(CoordVector& pos, CoordVector& vec);
76+
77+
// template <typename KernelT = DefaultKernel>
78+
// std::vector<scalar_t> Eip(std::vector<CoordVector>& pos, std::vector<CoordVector>& vec);
6379

6480
DeltaVector GetSamplingIntervals() const;
6581
CoordVector GetStartCoords() const;

src/CylindricalWeightingFieldCalculator.cxx

+32-16
Original file line numberDiff line numberDiff line change
@@ -325,32 +325,42 @@ namespace meep {
325325

326326
} // end namespace meep
327327

328-
void CylindricalWeightingFieldCalculator::Calculate(std::filesystem::path outdir, std::filesystem::path tmpdir) {
328+
void CylindricalWeightingFieldCalculator::Calculate(std::filesystem::path outdir, std::filesystem::path mergedir, std::filesystem::path tmpdir) {
329329

330+
// Prepare merge directory
331+
if(mergedir.empty()) {
332+
mergedir = outdir;
333+
}
334+
330335
// TODO: this will get a lot easier once we can have all three components together in the same array
331-
std::filesystem::path outdir_Er = outdir / "E_r";
332-
std::filesystem::path outdir_Ez = outdir / "E_z";
336+
std::filesystem::path mergedir_E_r = mergedir / "E_r";
337+
std::filesystem::path mergedir_E_z = mergedir / "E_z";
333338

334339
if(meep::am_master()) {
335340

336-
// Prepare output directory
337-
if(!std::filesystem::exists(outdir)) {
338-
std::filesystem::create_directory(outdir);
341+
if(!std::filesystem::exists(mergedir)) {
342+
std::filesystem::create_directory(mergedir);
339343
}
340344

341-
std::filesystem::create_directory(outdir_Er);
342-
std::filesystem::create_directory(outdir_Ez);
343-
}
345+
if(!std::filesystem::exists(mergedir_E_r)) {
346+
std::filesystem::create_directory(mergedir_E_r);
347+
}
344348

345-
meep::all_wait();
349+
if(!std::filesystem::exists(mergedir_E_z)) {
350+
std::filesystem::create_directory(mergedir_E_z);
351+
}
352+
}
346353

347354
// Make sure to have a valid temporary directory to store the results as we go along
348355
if(tmpdir.empty()) {
349356
char tmpdir_template[] = "/tmp/eisvogel.XXXXXX";
350-
tmpdir = std::string(mkdtemp(tmpdir_template));
357+
tmpdir = std::filesystem::path(mkdtemp(tmpdir_template));
351358
}
352-
359+
353360
std::cout << "Using tmpdir = " << tmpdir << std::endl;
361+
std::cout << "Using mergedir = " << mergedir << std::endl;
362+
363+
meep::all_wait();
354364

355365
// This is only for cross-checking the geometry for now
356366
// f -> output_hdf5(meep::Dielectric, gv -> surroundings());
@@ -386,7 +396,11 @@ void CylindricalWeightingFieldCalculator::Calculate(std::filesystem::path outdir
386396
cld.ind_t = stepcnt++;
387397
m_f -> loop_in_chunks(meep::eisvogel_saving_chunkloop, static_cast<void*>(&cld), m_f -> total_volume());
388398

399+
std::cout << "LLL now on stepcnt = " << std::endl;
400+
std::cout << stepcnt << std::endl;
401+
389402
if((stepcnt % 400) == 0) {
403+
std::cout << "BBB now merging chunks" << std::endl;
390404
fstor -> MergeChunks(0, 400);
391405
}
392406
}
@@ -396,9 +410,9 @@ void CylindricalWeightingFieldCalculator::Calculate(std::filesystem::path outdir
396410
// TODO: again, will get better once the three separate arrays are gone
397411
// TODO: for large weighting fields, will have to move chunks to the permanent location continuously throughout the calculation so as not to fill up local storage
398412
// move them so that only the complete chunks (surviving after defragmentation) are moved that won't need to be accessed anymore
399-
std::cout << "moving output into final location ...";
400-
std::filesystem::copy(tmpdir / "E_r", outdir_Er, std::filesystem::copy_options::recursive);
401-
std::filesystem::copy(tmpdir / "E_z", outdir_Ez, std::filesystem::copy_options::recursive);
413+
std::cout << "moving output into merging location ...";
414+
std::filesystem::copy(tmpdir / "E_r", mergedir_E_r, std::filesystem::copy_options::recursive);
415+
std::filesystem::copy(tmpdir / "E_z", mergedir_E_z, std::filesystem::copy_options::recursive);
402416
std::cout << " done!" << std::endl;
403417

404418
// Wait until everybody has finished copying
@@ -411,8 +425,10 @@ void CylindricalWeightingFieldCalculator::Calculate(std::filesystem::path outdir
411425
std::cout << "==============================================" << std::endl;
412426

413427
if(meep::am_master()) {
414-
std::shared_ptr<CylindricalWeightingField> cwf = std::make_shared<CylindricalWeightingField>(outdir, *m_start_coords, *m_end_coords);
428+
std::shared_ptr<CylindricalWeightingField> cwf = std::make_shared<CylindricalWeightingField>(mergedir, *m_start_coords, *m_end_coords);
415429
cwf -> MakeMetadataPersistent();
416430
cwf -> RebuildChunks(requested_chunk_size);
431+
432+
std::filesystem::copy(mergedir, outdir, std::filesystem::copy_options::recursive);
417433
}
418434
}

src/DenseNDArray.hh

+8
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ public:
157157
return rhs.m_data == m_data;
158158
}
159159

160+
// to assign blocks of data in an efficient way
161+
void copy_from(const DenseNDArray<T, dims>& src,
162+
const DenseNDArray<std::size_t, 1>& ind_src_start, const DenseNDArray<std::size_t, 1>& ind_src_stop,
163+
const DenseNDArray<std::size_t, 1>& ind_dest_start, const DenseNDArray<std::size_t, 1>& ind_dest_stop) {
164+
165+
166+
}
167+
160168
// template <std::size_t len>
161169
// bool operator==(const std::array<T, len>& rhs) const requires(dims == 1) {
162170
// if(len != m_data.size()) {

0 commit comments

Comments
 (0)