RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
MultithreadedMolSupplier.h
Go to the documentation of this file.
1//
2// Copyright (C) 2020 Shrey Aryan
3//
4// @@ All Rights Reserved @@
5// This file is part of the RDKit.
6// The contents are covered by the terms of the BSD license
7// which is included in the file license.txt, found at the root
8// of the RDKit source tree.
9//
10#ifdef RDK_BUILD_THREADSAFE_SSS
11#ifndef MULTITHREADED_MOL_SUPPLIER
12#define MULTITHREADED_MOL_SUPPLIER
13
18#include <RDGeneral/RDLog.h>
19#include <RDGeneral/RDThreads.h>
20#include <RDGeneral/StreamOps.h>
21
22#include "FileParsers.h"
23#include "MolSupplier.h"
24
25#include <atomic>
26#include <cstddef>
27#include <functional>
28#include <memory>
29#include <mutex>
30#include <string>
31#include <thread>
32#include <tuple>
33#include <vector>
34
35namespace RDKit {
36namespace v2 {
37namespace FileParsers {
38class RDKIT_FILEPARSERS_EXPORT MultithreadedMolSupplier : public MolSupplier {
39 //! this is an abstract base class to concurrently supply molecules one at a
40 //! time
41 public:
42 using readCallBackFn_t =
43 std::function<std::string(const std::string &, unsigned int)>;
44 using nextCallBackFn_t =
45 std::function<void(RWMol &, const MultithreadedMolSupplier &)>;
46 using writeCallBackFn_t =
47 std::function<void(RWMol &, const std::string &, unsigned int)>;
48
49 using inputQueue_t =
50 ConcurrentQueue<std::tuple<std::string, unsigned int, unsigned int>>;
51 using outputQueue_t =
52 ConcurrentQueue<std::tuple<RWMol *, std::string, unsigned int>>;
53
54 struct Parameters {
55 unsigned int numWriterThreads = 1;
56 size_t sizeInputQueue = 5;
57 size_t sizeOutputQueue = 5;
58 };
59
60 MultithreadedMolSupplier() {}
61
62 // Derived classes MUST have a destructor that calls close
63 // to properly end threads while the instance is alive
64 ~MultithreadedMolSupplier() override { close(); }
65
66 //! shut down the supplier
67 void close() final;
68
69 //! pop elements from the output queue
70 std::unique_ptr<RWMol> next() final;
71
72 //! returns true when all records have been read from the supplier
73 bool atEnd() final;
74
75 //! included for the interface. Python wrappers check this
76 //! each time next() is called. It is not used in the C++ code.
77 virtual bool getEOFHitOnRead() const = 0;
78
79 //! returns the record id of the last extracted item
80 //! Note: d_LastRecordId = 0, initially therefore the value 0 is returned
81 //! if and only if the function is called before extracting the first
82 //! record
83 unsigned int getLastRecordId() const;
84
85 //! returns the text block for the last extracted item
86 std::string getLastItemText() const;
87
88 //! sets the callback to be applied to molecules before they are returned by
89 ///! the next() function
90 /*!
91 \param cb: a function that takes a reference to an RWMol and a const
92 reference to the MultithreadedMolSupplier. This can modify the molecule in
93 place
94
95 */
96 void setNextCallback(nextCallBackFn_t cb) { nextCallback = cb; }
97
98 //! sets the callback to be applied to molecules after they are processed, but
99 ///! before they are written to the output queue
100 /*!
101 \param cb: a function that takes a reference to an RWMol, a const reference
102 to the string record, and an unsigned int record id. This can modify the
103 molecule in place
104 */
105 void setWriteCallback(writeCallBackFn_t cb) { writeCallback = cb; }
106
107 //! sets the callback to be applied to input text records before they are
108 ///! added to the input queue
109 /*!
110 \param cb: a function that takes a const reference to the string record and
111 an unsigned int record id and returns the modified string record
112 */
113 void setReadCallback(readCallBackFn_t cb) { readCallback = cb; }
114
115 //! not yet implemented
116 void init() final{};
117
118 //! not yet implemented
119 void reset() final;
120
121 protected:
122 void initFromSettings(bool takeOwnership, const Parameters &params);
123
124 //! extracts next record from the input file or stream
125 virtual bool extractNextRecord(std::string &record, unsigned int &lineNum,
126 unsigned int &index) = 0;
127
128 //! processes the record into an RWMol object
129 virtual std::unique_ptr<RWMol> processMoleculeRecord(
130 const std::string &record, unsigned int lineNum) = 0;
131
132 //!< stores last extracted record id
133 std::atomic<unsigned int> d_lastRecordId = 0;
134
135 int d_line = 0; //!< line number we are currently on
136 unsigned int d_currentRecordId = 1; //!< current record id
137
138 //!< concurrent input queue
139 std::unique_ptr<inputQueue_t> d_inputQueue;
140
141 //!< concurrent output queue
142 std::unique_ptr<outputQueue_t> d_outputQueue;
143
144 Parameters d_params;
145
146 private:
147 //! Close down any external streams
148 void closeStreams();
149
150 //! starts reader and writer threads
151 void startThreads();
152
153 //! finalizes the reader and writer threads
154 void endThreads();
155
156 //! reads lines from input stream to populate the input queue
157 void reader();
158
159 //! parses lines from the input queue converting them to RWMol objects
160 //! populating the output queue
161 void writer();
162
163 //! disable automatic copy constructors and assignment operators
164 //! for this class and its subclasses. They will likely be
165 //! carrying around stream pointers and copying those is a recipe
166 //! for disaster.
167 MultithreadedMolSupplier(const MultithreadedMolSupplier &) = delete;
168
169 MultithreadedMolSupplier &operator=(const MultithreadedMolSupplier &) =
170 delete;
171
172 std::atomic<bool> df_started = false;
173 std::atomic<bool> df_forceStop = false;
174
175 std::mutex d_threadCounterMutex;
176 unsigned int d_threadEndCounter{1}; //!< thread counter
177 std::vector<std::thread> d_writerThreads; //!< vector writer threads
178 std::thread d_readerThread; //!< single reader thread
179
180 std::string d_lastItemText; //!< stores last extracted record
181
182 readCallBackFn_t readCallback = nullptr;
183 nextCallBackFn_t nextCallback = nullptr;
184 writeCallBackFn_t writeCallback = nullptr;
185};
186} // namespace FileParsers
187} // namespace v2
188} // namespace RDKit
189#endif
190#endif
#define RDKIT_FILEPARSERS_EXPORT
Definition export.h:221
Std stuff.