ATLAS Offline Software
Loading...
Searching...
No Matches
TracccMeasurementDeviceConverterAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
12#include <GaudiKernel/StatusCode.h>
13#include <memory>
14#include <traccc/edm/measurement_collection.hpp>
15#include <traccc/geometry/detector.hpp>
16#include <vecmem/containers/data/vector_buffer.hpp>
17#include <vecmem/containers/data/vector_view.hpp>
18#include <vecmem/containers/device_vector.hpp>
19
20namespace {
21 const SG::Accessor<unsigned long> s_acc_id("identifier");
22 const SG::Accessor<unsigned int> s_acc_id_hash("identifierHash");
23 const SG::Accessor<std::array<float, 1>> s_acc_loc_pos_x("localPositionDim1");
24 const SG::Accessor<std::array<float, 1>> s_acc_loc_cov_x("localCovarianceDim1");
25 const SG::Accessor<std::array<float, 2>> s_acc_loc_pos_xy("localPositionDim2");
26 const SG::Accessor<std::array<float, 4>> s_acc_loc_cov_xy("localCovarianceDim2");
27 const SG::Accessor<xAOD::ArrayFloat3> s_acc_global_pos("globalPosition");
28}
29
30namespace ActsTrk {
31
33{
34 ATH_CHECK(m_mrTool.retrieve());
35 ATH_CHECK(m_copiesTool.retrieve());
36 ATH_CHECK(m_streamTool.retrieve());
37
38 ATH_CHECK(m_inputMeasKey.initialize());
39 ATH_CHECK(m_outputPixelKey.initialize());
40 ATH_CHECK(m_outputStripKey.initialize());
41 ATH_CHECK(m_deviceCondKey.initialize());
42
44
45 ATH_MSG_DEBUG("Successfully initialized");
46 return StatusCode::SUCCESS;
47}
48
49StatusCode TracccMeasurementDeviceConverterAlg::execute(const EventContext& ctx) const
50{
52 detector_conditions_handle{m_deviceCondKey, ctx};
53 ATH_CHECK(detector_conditions_handle.isValid());
54 if ((*detector_conditions_handle) == nullptr) {
55 ATH_MSG_ERROR("null detector conditions");
56 return StatusCode::FAILURE;
57 }
58 auto const & detector_conditions = **detector_conditions_handle;
59
60 // ---- Create (empty) output objects
61
62 // Create non-owning SG containers
63 auto pixel_cont = std::make_unique<xAOD::PixelClusterContainer>(
65 auto strip_cont = std::make_unique<xAOD::StripClusterContainer>(
67
68 // Create Aux containers
69 auto pixel_aux = std::make_unique<xAOD::PixelClusterAuxContainer>();
70 auto strip_aux = std::make_unique<xAOD::StripClusterAuxContainer>();
71
72 // Associate the Aux container to the containers
73 pixel_cont->setStore(pixel_aux.get());
74 strip_cont->setStore(strip_aux.get());
75
76 // ---- Read input
77 auto device_copy = m_copiesTool->deviceCopy(ctx);
78 cudaStream_t cuda_stream = static_cast<cudaStream_t>(m_streamTool->stream(ctx));
79 auto traccc_measurements = SG::makeHandle(m_inputMeasKey, ctx);
80 ATH_CHECK(traccc_measurements.isValid());
81 traccc::edm::measurement_collection::const_view::size_type const n_meas =
82 device_copy->get_size(*traccc_measurements);
83
84 // ---- Nothing to convert
85 if (n_meas == 0) {
86 // We still need to register empty containers in SG
88 ATH_CHECK(pixelHandle.record(std::move(pixel_cont), std::move(pixel_aux)));
89
91 ATH_CHECK(stripHandle.record(std::move(strip_cont), std::move(strip_aux)));
92
93 ATH_MSG_DEBUG("Converted 0 pixel clusters, 0 strip clusters");
94 return StatusCode::SUCCESS;
95 }
96
97 // ---- Create output buffers
98 // They are allocated during the conversion when we know how many pixels and strips there are
99 std::unique_ptr<DevicePixelMeasurementContainer::buffer> converted_pixel_meas_device_buffer{nullptr};
100 std::unique_ptr<DeviceStripMeasurementContainer::buffer> converted_strip_meas_device_buffer{nullptr};
101
102 // ---- Conversion on GPU
103 DevicePixelMeasurementContainer::view::size_type n_pixels = 0;
104 DeviceStripMeasurementContainer::view::size_type n_strips = 0;
105 ATH_CHECK(convertMeasurementsOnGPU(cuda_stream, m_mrTool->mainMR(), *device_copy,
106 m_detector->as_view<traccc::itk_detector>(), detector_conditions,
107 n_meas, *traccc_measurements, n_pixels, n_strips,
108 converted_pixel_meas_device_buffer, converted_strip_meas_device_buffer));
109 if (!converted_pixel_meas_device_buffer or !converted_strip_meas_device_buffer)[[unlikely]]{
110 ATH_MSG_ERROR("nullptr detected");
111 return StatusCode::FAILURE;
112 }
113 // Create const device objects to access the field vectors directly
114 DevicePixelMeasurementContainer::device pixel_meas_device{*converted_pixel_meas_device_buffer};
115 DeviceStripMeasurementContainer::device strip_meas_device{*converted_strip_meas_device_buffer};
116
117 // ---- Feed output SG containers
118
119 // Create data pools
120 DataPool<xAOD::PixelCluster> pixel_pool(ctx, n_pixels);
121 DataPool<xAOD::StripCluster> strip_pool(ctx, n_strips);
122
123 // Reserve space and set element pointers in SG containers
124 pixel_cont->push_new(n_pixels, [&pixel_pool]() {
125 return pixel_pool.nextElementPtr(); });
126 strip_cont->push_new(n_strips, [&strip_pool]() {
127 return strip_pool.nextElementPtr(); });
128
129 // ---- Copy data from vecmem containers on device directly to SG containers
130 { // Pixels
131 auto span_id = s_acc_id.getDataSpan(*pixel_cont);
132 auto span_id_hash = s_acc_id_hash.getDataSpan(*pixel_cont);
133 auto span_local_pos = s_acc_loc_pos_xy.getDataSpan(*pixel_cont);
134 auto span_local_cov = s_acc_loc_cov_xy.getDataSpan(*pixel_cont);
135 auto span_global_pos = s_acc_global_pos.getDataSpan(*pixel_cont);
136 (*device_copy)(
137 vecmem::data::vector_view<unsigned long>(n_pixels, pixel_meas_device.identifier().data()),
138 vecmem::data::vector_view<unsigned long>(n_pixels, span_id.data())
139 )->ignore();
140 (*device_copy)(
141 vecmem::data::vector_view<std::array<float, 2>>(n_pixels, pixel_meas_device.local_position().data()),
142 vecmem::data::vector_view<std::array<float, 2>>(n_pixels, span_local_pos.data())
143 )->ignore();
144 (*device_copy)(
145 vecmem::data::vector_view<std::array<float, 4>>(n_pixels, pixel_meas_device.local_variance().data()),
146 vecmem::data::vector_view<std::array<float, 4>>(n_pixels, span_local_cov.data())
147 )->ignore();
148 (*device_copy)(
149 vecmem::data::vector_view<xAOD::ArrayFloat3>(n_pixels,
150 reinterpret_cast<xAOD::ArrayFloat3*>(pixel_meas_device.global_position().data())),
151 vecmem::data::vector_view<xAOD::ArrayFloat3>(n_pixels, span_global_pos.data())
152 )->ignore();
153 (*device_copy)(
154 vecmem::data::vector_view<unsigned int>(n_pixels, pixel_meas_device.module_id_hash().data()),
155 vecmem::data::vector_view<unsigned int>(n_pixels, span_id_hash.data())
156 )->wait();
157 }
158 { // Strips
159 auto span_id = s_acc_id.getDataSpan(*strip_cont);
160 auto span_id_hash = s_acc_id_hash.getDataSpan(*strip_cont);
161 auto span_local_pos = s_acc_loc_pos_x.getDataSpan(*strip_cont);
162 auto span_local_cov = s_acc_loc_cov_x.getDataSpan(*strip_cont);
163 CUDA_ERROR_CHECK(cudaMemcpy(span_id.data(), strip_meas_device.identifier().data(),
164 sizeof(unsigned long) * n_strips, cudaMemcpyDeviceToHost));
165 CUDA_ERROR_CHECK(cudaMemcpy(span_local_pos.data(), strip_meas_device.local_position().data(),
166 sizeof(float) * n_strips, cudaMemcpyDeviceToHost));
167 CUDA_ERROR_CHECK(cudaMemcpy(span_local_cov.data(), strip_meas_device.local_variance().data(),
168 sizeof(float) * n_strips, cudaMemcpyDeviceToHost));
169 CUDA_ERROR_CHECK(cudaMemcpy(span_id_hash.data(), strip_meas_device.module_id_hash().data(),
170 sizeof(unsigned int) * n_strips, cudaMemcpyDeviceToHost));
171 }
172
173 // ---- Register to SG
175 ATH_CHECK(pixelHandle.record(std::move(pixel_cont), std::move(pixel_aux)));
176
178 ATH_CHECK(stripHandle.record(std::move(strip_cont), std::move(strip_aux)));
179
180 // ---- Et voilĂ 
181 ATH_MSG_DEBUG("Converted " << n_pixels << " pixel clusters, "
182 << n_strips << " strip clusters");
183
184 m_nMeas += n_pixels + n_strips;
185 m_nPix += n_pixels;
186 m_nStrip += n_strips;
187
188 return StatusCode::SUCCESS;
189}
190
192{
193 ATH_MSG_DEBUG("Finalizing.");
194
195 ATH_MSG_DEBUG("Received total number of measurements = " << m_nMeas
196 << ", of which pixel clusters = " << m_nPix
197 << " and strip clusters = " << m_nStrip);
198
199 ATH_MSG_DEBUG("Successfully finalized");
200 return StatusCode::SUCCESS;
201}
202
203} // namespace ActsTrk
#define CUDA_ERROR_CHECK(EXP)
Helper macro used for checking cudaError_t type return values.
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
SG::ReadCondHandleKey< traccc::detector_conditions_description::buffer > m_deviceCondKey
std::atomic< int > m_nPix
The object counters for debug prints in finalize method {.
virtual StatusCode execute(const EventContext &ctx) const override
Function executing the algorithm.
SG::WriteHandleKey< xAOD::PixelClusterContainer > m_outputPixelKey
virtual StatusCode finalize() override
Function finalizing the algorthm.
SG::ReadHandleKey< traccc::edm::measurement_collection::buffer > m_inputMeasKey
virtual StatusCode initialize() override
Function initializing the algorithm.
ToolHandle< AthDevice::IMemoryResourcesTool > m_mrTool
SG::WriteHandleKey< xAOD::StripClusterContainer > m_outputStripKey
const ServiceHandle< StoreGateSvc > & detStore() const
a typed memory pool that saves time spent allocation small object.
Definition DataPool.h:63
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
Helper class to provide type-safe access to aux data.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
StatusCode convertMeasurementsOnGPU(cudaStream_t stream, vecmem::memory_resource &mr, vecmem::copy const &copy, traccc::itk_detector::view_type const &detector_view, traccc::detector_conditions_description::const_view const &detector_conditions_view, traccc::edm::measurement_collection::const_view::size_type nb_measurements, const traccc::edm::measurement_collection::const_view &input, DevicePixelMeasurementContainer::view::size_type &output_n_pixels, DeviceStripMeasurementContainer::view::size_type &output_n_strips, std::unique_ptr< DevicePixelMeasurementContainer::buffer > &output_pixel_meas, std::unique_ptr< DeviceStripMeasurementContainer::buffer > &output_strip_meas)
@ ALWAYS_TRACK_INDICES
Always track indices, regardless of the setting of the ownership policy.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
#define unlikely(x)
A struct mimicking std::array<float ,3> this structure is a temporary solution for our dynamic variab...
Definition ArrayFloat3.h:17