ATLAS Offline Software
CaloGPUOutput.cxx
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
7 #include "CaloGPUOutput.h"
8 
10 
11 #include <unordered_map>
12 
13 using namespace CaloRecGPU;
14 
15 CaloGPUOutput::CaloGPUOutput(const std::string & type, const std::string & name, const IInterface * parent):
17  m_constantDataSaved(false)
18 {
19  declareInterface<CaloClusterGPUProcessor> (this);
20 }
21 
22 StatusCode CaloGPUOutput::execute(const EventContext & ctx, const ConstantDataHolder & constant_data, EventDataHolder & event_data, void * /*temporary_buffer*/) const
23 {
24  if (!m_constantDataSaved.load())
25  {
26  std::lock_guard<std::mutex> lock_guard(m_mutex);
27  if (!m_constantDataSaved.load())
28  {
29  const auto err1 = StandaloneDataIO::save_constants_to_folder(std::string(m_savePath), constant_data.m_geometry_dev,
32  {
33  return StatusCode::FAILURE;
34  }
35  m_constantDataSaved.store(true);
36  }
37  }
38 
40 
41  if (m_onlyCellInfo)
42  {
43  const auto err2 = StandaloneDataIO::save_cell_info_to_folder(ctx.evt(), std::string(m_savePath), cell_info, m_filePrefix, m_fileSuffix, m_numWidth);
44 
46  {
47  return StatusCode::FAILURE;
48  }
49 
50  return StatusCode::SUCCESS;
51  }
52 
53 
56 
57  std::unordered_map<int, int> tag_map;
58 
60  {
61  std::vector<int> cluster_order(clusters->number);
62 
63  std::iota(cluster_order.begin(), cluster_order.end(), 0);
64 
65  std::sort(cluster_order.begin(), cluster_order.end(), [&](const int a, const int b)
66  {
67  if (clusters->seedCellID[a] < 0)
68  {
69  return false;
70  //This means that clusters with no cells
71  //(marked as invalid) always compare lower,
72  //so they appear in the end.
73  }
74  else if (clusters->seedCellID[b] < 0)
75  {
76  return true;
77  }
78  return clusters->clusterEt[a] > clusters->clusterEt[b];
79  } );
80 
81  int real_cluster_numbers = clusters->number;
82 
83  for (size_t i = 0; i < cluster_order.size(); ++i)
84  {
85  const int this_id = cluster_order[i];
86  if (clusters->seedCellID[this_id] < 0)
87  {
88  tag_map[this_id] = -1;
89  --real_cluster_numbers;
90  }
91  else
92  {
93  tag_map[this_id] = i;
94  }
95  }
96 
97  const Helpers::CPU_object<ClusterInfoArr> temp_clusters(clusters);
98 
99  clusters->number = real_cluster_numbers;
100 
101  for (int i = 0; i < temp_clusters->number; ++i)
102  {
103  clusters->clusterEnergy[i] = temp_clusters->clusterEnergy[cluster_order[i]];
104  clusters->clusterEt[i] = temp_clusters->clusterEt[cluster_order[i]];
105  clusters->clusterEta[i] = temp_clusters->clusterEta[cluster_order[i]];
106  clusters->clusterPhi[i] = temp_clusters->clusterPhi[cluster_order[i]];
107  clusters->seedCellID[i] = temp_clusters->seedCellID[cluster_order[i]];
108  }
109 
110  }
111  size_t shared_count = 0;
112  for (int i = 0; i < NCaloCells; ++i)
113  {
114  if (!cell_info->is_valid(i))
115  {
116  continue;
117  }
118  const ClusterTag this_tag = cell_state->clusterTag[i];
119  if (!this_tag.is_part_of_cluster())
120  {
121  cell_state->clusterTag[i] = ClusterTag::make_invalid_tag();
122  }
123  else if (this_tag.is_part_of_cluster() && m_sortedAndCutClusters)
124  {
125  const int old_idx = this_tag.cluster_index();
126  const int new_idx = tag_map[old_idx];
127  const int old_idx2 = this_tag.is_shared_between_clusters() ? this_tag.secondary_cluster_index() : -1;
128  const int new_idx2 = old_idx2 >= 0 ? tag_map[old_idx2] : -1;
129  if (new_idx < 0 && new_idx2 < 0)
130  {
131  cell_state->clusterTag[i] = ClusterTag::make_invalid_tag();
132  }
133  else if (new_idx < 0)
134  {
135  cell_state->clusterTag[i] = ClusterTag::make_tag(new_idx2);
136  }
137  else if (new_idx2 < 0)
138  {
139  cell_state->clusterTag[i] = ClusterTag::make_tag(new_idx);
140  }
141  else
142  {
143  ++shared_count;
144  cell_state->clusterTag[i] = ClusterTag::make_tag(new_idx, this_tag.secondary_cluster_weight(), new_idx2);
145  }
146  }
147  }
148 
149 
150  ATH_MSG_INFO("Clusters: " << clusters->number << " (" << tag_map.size() << " total)");
151  ATH_MSG_INFO("Shared Cells: " << shared_count);
152 
153 
154  const auto err2 = StandaloneDataIO::save_event_to_folder(ctx.evt(), std::string(m_savePath), cell_info, cell_state, clusters,
155  m_filePrefix, m_fileSuffix, m_numWidth);
156 
158  {
159  return StatusCode::FAILURE;
160  }
161 
162  return StatusCode::SUCCESS;
163 
164 
165 }
CaloGPUOutput.h
StandaloneDataIO::save_constants_to_folder
static ErrorState save_constants_to_folder(const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::GeometryArr > &geo, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellNoiseArr > &noise, const std::string &prefix="", const std::string &suffix="", const bool output_errors=true)
Definition: StandaloneDataIO.h:295
CaloRecGPU::ClusterTag::secondary_cluster_index
constexpr int32_t secondary_cluster_index() const
Definition: TagDefinitions.h:253
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloRecGPU::ClusterTag::is_shared_between_clusters
constexpr bool is_shared_between_clusters() const
Definition: TagDefinitions.h:273
CaloGPUOutput::execute
virtual StatusCode execute(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, CaloRecGPU::EventDataHolder &event_data, void *temporary_buffer) const override
Process the clusters on GPU.
Definition: CaloGPUOutput.cxx:22
CaloRecGPU::Helpers::SimpleHolder
Holds one objects of type \T in memory context Context.
Definition: Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h:1067
CaloRecGPU::EventDataHolder::m_cell_state_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellStateArr > m_cell_state_dev
Definition: DataHolders.h:89
CaloRecGPU::EventDataHolder::m_clusters_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::ClusterInfoArr > m_clusters_dev
Definition: DataHolders.h:90
StandaloneDataIO::save_event_to_folder
static ErrorState save_event_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellStateArr > &cell_state, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
Definition: StandaloneDataIO.h:323
CaloRecGPU::ClusterTag
Definition: TagDefinitions.h:222
CaloRecGPU::EventDataHolder::m_cell_info_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellInfoArr > m_cell_info_dev
Definition: DataHolders.h:88
CaloRecGPU::ClusterTag::cluster_index
constexpr int32_t cluster_index() const
Definition: TagDefinitions.h:243
StandaloneDataIO::ErrorState::OK
@ OK
CaloRecGPU::EventDataHolder
Definition: DataHolders.h:35
CaloGPUOutput::m_onlyCellInfo
Gaudi::Property< bool > m_onlyCellInfo
If true, only output cell info (useful for reducing disk usage when running the full standalone versi...
Definition: CaloGPUOutput.h:73
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CaloGPUOutput::m_numWidth
Gaudi::Property< unsigned int > m_numWidth
The number of digits to reserve for the events.
Definition: CaloGPUOutput.h:63
test_pyathena.parent
parent
Definition: test_pyathena.py:15
StandaloneDataIO.h
CaloRecGPU::NCaloCells
constexpr int NCaloCells
Definition: BaseDefinitions.h:13
CaloRecGPU::ConstantDataHolder::m_cell_noise_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellNoiseArr > m_cell_noise_dev
Definition: DataHolders.h:30
CaloGPUOutput::m_savePath
Gaudi::Property< std::string > m_savePath
The path specifying the folder to which the files should be saved.
Definition: CaloGPUOutput.h:48
CaloRecGPU::ConstantDataHolder::m_geometry_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::GeometryArr > m_geometry_dev
Definition: DataHolders.h:28
CaloGPUOutput::CaloGPUOutput
CaloGPUOutput(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloGPUOutput.cxx:15
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
CaloGPUOutput::m_filePrefix
Gaudi::Property< std::string > m_filePrefix
The prefix of the saved files.
Definition: CaloGPUOutput.h:53
CaloRecGPU::ClusterTag::is_part_of_cluster
constexpr bool is_part_of_cluster() const
Definition: TagDefinitions.h:233
CaloGPUOutput::m_mutex
std::mutex m_mutex
This mutex is locked when saving the constant data on the first event to ensure thread safety.
Definition: CaloGPUOutput.h:84
StandaloneDataIO::save_cell_info_to_folder
static ErrorState save_cell_info_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
Definition: StandaloneDataIO.h:391
a
TList * a
Definition: liststreamerinfos.cxx:10
CaloGPUOutput::m_constantDataSaved
std::atomic< bool > m_constantDataSaved
A flag to signal that the constant data has been adequately saved.
Definition: CaloGPUOutput.h:79
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
CaloRecGPU::ConstantDataHolder
Definition: DataHolders.h:19
CaloGPUOutput::m_fileSuffix
Gaudi::Property< std::string > m_fileSuffix
The suffix of the saved files.
Definition: CaloGPUOutput.h:58
AthAlgTool
Definition: AthAlgTool.h:26
CaloRecGPU
Definition: BaseDefinitions.h:11
CaloRecGPU::ClusterTag::secondary_cluster_weight
constexpr int32_t secondary_cluster_weight() const
Definition: TagDefinitions.h:263
CaloGPUOutput::m_sortedAndCutClusters
Gaudi::Property< bool > m_sortedAndCutClusters
If true, sort the clusters by transverse energy and compactify the tags to ensure sequentiality.
Definition: CaloGPUOutput.h:68