Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OnnxMetricLearning.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file OnnxMetricLearning.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2022 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 
10 
12 
13 #include <onnxruntime_cxx_api.h>
14 #include <torch/script.h>
15 
17 
18 namespace Acts {
19 
21  std::unique_ptr<const Logger> logger)
22  : m_logger(std::move(logger)), m_cfg(cfg) {
23  m_env = std::make_unique<Ort::Env>(ORT_LOGGING_LEVEL_WARNING,
24  "ExaTrkX - metric learning");
25 
26  Ort::SessionOptions session_options;
27  session_options.SetIntraOpNumThreads(1);
28  session_options.SetGraphOptimizationLevel(
29  GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
30 
31  m_model = std::make_unique<Ort::Session>(*m_env, m_cfg.modelPath.c_str(),
32  session_options);
33 }
34 
36 
37 void OnnxMetricLearning::buildEdgesWrapper(std::vector<float>& embedFeatures,
38  std::vector<int64_t>& edgeList,
39  int64_t numSpacepoints,
40  const Logger& logger) const {
41  torch::Device device(torch::kCUDA);
42  auto options =
43  torch::TensorOptions().dtype(torch::kFloat32).device(torch::kCUDA);
44 
45  torch::Tensor embedTensor =
46  torch::tensor(embedFeatures, options)
47  .reshape({numSpacepoints, m_cfg.embeddingDim});
48 
49  auto stackedEdges = detail::buildEdges(embedTensor, m_cfg.rVal, m_cfg.knnVal);
50 
51  stackedEdges = stackedEdges.toType(torch::kInt64).to(torch::kCPU);
52 
53  ACTS_VERBOSE("copy edges to std::vector");
54  std::copy(stackedEdges.data_ptr<int64_t>(),
55  stackedEdges.data_ptr<int64_t>() + stackedEdges.numel(),
56  std::back_inserter(edgeList));
57 }
58 
59 std::tuple<std::any, std::any> OnnxMetricLearning::operator()(
60  std::vector<float>& inputValues, std::size_t, int) {
61  Ort::AllocatorWithDefaultOptions allocator;
62  auto memoryInfo = Ort::MemoryInfo::CreateCpu(
63  OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault);
64 
65  // ************
66  // Embedding
67  // ************
68 
69  int64_t numSpacepoints = inputValues.size() / m_cfg.spacepointFeatures;
70  std::vector<int64_t> eInputShape{numSpacepoints, m_cfg.spacepointFeatures};
71 
72  std::vector<const char*> eInputNames{"sp_features"};
73  std::vector<Ort::Value> eInputTensor;
74  eInputTensor.push_back(Ort::Value::CreateTensor<float>(
75  memoryInfo, inputValues.data(), inputValues.size(), eInputShape.data(),
76  eInputShape.size()));
77 
78  std::vector<float> eOutputData(numSpacepoints * m_cfg.embeddingDim);
79  std::vector<const char*> eOutputNames{"embedding_output"};
80  std::vector<int64_t> eOutputShape{numSpacepoints, m_cfg.embeddingDim};
81  std::vector<Ort::Value> eOutputTensor;
82  eOutputTensor.push_back(Ort::Value::CreateTensor<float>(
83  memoryInfo, eOutputData.data(), eOutputData.size(), eOutputShape.data(),
84  eOutputShape.size()));
85  runSessionWithIoBinding(*m_model, eInputNames, eInputTensor, eOutputNames,
86  eOutputTensor);
87 
88  ACTS_VERBOSE("Embedding space of the first SP: ");
89  for (size_t i = 0; i < 3; i++) {
90  ACTS_VERBOSE("\t" << eOutputData[i]);
91  }
92 
93  // ************
94  // Building Edges
95  // ************
96  std::vector<int64_t> edgeList;
97  buildEdgesWrapper(eOutputData, edgeList, numSpacepoints, logger());
98  int64_t numEdges = edgeList.size() / 2;
99  ACTS_DEBUG("Graph construction: built " << numEdges << " edges.");
100 
101  for (size_t i = 0; i < 10; i++) {
102  ACTS_VERBOSE(edgeList[i]);
103  }
104  for (size_t i = 0; i < 10; i++) {
105  ACTS_VERBOSE(edgeList[numEdges + i]);
106  }
107 
108  return {std::make_shared<Ort::Value>(std::move(eInputTensor[0])), edgeList};
109 }
110 
111 } // namespace Acts