1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
|
/*
* File: NavigationBenchmark.cpp
*
* Created on: Oct 25, 2014
* Author: swenzel, lima
*/
#undef VERBOSE
//#define VERBOSE
#include "VecGeom/base/Config.h"
#ifdef VECGEOM_ROOT
#include "VecGeomTest/RootGeoManager.h"
#include "VecGeomTest/Visualizer.h"
#endif
#ifdef VECGEOM_GEANT4
#include "VecGeomTest/G4GeoManager.h"
#include "G4ThreeVector.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4PVPlacement.hh"
#include "G4GeometryManager.hh"
#endif
#include "VecGeomTest/NavigationBenchmarker.h"
#include "test/benchmark/ArgParser.h"
#include "VecGeom/volumes/utilities/VolumeUtilities.h"
#include "VecGeom/management/GeoManager.h"
#include "VecGeom/volumes/Box.h"
#include "VecGeom/volumes/Orb.h"
#include "VecGeom/volumes/Trapezoid.h"
using namespace VECGEOM_NAMESPACE;
VPlacedVolume *SetupGeometry()
{
UnplacedBox *worldUnplaced = new UnplacedBox(10, 10, 10);
UnplacedTrapezoid *trapUnplaced = new UnplacedTrapezoid(4, 0, 0, 4, 4, 4, 0, 4, 4, 4, 0);
UnplacedBox *boxUnplaced = new UnplacedBox(2, 2, 2);
UnplacedOrb *orbUnplaced = new UnplacedOrb(2.8);
LogicalVolume *world = new LogicalVolume("world", worldUnplaced);
LogicalVolume *trap = new LogicalVolume("trap", trapUnplaced);
LogicalVolume *box = new LogicalVolume("box", boxUnplaced);
LogicalVolume *orb = new LogicalVolume("orb", orbUnplaced);
Transformation3D *ident = new Transformation3D(0, 0, 0, 0, 0, 0);
orb->PlaceDaughter("orb1", box, ident);
trap->PlaceDaughter("box1", orb, ident);
Transformation3D *placement1 = new Transformation3D(5, 5, 5, 0, 0, 0);
Transformation3D *placement2 = new Transformation3D(-5, 5, 5, 0, 0, 0); // 45, 0, 0);
Transformation3D *placement3 = new Transformation3D(5, -5, 5, 0, 0, 0); // 0, 45, 0);
Transformation3D *placement4 = new Transformation3D(5, 5, -5, 0, 0, 0); // 0, 0, 45);
Transformation3D *placement5 = new Transformation3D(-5, -5, 5, 0, 0, 0); // 45, 45, 0);
Transformation3D *placement6 = new Transformation3D(-5, 5, -5, 0, 0, 0); // 45, 0, 45);
Transformation3D *placement7 = new Transformation3D(5, -5, -5, 0, 0, 0); // 0, 45, 45);
Transformation3D *placement8 = new Transformation3D(-5, -5, -5, 0, 0, 0); // 45, 45, 45);
world->PlaceDaughter("trap1", trap, placement1);
world->PlaceDaughter("trap2", trap, placement2);
world->PlaceDaughter("trap3", trap, placement3);
world->PlaceDaughter("trap4", trap, placement4);
world->PlaceDaughter("trap5", trap, placement5);
world->PlaceDaughter("trap6", trap, placement6);
world->PlaceDaughter("trap7", trap, placement7);
world->PlaceDaughter("trap8", trap, placement8);
VPlacedVolume *w = world->Place();
GeoManager::Instance().SetWorld(w);
GeoManager::Instance().CloseGeometry();
// cleanup
delete ident;
delete placement1;
delete placement2;
delete placement3;
delete placement4;
delete placement5;
delete placement6;
delete placement7;
delete placement8;
return w;
}
int main(int argc, char *argv[])
{
OPTION_INT(ntracks, 1024);
OPTION_INT(nreps, 3);
OPTION_STRING(geometry, "navBench");
OPTION_STRING(logvol, "world");
OPTION_DOUBLE(bias, 0.8f);
#ifdef VECGEOM_ROOT
OPTION_BOOL(vis, false);
#endif
// default values used above are always printed. If help true, stop now, so user will know which options
// are available, and what the default values are.
OPTION_BOOL(help, false);
if (help) return 0;
#ifdef VECGEOM_ENABLE_CUDA
// If CUDA enabled, then GPU hardware is required!
int nDevice;
cudaGetDeviceCount(&nDevice);
if(nDevice > 0) {
cudaDeviceReset();
}
else {
std::cout << "\n ***** No Cuda Capable Device!!! *****\n" << std::endl;
return 0;
}
#else
std::cerr<<"... VECGEOM_ENABLE_CUDA not defined at compilation?!?\n";
#endif
if (geometry.compare("navBench") == 0) {
SetupGeometry();
#ifdef VERBOSE
//.. print geometry details
for (auto &element : GeoManager::Instance().GetLogicalVolumesMap()) {
auto *lvol = element.second;
// lvol->SetLevelLocator(nullptr); // force-disable locators to test default GlobalLocator implementations
std::cerr << "SetupBoxGeom(): logVol=" << lvol << ", name=" << lvol->GetName()
<< ", locator=" << (lvol->GetLevelLocator() ? lvol->GetLevelLocator()->GetName() : "NULL") << "\n";
}
std::vector<VPlacedVolume *> v1;
GeoManager::Instance().getAllPlacedVolumes(v1);
for (auto &plvol : v1) {
std::cerr << "placedVol=" << plvol << ", name=" << plvol->GetName() << ", world=" << world << ", <"
<< world->GetName() << ", " << GeoManager::Instance().GetWorld() << ">\n";
}
//.. more details
world->PrintContent();
std::cerr << "\n";
#endif
#ifdef VECGEOM_ROOT
// Exporting to ROOT file
RootGeoManager::Instance().ExportToROOTGeometry(GeoManager::Instance().GetWorld(), "navBench.root");
RootGeoManager::Instance().Clear();
#endif
}
// Now try to read back in. This is needed to make comparisons to VecGeom easily,
// since it builds VecGeom geometry based on the ROOT geometry and its TGeoNodes.
#ifdef VECGEOM_ROOT
auto rootgeom = geometry + ".root";
RootGeoManager::Instance().set_verbose(0);
RootGeoManager::Instance().LoadRootGeometry(rootgeom.c_str());
#endif
#ifdef VECGEOM_GEANT4
auto g4geom = geometry + ".gdml";
G4GeoManager::Instance().LoadG4Geometry(g4geom.c_str());
#endif
// Visualization
#ifdef VECGEOM_ROOT
if (vis) { // note that visualization block returns, excluding the rest of benchmark
Visualizer visualizer;
const VPlacedVolume *world = GeoManager::Instance().GetWorld();
visualizer.AddVolume(*world);
Vector<Daughter> const *daughters = world->GetLogicalVolume()->GetDaughtersp();
for (size_t i = 0; i < daughters->size(); ++i) {
VPlacedVolume const *daughter = (*daughters)[i];
Transformation3D const &trf1 = *(daughter->GetTransformation());
visualizer.AddVolume(*daughter, trf1);
Vector<Daughter> const* daughters2 = daughter->GetLogicalVolume()->GetDaughtersp();
for (int ii=0; ii < (int)daughters2->size(); ++ii) {
VPlacedVolume const* daughter2 = (*daughters2)[ii];
Transformation3D const& trf2 = *(daughter2->GetTransformation());
Transformation3D comb = trf1;
comb.MultiplyFromRight(trf2);
visualizer.AddVolume(*daughter2, comb);
}
}
std::vector<VPlacedVolume *> v1;
GeoManager::Instance().getAllPlacedVolumes(v1);
for (auto &plvol : v1) {
std::cerr << "placedVol=" << plvol << ", name=" << plvol->GetName() << ", world=" << world << ", <"
<< world->GetName() << ", " << GeoManager::Instance().GetWorld() << ">\n";
}
// visualizer.Show();
return 0;
}
#endif
std::cout << "\n*** Validating VecGeom navigation...\n";
const LogicalVolume *startVolume = GeoManager::Instance().GetWorld()->GetLogicalVolume();
if (logvol.compare("world") != 0) {
startVolume = GeoManager::Instance().FindLogicalVolume(logvol.c_str());
}
#ifdef VERBOSE
std::cout << "NavigationBenchmark: logvol=<" << logvol << ">, startVolume=<"
<< (startVolume ? startVolume->GetLabel() : "NULL") << ">\n";
if (startVolume) std::cout << *startVolume << "\n";
#endif
// no more than about 1000 points used for validation
int np = Min(ntracks, 1024);
// prepare tracks to be used for benchmarking
SOA3D<Precision> points(np);
SOA3D<Precision> dirs(np);
Vector3D<Precision> samplingVolume(10, 10, 10);
vecgeom::volumeUtilities::FillRandomPoints(samplingVolume, points);
vecgeom::volumeUtilities::FillRandomDirections(dirs);
// run validation on subsample of np tracks
Precision *maxSteps = (Precision *)vecCore::AlignedAlloc(32, sizeof(Precision) * np);
for (int i = 0; i < np; ++i)
maxSteps[i] = 10. * RNG::Instance().uniform();
// Must be validated before being benchmarked
bool ok = validateVecGeomNavigation(np, points, dirs, maxSteps);
if (!ok) {
std::cout << "VecGeom validation failed." << std::endl;
//return 1;
}
else {
std::cout << "VecGeom validation passed." << std::endl;
}
// on mic.fnal.gov CPUs, loop execution takes ~70sec for ntracks=10M
while (np <= ntracks) {
std::cout << "\n*** Running navigation benchmarks with ntracks=" << np << " and nreps=" << nreps << ".\n";
runNavigationBenchmarks(startVolume, np, nreps, maxSteps, bias);
np *= 8;
}
// cleanup
vecCore::AlignedFree(maxSteps);
#ifdef VECGEOM_ROOT
RootGeoManager::Instance().Clear();
#endif
return 0;
}
|