MCPcopy Index your code
hub / github.com/tensorpack/tensorpack / MultiProcessRunner

Class MultiProcessRunner

tensorpack/dataflow/parallel.py:142–238  ·  view source on GitHub ↗

Running a DataFlow in >=1 processes using Python multiprocessing utilities. It will fork the process that calls :meth:`__init__`, collect datapoints from `ds` in each process by a Python :class:`multiprocessing.Queue`. Note: 1. (Data integrity) An iterator cannot run faster

Source from the content-addressed store, hash-verified

140
141
142class MultiProcessRunner(ProxyDataFlow):
143 """
144 Running a DataFlow in >=1 processes using Python multiprocessing utilities.
145 It will fork the process that calls :meth:`__init__`, collect datapoints from `ds` in each
146 process by a Python :class:`multiprocessing.Queue`.
147
148 Note:
149 1. (Data integrity) An iterator cannot run faster automatically -- what's happening is
150 that the process will be forked ``num_proc`` times.
151 There will be ``num_proc`` dataflow running in parallel and **independently**.
152 As a result, we have the following guarantee on the dataflow correctness:
153
154 a. When ``num_proc=1``, this dataflow produces the same data as the
155 given dataflow in the same order.
156 b. When ``num_proc>1``, if each sample from the given dataflow is i.i.d.,
157 then this dataflow produces the **same distribution** of data as the given dataflow.
158 This implies that there will be duplication, reordering, etc.
159 You probably only want to use it for training.
160
161 For example, if your original dataflow contains no randomness and produces the same first datapoint,
162 then after parallel prefetching, the datapoint will be produced ``num_proc`` times
163 at the beginning.
164 Even when your original dataflow is fully shuffled, you still need to be aware of the
165 `Birthday Paradox <https://en.wikipedia.org/wiki/Birthday_problem>`_
166 and know that you&#x27;ll likely see duplicates.
167
168 To utilize parallelism with more strict data integrity, you can use
169 the parallel versions of :class:`MapData`: :class:`MultiThreadMapData`, :class:`MultiProcessMapData`.
170 2. This has more serialization overhead than :class:`MultiProcessRunnerZMQ` when data is large.
171 3. You can nest like this: ``MultiProcessRunnerZMQ(MultiProcessRunner(df, num_proc=a), num_proc=b)``.
172 A total of ``a`` instances of ``df`` worker processes will be created.
173 4. Fork happens in `__init__`. `reset_state()` is a no-op.
174 DataFlow in the worker processes will be reset at the time of fork.
175 5. This DataFlow does support windows. However, Windows requires more strict picklability on processes,
176 which means that some code that's forkable on Linux may not be forkable on Windows. If that happens you'll
177 need to re-organize some part of code that&#x27;s not forkable.
178 """
179
180 class _Worker(mp.Process):
181 def __init__(self, ds, queue, idx):
182 super(MultiProcessRunner._Worker, self).__init__()
183 self.ds = ds
184 self.queue = queue
185 self.idx = idx
186
187 def run(self):
188 enable_death_signal(_warn=self.idx == 0)
189 # reset all ds so each process will produce different data
190 self.ds.reset_state()
191 while True:
192 for dp in self.ds:
193 self.queue.put(dp)
194
195 def __init__(self, ds, num_prefetch, num_proc):
196 """
197 Args:
198 ds (DataFlow): input DataFlow.
199 num_prefetch (int): size of the queue to hold prefetched datapoints.

Callers 3

get_dataFunction · 0.85
get_dataFunction · 0.85
get_dataFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected