def make_worker_pool(<EOL>processes=None,<EOL>initializer=None,<EOL>initializer_kwargs_per_process=None,<EOL>max_tasks_per_worker=None):
if not processes:<EOL><INDENT>processes = cpu_count()<EOL><DEDENT>pool_kwargs = {<EOL>'<STR_LIT>': processes,<EOL>}<EOL>if max_tasks_per_worker:<EOL><INDENT>pool_kwargs["<STR_LIT>"] = max_tasks_per_worker<EOL><DEDENT>if initializer:<EOL><INDENT>if initializer_kwargs_per_process:<EOL><INDENT>assert len(initializer_kwargs_per_process) == processes<EOL>kwargs_queue = Queue()<EOL>kwargs_queue_backup = Queue()<EOL>for kwargs in initializer_kwargs_per_process:<EOL><INDENT>kwargs_queue.put(kwargs)<EOL>kwargs_queue_backup.put(kwargs)<EOL><DEDENT>pool_kwargs["<STR_LIT>"] = worker_init_entry_point<EOL>pool_kwargs["<STR_LIT>"] = (<EOL>initializer, kwargs_queue, kwargs_queue_backup)<EOL><DEDENT>else:<EOL><INDENT>pool_kwargs["<STR_LIT>"] = initializer<EOL><DEDENT><DEDENT>worker_pool = Pool(**pool_kwargs)<EOL>print("<STR_LIT>" % str(worker_pool))<EOL>pprint(pool_kwargs)<EOL>return worker_pool<EOL>
Convenience wrapper to create a multiprocessing.Pool.

This function adds support for per-worker initializer arguments, which are
not natively supported by the multiprocessing module. The motivation for
this feature is to support allocating each worker to a (different) GPU.

IMPLEMENTATION NOTE:
    The per-worker initializer arguments are implemented using a Queue. Each
    worker reads its arguments from this queue when it starts. When it
    terminates, it adds its initializer arguments back to the queue, so a
    future process can initialize itself using these arguments.

    There is one issue with this approach, however. If a worker crashes, it
    never repopulates the queue of initializer arguments. This will prevent
    any future worker from re-using those arguments. To deal with this
    issue we add a second 'backup queue'. This queue always contains the
    full set of initializer arguments: whenever a worker reads from it, it
    always pushes the pop'd args back to the end of the queue immediately.
    If the primary arg queue is ever empty, then workers will read
    from this backup queue.

Parameters
----------
processes : int
    Number of workers. Default: num CPUs.

initializer : function, optional
    Init function to call in each worker

initializer_kwargs_per_process : list of dict, optional
    Arguments to pass to initializer function for each worker. Length of
    list must equal the number of workers.

max_tasks_per_worker : int, optional
    Restart workers after this many tasks. Requires Python >=3.2.

Returns
-------
multiprocessing.Pool