HepMC3 event record library
ReaderMT.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // This file is part of HepMC
4 // Copyright (C) 2014-2020 The HepMC collaboration (see AUTHORS for details)
5 //
6 #ifndef HEPMC3_READERMT_H
7 #define HEPMC3_READERMT_H
8 ///
9 /// @file ReaderMT.h
10 /// @brief Definition of class \b ReaderMT
11 ///
12 /// @class HepMC3::ReaderMT
13 /// @brief Multithreader GenEvent I/O parsing
14 ///
15 /// @ingroup IO
16 ///
17 #include <set>
18 #include <string>
19 #include <fstream>
20 #include <istream>
21 #include <iterator>
22 #include <thread>
23 #include "HepMC3/Reader.h"
24 #include "HepMC3/GenEvent.h"
25 namespace HepMC3 {
26 template <class T, size_t m_number_of_threads> class ReaderMT : public Reader
27 {
28 private:
29  bool m_go_try_cache; //!< Flag to trigger using the cached event
30  std::vector< std::shared_ptr<T> > m_readers; //!< Vector of all active readers
31  std::vector< std::pair<GenEvent, bool> > m_events; //!< Vector of events
32  std::vector< std::thread > m_threads;
33  static void read_function(std::pair<GenEvent,bool>& e, std::shared_ptr<T> r)
34  {
35  e.second = r->read_event(e.first);
36  r->skip(m_number_of_threads-1);
37  if (r->failed()) r->close();
38  }
39 public:
40  ReaderMT(const std::string& filename): m_go_try_cache(true) {
41  m_events.reserve(m_number_of_threads);
42  m_readers.reserve(m_number_of_threads);
43  m_threads.reserve(m_number_of_threads);
44  for (size_t i = 0; i < m_number_of_threads; ++i) {
45  m_readers.push_back(std::make_shared<T>(filename));
46  m_readers.back()->skip(m_number_of_threads-1-i);
47  }
48  }
49  ~ReaderMT() {
50  m_readers.clear();
51  m_events.clear();
52  m_threads.clear();
53  }
54  bool skip(const int) override {
55  return false;///Not implemented
56  }
57  bool read_event(GenEvent& evt) override {
58  if ( !m_events.empty() ) {
59  evt = m_events.back().first;
60  m_events.pop_back();
61  return true;
62  }
63  m_events.clear();
64  m_threads.clear();
65  m_go_try_cache = true;
66  m_threads.reserve(m_number_of_threads);
67  m_events.reserve(m_number_of_threads);
68  for (size_t i = 0; i < m_number_of_threads; ++i) {
69  m_events.push_back(std::pair<GenEvent, bool>(GenEvent(Units::GEV,Units::MM), true));
70  m_threads.push_back(std::thread(read_function, std::ref(m_events.at(i)), m_readers.at(i)));
71  }
72  for (auto& th : m_threads) {
73  th.join();
74  }
75  m_threads.clear();
76 
77  m_events.erase(std::remove_if(m_events.begin(), m_events.end(),[](std::pair<GenEvent, bool>& x) {
78  return !x.second;
79  }), m_events.end());
80 
81  if (m_events.empty()) {
82  m_go_try_cache = false;
83  return false;
84  }
85  evt = m_events.back().first;
86  m_events.pop_back();
87  return true;
88  }
89  bool failed() override {
90  for (auto& reader: m_readers) if (reader && !reader->failed()) return false;
91  if ( !m_events.empty() ) return false;
92  if ( m_go_try_cache ) return false;
93  return true;
94  }
95  void close() override {
96  for (auto& reader: m_readers) if (reader) reader->close();
97  }
98 };
99 }
100 #endif
std::vector< std::pair< GenEvent, bool > > m_events
Vector of events.
Definition: ReaderMT.h:31
Definition of interface Reader.
bool failed() override
Get file and/or stream error state.
Definition: ReaderMT.h:89
std::vector< std::shared_ptr< T > > m_readers
Vector of all active readers.
Definition: ReaderMT.h:30
void close() override
Close file and/or stream.
Definition: ReaderMT.h:95
bool read_event(GenEvent &evt) override
Fill next event from input into evt.
Definition: ReaderMT.h:57
Multithreader GenEvent I/O parsing.
Definition: ReaderMT.h:26
Stores event-related information.
Definition: GenEvent.h:41
Definition of class GenEvent.
bool m_go_try_cache
Flag to trigger using the cached event.
Definition: ReaderMT.h:29
Base class for all I/O readers.
Definition: Reader.h:25
bool skip(const int) override
skip or fast forward reading of some events
Definition: ReaderMT.h:54