26 #include <boost/type_erasure/any_cast.hpp>
27 #include <cuda_profiler_api.h>
32 using namespace Acts::UnitLiterals;
37 std::vector<const SpacePoint*> readSP;
39 std::ifstream spFile(filename);
40 if (spFile.is_open()) {
41 while (!spFile.eof()) {
42 std::getline(spFile, line);
43 std::stringstream ss(line);
46 float x,
y,
z,
r, varianceR, varianceZ;
47 if (linetype ==
"lxyz") {
48 ss >> layer >> x >> y >> z >> varianceR >> varianceZ;
50 float f22 = varianceR;
51 float wid = varianceZ;
52 float cov = wid * wid * .08333;
55 if (std::abs(z) > 450.) {
74 int main(
int argc,
char** argv) {
75 auto start_pre = std::chrono::system_clock::now();
82 int nGroupToIterate = 500;
85 int nTrplPerSpBLimit = 100;
86 int nAvgTrplPerSpBLimit = 2;
89 while ((opt = getopt(argc, argv,
"haf:n:s:d:l:m:qG")) != -1) {
98 nGroupToIterate = atoi(optarg);
104 deviceID = atoi(optarg);
107 nAvgTrplPerSpBLimit = atoi(optarg);
110 nTrplPerSpBLimit = atoi(optarg);
122 std::cerr <<
"Usage: " << argv[0] <<
" [-hq] [-f FILENAME]\n";
124 std::cout <<
" -h : this help" << std::endl;
125 std::cout <<
" -a ALL : analyze all groups. Default is \""
126 << allgroup <<
"\"" << std::endl;
128 <<
" -f FILE : read spacepoints from FILE. Default is \""
129 <<
file <<
"\"" << std::endl;
130 std::cout <<
" -n NUM : Number of groups to iterate in seed "
131 "finding. Default is "
132 << nGroupToIterate << std::endl;
133 std::cout <<
" -s SKIP : Number of groups to skip in seed "
134 "finding. Default is "
135 << skip << std::endl;
136 std::cout <<
" -d DEVID : NVIDIA GPU device ID. Default is "
137 << deviceID << std::endl;
138 std::cout <<
" -l : A limit on the average number of triplets "
139 "per bottom spacepoint: this is used for determining "
140 "matrix size for triplets per middle space point"
141 << nAvgTrplPerSpBLimit << std::endl;
142 std::cout <<
" -m : A limit on the number of triplets per "
143 "bottom spacepoint: users do not have to touch this for "
144 "# spacepoints < ~200k"
145 << nTrplPerSpBLimit << std::endl;
146 std::cout <<
" -q : don't print out all found seeds"
148 std::cout <<
" -G : only run on GPU, not CPU" << std::endl;
156 ACTS_CUDA_ERROR_CHECK(cudaSetDevice(deviceID));
158 std::ifstream
f(
file);
160 std::cerr <<
"input file \"" <<
file <<
"\" does not exist\n";
166 std::cout <<
"read " << spVec.size() <<
" SP from file " <<
file << std::endl;
171 config.
rMax = 160._mm;
180 config.
zMin = -2800._mm;
181 config.
zMax = 2800._mm;
187 config.
minPt = 500._MeV;
193 options.
beamPos = {-.5_mm, -.5_mm};
196 int numPhiNeighbors = 1;
203 std::vector<std::pair<int, int>> zBinNeighborsTop;
204 std::vector<std::pair<int, int>> zBinNeighborsBottom;
208 ACTS_CUDA_ERROR_CHECK(cudaGetDeviceProperties(&prop, deviceID));
209 printf(
"\n GPU Device %d: \"%s\" with compute capability %d.%d\n\n", deviceID,
210 prop.name, prop.major, prop.minor);
216 auto bottomBinFinder = std::make_shared<Acts::BinFinder<SpacePoint>>(
218 auto topBinFinder = std::make_shared<Acts::BinFinder<SpacePoint>>(
222 config.
seedFilter = std::make_unique<Acts::SeedFilter<SpacePoint>>(
228 auto ct = [=](
const SpacePoint& sp, float, float,
229 float) -> std::pair<Acts::Vector3, Acts::Vector2> {
232 return std::make_pair(
position, variance);
247 std::unique_ptr<Acts::SpacePointGrid<SpacePoint>>
grid =
248 Acts::SpacePointGridCreator::createGrid<SpacePoint>(gridConf, gridOpts);
250 spVec.begin(), spVec.end(), ct, bottomBinFinder, topBinFinder,
253 auto end_pre = std::chrono::system_clock::now();
254 std::chrono::duration<double> elapsec_pre = end_pre - start_pre;
255 double preprocessTime = elapsec_pre.count();
256 std::cout <<
"Preprocess Time: " << preprocessTime << std::endl;
262 auto start_cpu = std::chrono::system_clock::now();
269 std::vector<std::vector<Acts::Seed<SpacePoint>>> seedVector_cpu;
272 decltype(seedFinder_cpu)::SeedingState
state;
273 state.spacePointData.resize(spVec.size());
274 for (; groupIt != spGroup.end(); ++groupIt) {
275 const auto [bottom, middle, top] = *groupIt;
277 options, state, spGroup.grid(),
278 std::back_inserter(seedVector_cpu.emplace_back()), bottom, middle,
279 top, rMiddleSPRange);
281 if (allgroup ==
false) {
282 if (group_count >= nGroupToIterate)
287 std::cout <<
"Analyzed " << group_count <<
" groups for CPU" << std::endl;
290 auto end_cpu = std::chrono::system_clock::now();
291 std::chrono::duration<double> elapsec_cpu = end_cpu - start_cpu;
292 double cpuTime = elapsec_cpu.count();
297 auto start_cuda = std::chrono::system_clock::now();
300 std::vector<std::vector<Acts::Seed<SpacePoint>>> seedVector_cuda;
304 spacePointData.resize(spVec.size());
306 for (; groupIt != spGroup.end(); ++groupIt) {
307 const auto [bottom, middle, top] = *groupIt;
309 spacePointData, spGroup.grid(), bottom, middle, top));
311 if (allgroup ==
false) {
312 if (group_count >= nGroupToIterate)
317 auto end_cuda = std::chrono::system_clock::now();
318 std::chrono::duration<double> elapsec_cuda = end_cuda - start_cuda;
319 double cudaTime = elapsec_cuda.count();
322 std::cout <<
"Analyzed " << group_count <<
" groups for CUDA" << std::endl;
324 std::cout << std::endl;
325 std::cout <<
"----------------------- Time Metric -----------------------"
327 std::cout <<
" " << (do_cpu ?
"CPU" :
" ")
328 <<
" CUDA " << (do_cpu ?
"Speedup " :
"")
330 std::cout <<
"Seedfinding_Time " << std::setw(11)
331 << (do_cpu ?
std::to_string(cpuTime) :
"") <<
" " << std::setw(11)
332 << cudaTime <<
" " << std::setw(11)
333 << (do_cpu ?
std::to_string(cpuTime / cudaTime) :
"") << std::endl;
334 double wallTime_cpu = cpuTime + preprocessTime;
335 double wallTime_cuda = cudaTime + preprocessTime;
336 std::cout <<
"Wall_time " << std::setw(11)
338 << std::setw(11) << wallTime_cuda <<
" " << std::setw(11)
341 std::cout <<
"-----------------------------------------------------------"
343 std::cout << std::endl;
346 for (
auto& outVec : seedVector_cpu) {
347 nSeed_cpu += outVec.size();
351 for (
auto& outVec : seedVector_cuda) {
352 nSeed_cuda += outVec.size();
355 std::cout <<
"Number of Seeds (CPU | CUDA): " << nSeed_cpu <<
" | "
356 << nSeed_cuda << std::endl;
360 for (
size_t i = 0;
i < seedVector_cpu.size();
i++) {
361 auto regionVec_cpu = seedVector_cpu[
i];
362 auto regionVec_cuda = seedVector_cuda[
i];
364 std::vector<std::vector<SpacePoint>> seeds_cpu;
365 std::vector<std::vector<SpacePoint>> seeds_cuda;
368 for (
auto sd : regionVec_cpu) {
369 std::vector<SpacePoint> seed_cpu;
370 seed_cpu.push_back(*(sd.sp()[0]));
371 seed_cpu.push_back(*(sd.sp()[1]));
372 seed_cpu.push_back(*(sd.sp()[2]));
374 seeds_cpu.push_back(seed_cpu);
377 for (
auto sd : regionVec_cuda) {
378 std::vector<SpacePoint> seed_cuda;
379 seed_cuda.push_back(*(sd.sp()[0]));
380 seed_cuda.push_back(*(sd.sp()[1]));
381 seed_cuda.push_back(*(sd.sp()[2]));
383 seeds_cuda.push_back(seed_cuda);
386 for (
auto seed : seeds_cpu) {
387 for (
auto other : seeds_cuda) {
388 if (
seed[0] == other[0] &&
seed[1] == other[1] &&
seed[2] == other[2]) {
397 std::cout << nMatch <<
" seeds are matched" << std::endl;
398 std::cout <<
"Matching rate: " << float(nMatch) / nSeed_cpu * 100 <<
"%"
404 std::cout <<
"CPU Seed result:" << std::endl;
406 for (
auto& regionVec : seedVector_cpu) {
407 for (
size_t i = 0;
i < regionVec.size();
i++) {
410 std::cout <<
" (" << sp->
x() <<
", " << sp->
y() <<
", " << sp->
z()
413 std::cout << sp->
surface <<
" (" << sp->
x() <<
", " << sp->
y() <<
", "
416 std::cout << sp->
surface <<
" (" << sp->
x() <<
", " << sp->
y() <<
", "
418 std::cout << std::endl;
422 std::cout << std::endl;
424 std::cout <<
"CUDA Seed result:" << std::endl;
426 for (
auto& regionVec : seedVector_cuda) {
427 for (
size_t i = 0;
i < regionVec.size();
i++) {
430 std::cout <<
" (" << sp->
x() <<
", " << sp->
y() <<
", " << sp->
z()
433 std::cout << sp->
surface <<
" (" << sp->
x() <<
", " << sp->
y() <<
", "
436 std::cout << sp->
surface <<
" (" << sp->
x() <<
", " << sp->
y() <<
", "
438 std::cout << std::endl;
443 std::cout << std::endl;
444 std::cout << std::endl;