33 ActsPlugins::ModuleMapCuda::Config gcCfg;
38 gcCfg.gpuBlocks = 512;
39 auto gc = std::make_shared<ActsPlugins::ModuleMapCuda>(
40 gcCfg,
m_logger->cloneWithSuffix(
"ModuleMap"));
45 std::shared_ptr<ActsPlugins::EdgeClassificationBase> gnn;
46 if (
m_gnnPath.value().find(
".onnx") != std::string::npos) {
47#ifdef ACTS_GNN_ONNX_BACKEND
48 ActsPlugins::OnnxEdgeClassifier::Config gnnCfg;
51 gnn = std::make_shared<ActsPlugins::OnnxEdgeClassifier>(
52 gnnCfg,
m_logger->cloneWithSuffix(
"GNN"));
55 ATH_MSG_FATAL(
"Not compiled with ONNX, cannot interpret *.onnx files");
56 return StatusCode::FAILURE;
58 }
else if (
m_gnnPath.value().find(
".pt") != std::string::npos) {
59#ifdef ACTS_GNN_TORCH_BACKEND
60 ActsPlugins::TorchEdgeClassifier::Config gnnCfg;
63 gnn = std::make_shared<ActsPlugins::TorchEdgeClassifier>(
64 gnnCfg,
m_logger->cloneWithSuffix(
"GNN"));
67 ATH_MSG_FATAL(
"Not compiled with Torch, cannot interpret *.pt files");
68 return StatusCode::FAILURE;
70 }
else if (
m_gnnPath.value().find(
".engine") != std::string::npos) {
71#ifdef ACTS_GNN_WITH_TENSORRT
72 ActsPlugins::TensorRTEdgeClassifier::Config gnnCfg;
76 gnn = std::make_shared<ActsPlugins::TensorRTEdgeClassifier>(
77 gnnCfg,
m_logger->cloneWithSuffix(
"GNN"));
79 ATH_MSG_FATAL(
"Not compiled with TensorRT, cannot interpret *.engine files");
80 return StatusCode::FAILURE;
84 return StatusCode::FAILURE;
88 ATH_MSG_INFO(
"Configure CC&JunctionRemoval as graph segmentation algorithm");
89 ActsPlugins::CudaTrackBuilding::Config tbCfg;
90 tbCfg.doJunctionRemoval =
true;
91 auto tb = std::make_shared<ActsPlugins::CudaTrackBuilding>(
92 tbCfg,
m_logger->cloneWithSuffix(
"CC&JR"));
96 gc, std::vector{gnn}, tb,
m_logger->cloneWithSuffix(
"Pipeline"));
98 return StatusCode::SUCCESS;
102 const std::vector<const Trk::SpacePoint*>& spacepoints,
103 std::vector<std::vector<uint32_t>>& tracks,
104 std::unordered_map<
int, std::unordered_map<int, float>>* edgeMap)
const {
106 const std::size_t nSP = spacepoints.size();
111 std::vector<std::size_t> sortIdx(nSP);
112 std::iota(sortIdx.begin(), sortIdx.end(), 0);
113 std::ranges::sort(sortIdx, std::less{}, [&](std::size_t i) {
114 return spacepoints[i]->clusterList().first->detectorElement()->identify().get_compact();
119 std::vector<std::uint64_t> moduleIds(nSP);
120 std::vector<int> ids(nSP);
122 for (std::size_t k = 0; k < nSP; ++k) {
123 const std::size_t origIdx = sortIdx[k];
126 moduleIds[k] = spacepoints[origIdx]->clusterList().first->detectorElement()->identify().get_compact();
127 ids[k] =
static_cast<int>(k);
134 auto candidates = [&] {
135 std::unique_lock<std::mutex>
lock;
136 if (m_runMutex)
lock = std::unique_lock<std::mutex>(*m_runMutex);
138 if (edgeMap !=
nullptr) {
140 auto result =
m_gnnPipeline->run(features, moduleIds, ids, ActsPlugins::Device::Cuda(0), hook);
144 const std::vector<std::int64_t>& edgeIndex = hook.
getEdgeIndex();
145 const std::size_t nEdges = edgeScores.size();
148 for (std::size_t i = 0; i < nEdges; ++i) {
149 std::int64_t src = edgeIndex[i];
150 std::int64_t dst = edgeIndex[nEdges + i];
151 (*edgeMap)[sortIdx[src]][sortIdx[dst]] = edgeScores[i];
156 return m_gnnPipeline->run(features, moduleIds, ids, ActsPlugins::Device::Cuda(0));;
159 ATH_MSG_DEBUG(
"GNN pipeline returned " << candidates.size() <<
" candidates");
163 tracks.reserve(candidates.size());
165 for (
const auto& candidate : candidates) {
171 std::vector<uint32_t> track;
172 track.reserve(candidate.size());
173 for (
int sortedIdx : candidate) {
174 track.push_back(
static_cast<uint32_t
>(sortIdx[sortedIdx]));
176 tracks.push_back(std::move(track));
179 ATH_MSG_DEBUG(
"Returning " << tracks.size() <<
" track candidates after filtering (>= "
182 return StatusCode::SUCCESS;