ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleCalibratorExampleAlg.cxx
Go to the documentation of this file.
1//
2// Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3//
4
5// Local include(s).
7
9
10// Framework include(s).
15
16// VecMem include(s).
17#include <vecmem/memory/cuda/device_memory_resource.hpp>
18#include <vecmem/memory/host_memory_resource.hpp>
19#include <vecmem/utils/cuda/copy.hpp>
20
21// System include(s).
22#include <cstring>
23
24namespace AthCUDAExamples {
25
27
28 // Initialize the keys.
29 ATH_CHECK(m_inputKey.initialize());
30 ATH_CHECK(m_outputKey.initialize());
31
32 // Initialize the tools.
33 ATH_CHECK(m_hostMR.retrieve());
34 ATH_CHECK(m_deviceMR.retrieve());
35
36 // Print some information about the configuration:
37 ATH_MSG_INFO("Input container key: " << m_inputKey);
38 ATH_MSG_INFO("Output container key: " << m_outputKey);
39
40 // Return gracefully.
41 return StatusCode::SUCCESS;
42}
43
45 const EventContext& ctx) const {
46
47 // Retrieve the input container.
48 auto inputHandle = SG::makeHandle(m_inputKey, ctx);
49 const xAOD::TrackParticleContainer* input = inputHandle.cptr();
50 if (input == nullptr) {
51 ATH_MSG_ERROR("Failed to retrieve input container from: " << m_inputKey);
52 return StatusCode::FAILURE;
53 }
54
55 // The number of input/output tracks.
56 const std::size_t nTracks = input->size();
57
58 // If the input container is empty, then create an empty output container, and
59 // be done with it.
60 if (nTracks == 0) {
61 auto output = std::make_unique<xAOD::TrackParticleContainer>();
62 auto outputAux = std::make_unique<xAOD::AuxContainerBase>();
63 auto outputHandle = SG::makeHandle(m_outputKey, ctx);
64 ATH_CHECK(outputHandle.record(std::move(output), std::move(outputAux)));
65 return StatusCode::SUCCESS;
66 }
67
68 // The object managing CUDA memory copies.
69 vecmem::cuda::copy copy;
70
71 // Construct input buffer(s).
72 TrackParticleContainer::buffer inputHostBuffer(input->size(), m_hostMR->mr());
73 TrackParticleContainer::buffer inputDeviceBuffer(input->size(),
74 m_deviceMR->mr());
75
76 // Copy the relevant data into the input buffer.
77 static const SG::AuxElement::ConstAccessor<float> thetaAcc("theta");
78 static const SG::AuxElement::ConstAccessor<float> phiAcc("phi");
79 static const SG::AuxElement::ConstAccessor<float> qOverPAcc("qOverP");
80 std::memcpy(inputHostBuffer.get<0>().ptr(), thetaAcc.getDataArray(*input),
81 nTracks * sizeof(float));
82 std::memcpy(inputHostBuffer.get<1>().ptr(), phiAcc.getDataArray(*input),
83 nTracks * sizeof(float));
84 std::memcpy(inputHostBuffer.get<2>().ptr(), qOverPAcc.getDataArray(*input),
85 nTracks * sizeof(float));
86
87 // Copy the input buffer to the device.
88 copy(inputHostBuffer, inputDeviceBuffer)->wait();
89
90 // Construct output buffer(s).
91 TrackParticleContainer::buffer outputDeviceBuffer(input->size(),
92 m_deviceMR->mr());
93 TrackParticleContainer::buffer outputHostBuffer(input->size(),
94 m_hostMR->mr());
95
96 // Run the kernel.
97 ATH_CHECK(calibrateOnGPU(inputDeviceBuffer, outputDeviceBuffer));
98
99 // Get the output back to the host.
100 copy(outputDeviceBuffer, outputHostBuffer)->wait();
101
102 // Construct the output container.
103 auto outputAux = std::make_unique<xAOD::AuxContainerBase>();
104 SG::copyAuxStoreThinned(*(input->getConstStore()), *outputAux, nullptr);
105 std::memcpy(outputAux->getData(thetaAcc.auxid(), nTracks, nTracks),
106 outputHostBuffer.get<0>().ptr(), nTracks * sizeof(float));
107 std::memcpy(outputAux->getData(phiAcc.auxid(), nTracks, nTracks),
108 outputHostBuffer.get<1>().ptr(), nTracks * sizeof(float));
109 std::memcpy(outputAux->getData(qOverPAcc.auxid(), nTracks, nTracks),
110 outputHostBuffer.get<2>().ptr(), nTracks * sizeof(float));
111 auto output = std::make_unique<xAOD::TrackParticleContainer>();
112 for (std::size_t i = 0; i < nTracks; ++i) {
113 output->push_back(new xAOD::TrackParticle());
114 }
115 output->setStore(outputAux.get());
116
117 // Record the output container.
118 auto outputHandle = SG::makeHandle(m_outputKey, ctx);
119 ATH_CHECK(outputHandle.record(std::move(output), std::move(outputAux)));
120
121 // Return gracefully.
122 return StatusCode::SUCCESS;
123}
124
125} // namespace AthCUDAExamples
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
ToolHandle< AthDevice::IMemoryResourceTool > m_deviceMR
Device memory resource tool to use.
virtual StatusCode execute(const EventContext &ctx) const override
Function executing the algorithm.
ToolHandle< AthDevice::IMemoryResourceTool > m_hostMR
Host memory resource tool to use.
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_inputKey
The input container.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_outputKey
The output container.
virtual StatusCode initialize() override
Function initialising the algorithm.
Helper to copy an aux store while applying thinning.
StatusCode calibrateOnGPU(const TrackParticleContainer::const_view &input, TrackParticleContainer::view &output)
Perform the transformation on an NVIDIA GPU.
void copyAuxStoreThinned(const SG::IConstAuxStore &orig, SG::IAuxStore &copy, const SG::ThinningInfo *info)
Helper to copy an aux store while applying thinning.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".