§
    ¹³Ùgµ  ã                  óî  — d Z ddlmZ ddlZddlmZ ddlZddlmZ ddl	m
Z
 ddlmZ d„ Z ej        ¦   «         Z ej        d	d¦  «        �( ej        d	d¦  «                             ¦   «         d
k    Zn
 e¦   «         Z ej        d¦  «        €
dej        d<    ej        d¦  «        � e ej        d¦  «        ¦  «        Zn$e                     d e
¦   «         d         ¦  «        Zd„ Zddd„Zdi efd„ZdS )zi
Routines for running Python functions in parallel using process pools
from the multiprocessing library.
é    )ÚannotationsN)ÚProcessPoolExecutor)ÚQiskitError)Úlocal_hardware_info)Úuser_configc                 óV   — t           j        dk    rd} nt           j        dk    rd} nd} | S )z¼
    Returns the default parallelism flag value for the current platform.

    Returns:
        parallel_default: The default parallelism flag value for the
        current platform.

    Úwin32FÚdarwinT)ÚsysÚplatform)Úparallel_defaults    úK/granary/edev/quantum/lib/python3.11/site-packages/qiskit/utils/parallel.pyÚget_platform_parallel_defaultr   >   s>   € õ „|�wÒÐØ ÐÐå	Œ˜Ò	!Ð	!Ø ÐÐð  ÐàÐó    ÚQISKIT_PARALLELÚtrueÚQISKIT_IN_PARALLELÚFALSEÚQISKIT_NUM_PROCSÚnum_processÚcpusc                ó(   — | \  }}}} ||g|¢R i |¤ŽS ©N© )ÚparamÚtaskÚvalueÚ	task_argsÚtask_kwargss        r   Ú_task_wrapperr    e   s0   € Ø,1Ñ)€Tˆ5�)˜[Øˆ4�Ð1˜	Ð1Ð1Ð1 [Ð1Ð1Ð1r   Únum_processesú
int | NoneÚreturnÚboolc                ó–   — | €t           n| } | dk    o8t          j        dd¦  «        dk    ot                               dt
          ¦  «        S )a  Return whether the current parallelisation configuration suggests that we should run things
    like :func:`parallel_map` in parallel (``True``) or degrade to serial (``False``).

    Args:
        num_processes: the number of processes requested for use (if given).
    Né   r   r   Úparallel_enabled)Ú	CPU_COUNTÚosÚgetenvÚCONFIGÚgetÚPARALLEL_DEFAULT)r!   s    r   Úshould_run_in_parallelr.   j   sQ   € ð "/Ð!6•I�I¸M€Mà˜Òð 	=ÝŒIÐ*¨GÑ4Ô4¸Ò?ð	=å�JŠJÐ)Õ+;Ñ<Ô<ðr   r   c                óê  ‡ ‡‡— |€t           }t          |¦  «        dk    rg S t          |¦  «        dk    r ‰ |d         g‰¢R i ‰¤ŽgS t          |¦  «        rädt          j        d<   	 g }t          |¬¦  «        5 }ˆ ˆˆfd„|D ¦   «         }|                     t          |¦  «        }ddd¦  «         n# 1 swxY w Y   t          |¦  «        }n^# t          t          f$ rJ}	t          |	t          ¦  «        rdt          j        d<   t          d	¦  «        |	‚dt          j        d<   |	‚d}	~	ww xY wdt          j        d<   |S g }t          |¦  «        D ]&\  }
} ‰ |g‰¢R i ‰¤Ž}|                     |¦  «         Œ'|S )
aõ  
    Parallel execution of a mapping of `values` to the function `task`. This
    is functionally equivalent to::

        result = [task(value, *task_args, **task_kwargs) for value in values]

    This will parallelise the results if the number of ``values`` is greater than one, and the
    current system configuration permits parallelization.

    Args:
        task (func): Function that is to be called for each value in ``values``.
        values (array_like): List or array of values for which the ``task`` function is to be
            evaluated.
        task_args (list): Optional additional arguments to the ``task`` function.
        task_kwargs (dict): Optional additional keyword argument to the ``task`` function.
        num_processes (int): Number of processes to spawn.

    Returns:
        result: The result list contains the value of ``task(value, *task_args, **task_kwargs)`` for
        each value in ``values``.

    Raises:
        QiskitError: If user interrupts via keyboard.

    Examples:

        .. code-block:: python

            import time
            from qiskit.utils import parallel_map
            def func(_):
                    time.sleep(0.1)
                    return 0
            parallel_map(func, list(range(10)));
    Nr   r&   ÚTRUEr   )Úmax_workersc              3  ó$   •K  — | ]
}‰|‰‰fV — Œd S r   r   )Ú.0r   r   r   r   s     €€€r   ú	<genexpr>zparallel_map.<locals>.<genexpr>«   s,   øè è € ÐSÐSÀ5˜$  y°+Ð>ÐSÐSÐSÐSÐSÐSr   r   z#Keyboard interrupt in parallel_map.)r(   Úlenr.   r)   Úenvironr   Úmapr    ÚlistÚKeyboardInterruptÚ	ExceptionÚ
isinstancer   Ú	enumerateÚappend)r   Úvaluesr   r   r!   ÚresultsÚexecutorr   ÚfutureÚerrorÚ_r   Úresults   ` ``         r   Úparallel_maprE   y   s  øøø€ ðL ÐÝ!ˆÝ
ˆ6�{„{�aÒÐØˆ	Ý
ˆ6�{„{�aÒÐØ��V˜A”YÐ: Ð:Ð:Ð:¨kÐ:Ð:Ð;Ð;å˜mÑ,Ô,ð Ø+1�Œ
Ð'Ñ(ð	ØˆGÝ$°Ð?Ñ?Ô?ð <À8ØSÐSÐSÐSÐSÐSÈFÐSÑSÔS�Ø!Ÿš¥m°UÑ;Ô;�ð<ð <ð <ñ <ô <ð <ð <ð <ð <ð <ð <øøøð <ð <ð <ð <õ ˜6‘l”lˆGˆGøå!¥9Ð-ð 	ð 	ð 	Ý˜%Õ!2Ñ3Ô3ð TØ3:•”
Ð/Ñ0Ý!Ð"GÑHÔHÈeÐSà/6�BŒJÐ+Ñ,ØˆKøøøøð	øøøð ,3�Œ
Ð'Ñ(Øˆà€GÝ˜fÑ%Ô%ð ð ‰ˆˆ5Ø��eÐ7˜iÐ7Ð7Ð7¨;Ð7Ð7ˆØ�Š�vÑÔÐÐØ€Ns=   Á'C Á9,B1Â%C Â1B5Â5C Â8B5Â9C ÃD'ÃAD"Ä"D'r   )r!   r"   r#   r$   )Ú__doc__Ú
__future__r   r)   Úconcurrent.futuresr   r   Úqiskit.exceptionsr   Úqiskit.utils.multiprocessingr   Úqiskitr   r   Ú
get_configr+   r*   Úlowerr-   r6   Úintr(   r,   r    r.   rE   r   r   r   ú<module>rO      s¶  ðð\ð ð
 #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø 
€
€
€
à )Ð )Ð )Ð )Ð )Ð )Ø <Ð <Ð <Ð <Ð <Ð <Ø Ð Ð Ð Ð Ð ðð ð ð, 
 ˆÔ	Ñ	!Ô	!€à€2„9Ð Ñ%Ô%Ð1Ø �r”yÐ!2°DÑ9Ô9×?Ò?ÑAÔAÀVÒKÐÐà4Ð4Ñ6Ô6Ðð €2„9Ð!Ñ"Ô"Ð*Ø'.€B„JÐ#Ñ$à€2„9ÐÑ Ô Ð,Ø��I�B”IÐ0Ñ1Ô1Ñ2Ô2€I€Ià—
’
˜=Ð*=Ð*=Ñ*?Ô*?ÀÔ*GÑHÔH€Ið2ð 2ð 2ð
ð ð ð ð ð  ¨B¸iðFð Fð Fð Fð Fð Fr   