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"
25namespace HepMC3 {
26template <class T, size_t m_number_of_threads> class ReaderMT : public Reader
27{
28private:
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 }
39public:
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
Definition of class GenEvent.
Definition of interface Reader.
Stores event-related information.
Definition: GenEvent.h:41
Multithreader GenEvent I/O parsing.
Definition: ReaderMT.h:27
std::vector< std::pair< GenEvent, bool > > m_events
Vector of events.
Definition: ReaderMT.h:31
bool m_go_try_cache
Flag to trigger using the cached event.
Definition: ReaderMT.h:29
bool read_event(GenEvent &evt) override
Fill next event from input into evt.
Definition: ReaderMT.h:57
bool failed() override
Get file and/or stream error state.
Definition: ReaderMT.h:89
bool skip(const int) override
skip or fast forward reading of some events
Definition: ReaderMT.h:54
void close() override
Close file and/or stream.
Definition: ReaderMT.h:95
std::vector< std::shared_ptr< T > > m_readers
Vector of all active readers.
Definition: ReaderMT.h:30
Base class for all I/O readers.
Definition: Reader.h:25
HepMC3 main namespace.