Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SeedFinderSyclTest.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SeedFinderSyclTest.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
16 #include "Acts/Seeding/Seed.hpp"
22 
23 #include <chrono>
24 #include <cmath>
25 #include <ctime>
26 #include <fstream>
27 #include <iomanip>
28 #include <iostream>
29 #include <limits>
30 #include <memory>
31 #include <sstream>
32 #include <string>
33 
34 #include <boost/type_erasure/any_cast.hpp>
35 
36 #include "ATLASCuts.hpp"
37 #include "CommandLineArguments.h"
38 #include "SpacePoint.hpp"
39 #include "vecmem/memory/sycl/device_memory_resource.hpp"
40 #include "vecmem/memory/sycl/host_memory_resource.hpp"
41 
42 using namespace Acts::UnitLiterals;
43 
44 auto readFile(const std::string& filename) -> std::vector<const SpacePoint*> {
46  std::vector<const SpacePoint*> readSP;
47 
48  std::ifstream spFile(filename);
49  if (spFile.is_open()) {
50  int id = 0;
51  while (std::getline(spFile, line)) {
52  std::stringstream ss(line);
53  std::string linetype;
54  ss >> linetype;
55  if (linetype == "lxyz") {
56  float x;
57  float y;
58  float z;
59  float r;
60  float varianceR;
61  float varianceZ;
62  int layer;
63  ss >> layer >> x >> y >> z >> varianceR >> varianceZ;
64  r = std::hypot(x, y);
65  float f22 = varianceR;
66  float wid = varianceZ;
67  float cov = wid * wid * .08333;
68  if (cov < f22)
69  cov = f22;
70  if (std::abs(z) > 450.) {
71  varianceZ = 9. * cov;
72  varianceR = .06;
73  } else {
74  varianceR = 9. * cov;
75  varianceZ = .06;
76  }
77  readSP.emplace_back(
78  new SpacePoint(x, y, z, r, layer, varianceR, varianceZ, id));
79  ++id;
80  }
81  }
82  }
83  return readSP;
84 }
85 
86 template <typename external_spacepoint_t>
90  // silicon detector max
91  config.rMax = 160._mm;
92  config.deltaRMin = 5._mm;
93  config.deltaRMax = 160._mm;
94  config.deltaRMinTopSP = config.deltaRMin;
95  config.deltaRMinBottomSP = config.deltaRMin;
96  config.deltaRMaxTopSP = config.deltaRMax;
97  config.deltaRMaxBottomSP = config.deltaRMax;
98  config.collisionRegionMin = -250._mm;
99  config.collisionRegionMax = 250._mm;
100  config.zMin = -2800._mm;
101  config.zMax = 2800._mm;
102  config.maxSeedsPerSpM = 5;
103  // 2.7 eta
104  config.cotThetaMax = 7.40627;
105  config.sigmaScattering = 1.00000;
106  config.minPt = 500._MeV;
107  config.impactMax = 10._mm;
108  // for sycl
109  config.nTrplPerSpBLimit = 100;
110  config.nAvgTrplPerSpBLimit = 6;
111  return config;
112 }
113 
116  options.bFieldInZ = 1.99724_T;
117  options.beamPos = {-.5_mm, -.5_mm};
118  return options;
119 }
120 
121 template <typename external_spacepoint_t>
125  -> std::pair<Acts::SpacePointGridConfig, Acts::SpacePointGridOptions> {
126  Acts::SpacePointGridConfig gridConf{};
127  gridConf.minPt = config.minPt;
128  gridConf.rMax = config.rMax;
129  gridConf.zMax = config.zMax;
130  gridConf.zMin = config.zMin;
131  gridConf.deltaRMax = config.deltaRMax;
132  gridConf.cotThetaMax = config.cotThetaMax;
133 
134  Acts::SpacePointGridOptions gridOpts{};
135  gridOpts.bFieldInZ = options.bFieldInZ;
136  return std::make_pair(gridConf, gridOpts);
137 }
138 
139 auto main(int argc, char** argv) -> int {
140  auto start_prep = std::chrono::system_clock::now();
141 
142  CommandLineArguments cmdlTool;
143  cmdlTool.parse(argc, argv);
144 
145  if (!cmdlTool.inpFileName.empty() && !cmdlTool.inpFileExists) {
146  std::cerr << "Input file not found\n";
147  return -1;
148  }
149 
150  auto spVec = readFile(cmdlTool.inpFileName);
151 
152  int numPhiNeighbors = 1;
153 
154  // extent used to store r range for middle spacepoint
155  Acts::Extent rRangeSPExtent;
156 
157  const Acts::Range1D<float> rMiddleSPRange;
158 
159  std::vector<std::pair<int, int>> zBinNeighborsTop;
160  std::vector<std::pair<int, int>> zBinNeighborsBottom;
161 
162  auto bottomBinFinder = std::make_shared<Acts::BinFinder<SpacePoint>>(
163  Acts::BinFinder<SpacePoint>(zBinNeighborsBottom, numPhiNeighbors));
164  auto topBinFinder = std::make_shared<Acts::BinFinder<SpacePoint>>(
165  Acts::BinFinder<SpacePoint>(zBinNeighborsTop, numPhiNeighbors));
166  auto config = setupSeedFinderConfiguration<SpacePoint>();
167  config = config.toInternalUnits().calculateDerivedQuantities();
169  options = options.toInternalUnits().calculateDerivedQuantities(config);
170 
172  Acts::Sycl::DeviceExperimentCuts deviceAtlasCuts;
173  config.seedFilter = std::make_unique<Acts::SeedFilter<SpacePoint>>(
175 
176  const Acts::Logging::Level logLvl =
179  cmdlTool.deviceName,
180  Acts::getDefaultLogger("Sycl::QueueWrapper", logLvl));
181  vecmem::sycl::host_memory_resource resource(queue.getQueue());
182  vecmem::sycl::device_memory_resource device_resource(queue.getQueue());
183  Acts::Sycl::SeedFinder<SpacePoint> syclSeedFinder(
184  config, options, deviceAtlasCuts, queue, resource, &device_resource);
185  Acts::SeedFinder<SpacePoint> normalSeedFinder(config);
186  auto globalTool =
187  [=](const SpacePoint& sp, float /*unused*/, float /*unused*/,
188  float_t /*unused*/) -> std::pair<Acts::Vector3, Acts::Vector2> {
189  Acts::Vector3 position(sp.x(), sp.y(), sp.z());
191  return std::make_pair(position, covariance);
192  };
193  auto [gridConfig, gridOpts] = setupSpacePointGridConfig(config, options);
194  gridConfig = gridConfig.toInternalUnits();
195  gridOpts = gridOpts.toInternalUnits();
196  std::unique_ptr<Acts::SpacePointGrid<SpacePoint>> grid =
197  Acts::SpacePointGridCreator::createGrid<SpacePoint>(gridConfig, gridOpts);
198 
199  auto spGroup = Acts::BinnedSPGroup<SpacePoint>(
200  spVec.begin(), spVec.end(), globalTool, bottomBinFinder, topBinFinder,
201  std::move(grid), rRangeSPExtent, config, options);
202 
203  auto end_prep = std::chrono::system_clock::now();
204 
205  std::chrono::duration<double> elapsec_prep = end_prep - start_prep;
206  double prepTime = elapsec_prep.count();
207 
208  if (!cmdlTool.csvFormat) {
209  std::cout << "read " << spVec.size() << " SP from file "
210  << cmdlTool.inpFileName << std::endl;
211  std::cout << "Preparation time: " << std::to_string(prepTime) << std::endl;
212  }
213 
214  // -------------------------------------- //
215  // ----------- EXECUTE ON CPU ----------- //
216  // -------------------------------------- //
217 
218  auto start_cpu = std::chrono::system_clock::now();
219  uint group_count = 0;
220  std::vector<std::vector<Acts::Seed<SpacePoint>>> seedVector_cpu;
221 
222  if (!cmdlTool.onlyGpu) {
223  decltype(normalSeedFinder)::SeedingState state;
224  for (auto [bottom, middle, top] : spGroup) {
225  normalSeedFinder.createSeedsForGroup(
226  options, state, spGroup.grid(),
227  std::back_inserter(seedVector_cpu.emplace_back()), bottom, middle,
228  top, rMiddleSPRange);
229  group_count++;
230  if (!cmdlTool.allgroup && group_count >= cmdlTool.groups) {
231  break;
232  }
233  }
234  }
235 
236  auto end_cpu = std::chrono::system_clock::now();
237 
238  if (!cmdlTool.csvFormat) {
239  std::cout << "Analyzed " << group_count << " groups for CPU" << std::endl;
240  }
241 
242  // -------------------------------------- //
243  // -------- EXECUTE ON GPU - SYCL ------- //
244  // -------------------------------------- //
245 
246  auto start_sycl = std::chrono::system_clock::now();
247 
248  group_count = 0;
249  std::vector<std::vector<Acts::Seed<SpacePoint>>> seedVector_sycl;
250 
251  Acts::SpacePointData spacePointData;
252  spacePointData.resize(spVec.size());
253 
254  for (auto [bottom, middle, top] : spGroup) {
255  seedVector_sycl.push_back(syclSeedFinder.createSeedsForGroup(
256  spacePointData, spGroup.grid(), bottom, middle, top));
257  group_count++;
258  if (!cmdlTool.allgroup && group_count >= cmdlTool.groups) {
259  break;
260  }
261  }
262  auto end_sycl = std::chrono::system_clock::now();
263 
264  if (!cmdlTool.csvFormat) {
265  std::cout << "Analyzed " << group_count << " groups for SYCL" << std::endl;
266  }
267 
268  std::chrono::duration<double> elapsec_cpu = end_cpu - start_cpu;
269  double cpuTime = elapsec_cpu.count();
270 
271  std::chrono::duration<double> elapsec_sycl = end_sycl - start_sycl;
272  double syclTime = elapsec_sycl.count();
273 
274  auto textWidth = 20;
275  auto numWidth = 11;
276 
277  int nSeed_cpu = 0;
278  int nSeed_sycl = 0;
279  int nMatch = 0;
280 
281  if (cmdlTool.matches && !cmdlTool.onlyGpu) {
282  for (auto& outVec : seedVector_cpu) {
283  nSeed_cpu += outVec.size();
284  }
285 
286  for (auto& outVec : seedVector_sycl) {
287  nSeed_sycl += outVec.size();
288  }
289 
290  for (size_t i = 0; i < seedVector_cpu.size(); i++) {
291  auto regionVec_cpu = seedVector_cpu[i];
292  auto regionVec_sycl = seedVector_sycl[i];
293 
294  std::vector<std::vector<SpacePoint>> seeds_cpu;
295  std::vector<std::vector<SpacePoint>> seeds_sycl;
296 
297  for (const auto& sd : regionVec_cpu) {
298  std::vector<SpacePoint> seed_cpu;
299  seed_cpu.push_back(*(sd.sp()[0]));
300  seed_cpu.push_back(*(sd.sp()[1]));
301  seed_cpu.push_back(*(sd.sp()[2]));
302  seeds_cpu.push_back(seed_cpu);
303  }
304  for (const auto& sd : regionVec_sycl) {
305  std::vector<SpacePoint> seed_sycl;
306  seed_sycl.push_back(*(sd.sp()[0]));
307  seed_sycl.push_back(*(sd.sp()[1]));
308  seed_sycl.push_back(*(sd.sp()[2]));
309  seeds_sycl.push_back(seed_sycl);
310  }
311 
312  for (auto seed : seeds_cpu) {
313  for (auto other : seeds_sycl) {
314  if (seed[0] == other[0] && seed[1] == other[1] &&
315  seed[2] == other[2]) {
316  nMatch++;
317  break;
318  }
319  }
320  }
321  }
322  }
323 
324  if (!cmdlTool.csvFormat) {
325  std::cout << std::endl;
326  std::cout
327  << "------------------------- Time Metric -------------------------"
328  << std::endl;
329  std::cout << std::setw(textWidth) << " Device:";
330  std::cout << std::setw(numWidth) << "CPU";
331  std::cout << std::setw(numWidth) << "SYCL";
332  std::cout << std::setw(textWidth) << "Speedup/ Agreement" << std::endl;
333  std::cout << std::setw(textWidth) << " Time (s):";
334  std::cout << std::setw(numWidth) << std::to_string(cpuTime);
335  std::cout << std::setw(numWidth) << std::to_string(syclTime);
336  std::cout << std::setw(textWidth) << std::to_string(cpuTime / syclTime);
337  std::cout << std::endl;
338 
339  if (cmdlTool.matches && !cmdlTool.onlyGpu) {
340  std::cout << std::setw(textWidth) << " Seeds found:";
341  std::cout << std::setw(numWidth) << std::to_string(nSeed_cpu);
342  std::cout << std::setw(numWidth) << std::to_string(nSeed_sycl);
343  std::cout << std::setw(textWidth)
344  << std::to_string(float(nMatch) / float(nSeed_cpu) * 100);
345  std::cout << std::endl;
346  }
347 
348  std::cout
349  << "---------------------------------------------------------------"
350  << std::endl;
351  std::cout << std::endl;
352  } else {
353  std::cout << cpuTime << ',' << syclTime << ',' << cpuTime / syclTime << ','
354  << nSeed_cpu << ',' << nSeed_sycl << ',' << nMatch << '\n';
355  }
356 
357  for (const auto* S : spVec) {
358  delete[] S;
359  }
360 
361  return 0;
362 }