B
    ~d                 @   sJ   d Z ddlZddlmZmZ ddlmZ ddlmZ dd Z	dd
dZ
dS )zUtilities for multi-processing
    N)QueueProcess)
itemgetter   )progress_barc          
   C   sh   xb|  \}}|dkrP y||| |f W q tk
r^ } z|||f W dd}~X Y qX qW dS )a  Iterate through a Queue, call, ``func`, and Queue the result

    Parameters
    ----------
    func : `callable`
        any function that can take an element of the input `Queue` as
        the only argument

    q_in : `multiprocessing.queue.Queue`
        the input `Queue`

    q_out : `multiprocessing.queue.Queue`
        the output `Queue`

    Notes
    -----
    To close the input `Queue`, add ``(None, None)`` as the last item
    N)getput	Exception)funcq_inq_outidxargexc r   Z/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/gwpy/utils/mp.py_process_in_out_queues   s    r   Fc                s  | dddk	rtdt t|rdt|ts:t||d< t|ttfrX|	dt
| tf |nd| dkr fdd}tt||S t t  fd	d
t| D }x|D ]}d|_|  qW fdd
t|D }xt| D ]}	d qW g }
x6tt
|D ]&}	 }r,  |
| qW x|D ]}|  qBW rb  dd
 t|
tddD }x|D ]}
t|
tr|
qW |S )a  Map a function over a list of inputs using multiprocess

    This essentially duplicates `multiprocess.map` but allows for
    arbitrary functions (that aren't necessarily importable)

    Parameters
    ----------
    nproc : `int`
        number of processes to use, if ``1`` is given, the current process
        is used, and no child processes are forked

    func : `callable`
        the function to call in each iteration, should take a single
        argument that is the next element from ``inputs``

    inputs : `iterable`
        iterable (e.g. `list`) of inputs, each element of which is
        passed to ``func`` in one of the child processes

    verbose : `bool`, `str`, optional
        if `True`, print progress to the console as a bar, pass a
        `str` to customise the heading for the progress bar, default: `False`,
        (default heading ``'Processing:'`` if ``verbose=True`)

    Returns
    -------
    outputs : `list`
        the `list` of results from calling ``func(x)`` for each element
        of ``inputs``
    Zraise_exceptionsNzthe `raise_exceptions` keyword to multiprocess_with_queues is deprecated, and will be removed in a future release, all exceptions will be raised if they occurdesctotalr   c          	      s   z | S r d X d S )Nr   )update)x)r
   pbarr   r   _innert   s    z(multiprocess_with_queues.<locals>._innerc                s   g | ]}t t fd qS ))targetargs)r   r   ).0_)r
   r   r   r   r   
<listcomp>   s   z,multiprocess_with_queues.<locals>.<listcomp>Tc                s   g | ]} j |d dqS )F)block)r   )r   r   )r   r   r   r      s    )NNc             S   s   g | ]\}}|qS r   r   )r   r   outr   r   r   r      s    r   )key)popwarningswarnDeprecationWarningbool
isinstancestrlisttuple
setdefaultlenr   mapr   rangedaemonstart	enumerater   r   r   appendjoinclosesortedr   r	   )Znprocr
   inputsverboseZprogress_kwr   Zproclistprocsentr   resr   resultsr   )r
   r   r   r   r   multiprocess_with_queues@   sL     




r;   )F)__doc__r"   multiprocessingr   r   operatorr   progressr   r   r;   r   r   r   r   <module>   s   #