File indexing completed on 2025-01-18 09:55:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DDDIGI_DIGICONTAINERPROCESSOR_H
0014 #define DDDIGI_DIGICONTAINERPROCESSOR_H
0015
0016
0017 #include <DD4hep/Callback.h>
0018 #include <DDDigi/DigiData.h>
0019 #include <DDDigi/DigiEventAction.h>
0020 #include <DDDigi/DigiDepositMonitor.h>
0021 #include <DDDigi/DigiParallelWorker.h>
0022
0023
0024 #include <set>
0025
0026
0027 namespace dd4hep {
0028
0029
0030 namespace digi {
0031
0032
0033 class DigiDepositMonitor;
0034 class DigiSegmentContext;
0035 class DigiContainerSequence;
0036 class DigiContainerProcessor;
0037 class DigiContainerSequenceAction;
0038 class DigiMultiContainerProcessor;
0039
0040
0041
0042
0043
0044
0045
0046
0047 class DigiContainerProcessor : public DigiAction {
0048 public:
0049
0050 using action_t = DigiAction;
0051 using segment_t = DataSegment;
0052 using property_t = PropertyManager;
0053 using segmentation_t = DigiSegmentContext;
0054
0055
0056 struct input_t {
0057
0058 segment_t* segment;
0059
0060 Key key;
0061
0062 std::any* data;
0063 };
0064
0065
0066 struct output_t {
0067 int mask;
0068 segment_t& data;
0069 };
0070
0071
0072 struct predicate_t {
0073 using deposit_t = std::pair<const CellID, EnergyDeposit>;
0074 using callback_t = std::function<bool(const deposit_t&)>;
0075 callback_t callback { };
0076 uint32_t id { 0 };
0077 const segmentation_t* segmentation { nullptr };
0078
0079 predicate_t() = default;
0080 predicate_t(std::function<bool(const deposit_t&)> func, uint32_t i, const segmentation_t* s)
0081 : callback(std::move(func)), id(i), segmentation(s) {}
0082 predicate_t(predicate_t&& copy) = default;
0083 predicate_t(const predicate_t& copy) = default;
0084 predicate_t& operator = (predicate_t&& copy) = default;
0085 predicate_t& operator = (const predicate_t& copy) = default;
0086
0087 bool operator()(const deposit_t& deposit) const;
0088 static bool always_true(const deposit_t&) { return true; }
0089 static bool not_killed (const deposit_t& depo) { return 0 == (depo.second.flag&EnergyDeposit::KILLED); }
0090 };
0091
0092 struct env_t {
0093
0094 context_t& context;
0095
0096 const property_t& properties;
0097
0098 output_t& output;
0099 };
0100
0101
0102 struct work_t {
0103 env_t environ;
0104
0105 input_t input;
0106
0107
0108 bool has_input() const { return this->input.data->has_value(); }
0109
0110 Key input_key() const { return this->input.key; }
0111
0112 const std::type_info& input_type() const;
0113
0114 std::string input_type_name() const;
0115
0116 template <typename DATA> DATA* get_input(bool exc=false);
0117
0118 template <typename DATA> const DATA* get_input(bool exc=false) const;
0119 };
0120
0121
0122 DigiDepositMonitor* m_monitor { nullptr };
0123
0124 protected:
0125
0126 DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerProcessor);
0127
0128 public:
0129
0130 static const predicate_t& accept_all();
0131
0132 static const predicate_t& accept_not_killed();
0133
0134
0135 DigiContainerProcessor(const kernel_t& kernel, const std::string& name);
0136
0137 virtual ~DigiContainerProcessor();
0138
0139 virtual void adopt_monitor(DigiDepositMonitor* monitor);
0140
0141 virtual void execute(context_t& context, work_t& work, const predicate_t& predicate) const;
0142 };
0143
0144
0145 inline bool DigiContainerProcessor::predicate_t::operator()(const deposit_t& deposit) const {
0146 return this->callback(deposit);
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 class DigiDepositsProcessor : public DigiContainerProcessor {
0159 protected:
0160 std::function<void(context_t& context, DepositVector& cont, work_t& work, const predicate_t& predicate)> m_handleVector;
0161 std::function<void(context_t& context, DepositMapping& cont, work_t& work, const predicate_t& predicate)> m_handleMapping;
0162
0163 public:
0164
0165 using DigiContainerProcessor::DigiContainerProcessor;
0166
0167
0168 virtual void execute(context_t& context, work_t& work, const predicate_t& predicate) const;
0169 };
0170
0171 #define DEPOSIT_PROCESSOR_BIND_HANDLERS(X) \
0172 this->m_handleVector = std::bind( &X<DepositVector>, this, \
0173 std::placeholders::_1, \
0174 std::placeholders::_2, \
0175 std::placeholders::_3, \
0176 std::placeholders::_4); \
0177 this->m_handleMapping = std::bind( &X<DepositMapping>, this, \
0178 std::placeholders::_1, \
0179 std::placeholders::_2, \
0180 std::placeholders::_3, \
0181 std::placeholders::_4)
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 class DigiContainerSequence : public DigiContainerProcessor {
0192 protected:
0193
0194 using self_t = DigiContainerSequence;
0195 using processor_t = DigiContainerProcessor;
0196 using worker_t = DigiParallelWorker<processor_t,work_t,std::size_t,self_t&>;
0197 using workers_t = DigiParallelWorkers<worker_t>;
0198 friend class DigiParallelWorker<processor_t,work_t,std::size_t,self_t&>;
0199
0200 protected:
0201
0202
0203 bool m_parallel { false };
0204
0205 workers_t m_workers;
0206
0207 predicate_t m_worker_predicate = processor_t::accept_all();
0208
0209
0210 mutable std::mutex m_output_lock;
0211
0212 protected:
0213
0214 DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerSequence);
0215
0216 virtual ~DigiContainerSequence();
0217
0218
0219 worker_t* need_registered_worker(Key item_key) const;
0220
0221 public:
0222
0223 DigiContainerSequence(const kernel_t& kernel, const std::string& name);
0224
0225 virtual void set_predicate(const predicate_t& predicate);
0226
0227 virtual void adopt_processor(DigiContainerProcessor* action);
0228
0229 virtual void execute(context_t& context, work_t& work, const predicate_t& predicate) const;
0230 };
0231
0232
0233 struct DigiMultiProcessorParent {
0234 public:
0235 using action_t = DigiAction;
0236 using processor_t = DigiContainerProcessor;
0237 using env_t = processor_t::env_t;
0238 using segment_t = processor_t::segment_t;
0239 using predicate_t = processor_t::predicate_t;
0240 using output_t = processor_t::output_t;
0241 using property_t = processor_t::property_t;
0242 using work_item_t = processor_t::input_t;
0243 using work_items_t = std::vector<processor_t::input_t>;
0244 };
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 class DigiContainerSequenceAction : public DigiEventAction, public DigiMultiProcessorParent {
0256
0257 protected:
0258
0259 using self_t = DigiContainerSequenceAction;
0260
0261 struct work_t {
0262 env_t& environ;
0263 work_items_t& input_items;
0264 const self_t& parent;
0265 };
0266
0267 using worker_t = DigiParallelWorker<processor_t, work_t, std::size_t, self_t&>;
0268 using workers_t = DigiParallelWorkers<worker_t>;
0269 using predicate_t = processor_t::predicate_t;
0270 using reg_workers_t = std::map<Key::key_type, worker_t*>;
0271 using reg_processors_t = std::map<Key::key_type, processor_t*>;
0272 friend class DigiParallelWorker<processor_t, work_t, std::size_t, self_t&>;
0273
0274
0275 std::string m_input_segment { "inputs" };
0276
0277 int m_input_mask { 0x0 };
0278
0279 std::string m_output_segment { "outputs" };
0280
0281 int m_output_mask { 0x0 };
0282
0283
0284 workers_t m_workers { };
0285
0286 reg_processors_t m_registered_processors { };
0287
0288 reg_workers_t m_registered_workers { };
0289
0290 predicate_t m_worker_predicate { processor_t::accept_all() };
0291
0292
0293 mutable std::mutex m_output_lock { };
0294
0295 protected:
0296
0297 DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerSequenceAction);
0298
0299
0300 virtual ~DigiContainerSequenceAction();
0301
0302
0303 virtual void initialize();
0304
0305
0306 virtual void finalize();
0307
0308
0309 worker_t* need_registered_worker(Key item_key, bool exc=true) const;
0310
0311 public:
0312
0313 DigiContainerSequenceAction(const kernel_t& kernel, const std::string& name);
0314
0315 virtual void set_predicate(const predicate_t& predicate);
0316
0317 virtual void adopt_processor(DigiContainerProcessor* action, const std::string& container);
0318
0319 virtual void adopt_processor(DigiContainerProcessor* action, const std::vector<std::string>& containers);
0320
0321 virtual void execute(context_t& context) const override;
0322 };
0323
0324
0325
0326
0327
0328
0329
0330
0331 class DigiMultiContainerProcessor : public DigiEventAction, public DigiMultiProcessorParent {
0332 protected:
0333 using self_t = DigiMultiContainerProcessor;
0334 using worker_keys_t = std::vector<std::vector<Key> >;
0335
0336
0337 struct work_t {
0338 env_t& environ;
0339 work_items_t& items;
0340 const self_t& parent;
0341 };
0342 using worker_t = DigiParallelWorker<processor_t, work_t, std::size_t, self_t&>;
0343 using workers_t = DigiParallelWorkers<worker_t>;
0344 friend class DigiParallelWorker<processor_t, work_t, std::size_t, self_t&>;
0345
0346 protected:
0347
0348 std::string m_input_segment { "inputs" };
0349
0350 std::vector<int> m_input_masks { };
0351
0352 std::string m_output_segment { "outputs" };
0353
0354 int m_output_mask { 0x0 };
0355
0356
0357 std::map<std::string, std::vector<processor_t*> > m_processors;
0358 std::map<Key::itemkey_type, std::vector<worker_t*> > m_worker_map;
0359
0360
0361 std::set<Key> m_work_items;
0362
0363 worker_keys_t m_worker_keys;
0364
0365 std::vector<processor_t*> m_actions;
0366
0367 predicate_t m_worker_predicate = processor_t::accept_all();
0368
0369 mutable std::mutex m_output_lock;
0370
0371
0372 workers_t m_workers;
0373
0374 protected:
0375
0376 DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiMultiContainerProcessor);
0377
0378 virtual ~DigiMultiContainerProcessor();
0379
0380 void initialize();
0381
0382 public:
0383
0384 DigiMultiContainerProcessor(const kernel_t& kernel, const std::string& name);
0385 const std::vector<Key>& worker_keys(size_t worker_id) const {
0386 return this->m_worker_keys.at(worker_id);
0387 }
0388 const std::vector<int>& input_masks() const {
0389 return this->m_input_masks;
0390 }
0391
0392 virtual void set_predicate(const predicate_t& predicate);
0393
0394 virtual void adopt_processor(DigiContainerProcessor* action, const std::vector<std::string>& containers);
0395
0396 virtual void execute(context_t& context) const;
0397 };
0398 }
0399 }
0400 #endif