
    Q%da                     *   d dl Z d dlZd dlZddlT ddgZdZ G d de          Z G d de          Z	 G d	 d
          Z
 G d d          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          ZdS )    N   )*PoolTimeoutErrorzp
Standard Python Pool implementation based on Python API
for Intel(R) oneAPI Threading Building Blocks (oneTBB)
c                       e Zd ZdZdS )r   z>Raised when a result is not available within the given timeoutN)__name__
__module____qualname____doc__     (lib/python3.11/site-packages/tbb/pool.pyr   r   Q   s        HHDr   c                       e Zd ZdZddZd e            fdZddZdd	Zdd
Z	d e            dfdZ
ddZddZ	 	 ddZd Zd Zd Zd Zd Zd Zd ZdS )r   z
    The Pool class provides standard multiprocessing.Pool interface
    which is mapped onto oneTBB tasks executing in its thread pool
    r   c                 h    d| _         t                      | _        dgt                      z  | _        dS )z
        \param nworkers (integer) number of worker threads to start
        \param name (string) prefix for the worker threads' name
        FN)_closed
task_group_tasksdefault_num_threads_pool)selfnworkersnames      r   __init__zPool.__init__\   s/    
  llW0222


r   r   c                 T    |                      |||                                          S )zWEquivalent of the apply() builtin function. It blocks till
        the result is ready.)apply_asyncget)r   funcargskwdss       r   applyz
Pool.applye   s(     dD1155777r   Nc                 T    |                      |||                                          S )aT  A parallel equivalent of the map() builtin function. It
        blocks till the result is ready.

        This method chops the iterable into a number of chunks which
        it submits to the process pool as separate tasks. The
        (approximate) size of these chunks can be specified by setting
        chunksize to a positive integer.)	map_asyncr   )r   r   iterable	chunksizes       r   mapzPool.mapj   s&     ~~dHi88<<>>>r   r   c                 p    t          d          }|                     ||||           t          |          S )a*  
        An equivalent of itertools.imap().

        The chunksize argument is the same as the one used by the
        map() method. For very long iterables using a large value for
        chunksize can make the job complete much faster than
        using the default value of 1.

        Also if chunksize is 1 then the next() method of the iterator
        returned by the imap() method has an optional timeout
        parameter: next(timeout) will raise processing.TimeoutError if
        the result cannot be returned within timeout seconds.
        Tas_iterator)OrderedResultCollector_create_sequencesiterr   r   r#   r$   	collectors        r   imapz	Pool.imapt   s:     +t<<<	tXy)DDDIr   c                 l    t                      }|                     ||||           t          |          S )zThe same as imap() except that the ordering of the results
        from the returned iterator should be considered
        arbitrary. (Only when there is only one worker process is the
        order guaranteed to be "correct".))UnorderedResultCollectorr*   r+   r,   s        r   imap_unorderedzPool.imap_unordered   s5    
 -..	tXy)DDDIr   c                     | j         rJ t          |          }t          ||||          }| j                            |           |S )a  A variant of the apply() method which returns an
        ApplyResult object.

        If callback is specified then it should be a callable which
        accepts a single argument. When the result becomes ready,
        callback is applied to it (unless the call failed). callback
        should complete immediately since otherwise the thread which
        handles the results will get blocked.callback)r   ApplyResultJobr   run)r   r   r   r   r4   apply_resultjobs          r   r   zPool.apply_async   sO     <"H555$dL11r   c                     t          |          }t          |d          }|                     ||||          s|                    g            |S )a  A variant of the map() method which returns a ApplyResult
        object.

        If callback is specified then it should be a callable which
        accepts a single argument. When the result becomes ready
        callback is applied to it (unless the call failed). callback
        should complete immediately since otherwise the thread which
        handles the results will get blocked.r3   Fr'   )r5   r)   r*   
_set_valuer   r   r#   r$   r4   r8   r-   s          r   r"   zPool.map_async   s\     #H555-lNNN	%%dHiKK 	&

!
!"
%
%
%r   c                     t          |          }t          |d          }|                     ||||          s"|                    t	          g                      |S )a  A variant of the imap() method which returns an ApplyResult
        object that provides an iterator (next method(timeout)
        available).

        If callback is specified then it should be a callable which
        accepts a single argument. When the resulting iterator becomes
        ready, callback is applied to it (unless the call
        failed). callback should complete immediately since otherwise
        the thread which handles the results will get blocked.r3   Tr'   )r5   r)   r*   r;   r+   r<   s          r   
imap_asynczPool.imap_async   sb     #H555-lMMM	%%dHiKK 	,

!
!$r((
+
+
+r   c                     t          |          }t          |          }|                     ||||          s"|                    t	          g                      |S )a  A variant of the imap_unordered() method which returns an
        ApplyResult object that provides an iterator (next
        method(timeout) available).

        If callback is specified then it should be a callable which
        accepts a single argument. When the resulting iterator becomes
        ready, callback is applied to it (unless the call
        failed). callback should complete immediately since otherwise
        the thread which handles the results will get blocked.r3   )r5   r0   r*   r;   r+   r<   s          r   imap_unordered_asynczPool.imap_unordered_async   s]     #H555/==	%%dHiKK 	,

!
!$r((
+
+
+r   c                     d| _         dS )zPrevents any more tasks from being submitted to the
        pool. Once all the tasks have been completed the worker
        processes will exit.TN)r   r   s    r   closez
Pool.close   s    
 r   c                 `    |                                   | j                                         dS )zStops the worker processes immediately without completing
        outstanding work. When the pool object is garbage collected
        terminate() will be called immediately.N)rC   r   cancelrB   s    r   	terminatezPool.terminate   s+     	

r   c                 8    | j                                          dS )zhWait for the worker processes to exit. One must call
        close() or terminate() before using join().N)r   waitrB   s    r   joinz	Pool.join   s     	r   c                     | S Nr   rB   s    r   	__enter__zPool.__enter__       r   c                 .    |                                   d S rK   )rI   )r   exc_type	exc_value	tracebacks       r   __exit__zPool.__exit__   s    		r   c                 V    |                                   |                                  d S rK   )rF   rI   rB   s    r   __del__zPool.__del__   s#    		r   c                    | j         rJ t          |          }d}g }|sg }t          |pd          D ]]}		 t          |          }
n# t          $ r d}Y  n<w xY wt          |          }t          ||
fi |          }|                    |           ^|r"|                    t          |                     ||D ]}| j	        
                    |           |S )a  
        Create callable objects to process and pushes them on the
        work queue. Each work unit is meant to process a slice of
        iterable of size chunksize. If collector is specified, then
        the ApplyResult objects associated with the jobs will notify
        collector when their result becomes ready.

        eturn the list callable objects (basically: JobSequences)
        pushed onto the work queue
        Fr   T)r   r+   rangenextStopIterationr5   r6   appendJobSequencer   r7   )r   r   r#   r$   r-   it_	exit_loop	sequencesseq_argr8   r9   ts                 r   r*   zPool._create_sequences   s    <8nn		 	3C9>**    s))CC$    $IEE  +955$L99

3 3  S!1!1222  	3  	 	AKOOAs   AAA)r   r   rK   )r   NN)r   r	   r
   r   r   dictr    r%   r.   r1   r   r"   r>   r@   rC   rF   rI   rL   rR   rT   r*   r   r   r   r   r   V   s`        
3 3 3 3  " 8 8 8 8
? ? ? ?   $    &(ddfft            >B&*   "      
          r   c                       e Zd ZdZd Zd ZdS )r6   zBA work unit that corresponds to the execution of a single functionc                 >    || _         || _        || _        || _        dS )z
        \param func/args/kwds used to call the function
        \param apply_result ApplyResult object that holds the result
        of the function call
        N)_func_args_kwds_result)r   r   r   r   r8   s        r   r   zJob.__init__  s$     


#r   c                     	  | j         | j        i | j        }| j                            |           dS #  | j                                         Y dS xY w)z
        Call the function with the args/kwds and tell the ApplyResult
        that its result is ready. Correctly handles the exceptions
        happening during the execution of the function
        N)rf   rg   rh   ri   r;   _set_exception)r   results     r   __call__zJob.__call__  se    	,TZ:tz::F L##F+++++	*L''))))))s	   5 ANr   r	   r
   r   r   rm   r   r   r   r6   r6     s8        LL	$ 	$ 	$, , , , ,r   r6   c                       e Zd ZdZd Zd ZdS )rZ   zZA work unit that corresponds to the processing of a continuous
    sequence of Job objectsc                     || _         d S rK   _jobs)r   jobss     r   r   zJobSequence.__init__,  s    


r   c                 .    | j         D ]} |             dS )zC
        Call all the Job objects that have been specified
        Nrq   )r   r9   s     r   rm   zJobSequence.__call__/  s,     : 	 	CCEEEE	 	r   Nrn   r   r   r   rZ   rZ   (  s<               r   rZ   c                   B    e Zd ZdZd
dZddZddZd Zd Zd Z	d	 Z
dS )r5   aY  An object associated with a Job object that holds its result:
    it's available during the whole life the Job and after, even when
    the Job didn't process yet. It's possible to use this object to
    wait for the result/exception of the job to be available.

    The result objects returns by the Pool::*_async() methods are of
    this typeNc                     d| _         t          j                    | _        d| _        d| _        || _        ||                    |            || _        dS dS )aI  
        \param collector when not None, the notify_ready() method of
        the collector will be called when the result from the Job is
        ready
        \param callback when not None, function to call when the
        result becomes available (this is the parameter passed to the
        Pool::*_async() methods.
        FN)_success	threadingEvent_event_data
_collector	_callbackregister_result)r   r-   r4   s      r   r   zApplyResult.__init__@  s\     o''
! %%d+++'DOOO ! r   c                     |                      |          st          d|z            | j        r| j        S  | j        d         | j        d                                       | j        d                   )a  
        Returns the result when it arrives. If timeout is not None and
        the result does not arrive within timeout seconds then
        TimeoutError is raised. If the remote call raised an exception
        then that exception will be reraised by get().
        zResult not available within %fsr   r      )rH   r   rw   r{   with_tracebackr   timeouts     r   r   zApplyResult.getS  so     yy!! 	L@7JKKK= 	:djmDJqM**99$*Q-HHHr   c                 h    | j                             |           | j                                         S )zJWaits until the result is available or until timeout
        seconds pass.)rz   rH   isSetr   s     r   rH   zApplyResult.wait`  s.     	!!!{  """r   c                 4    | j                                         S )z'Returns whether the call has completed.)rz   r   rB   s    r   readyzApplyResult.readyf  s    {  """r   c                 <    |                                  sJ | j        S )zReturns whether the call completed without raising an
        exception. Will raise AssertionError if the result is not
        ready.)r   rw   rB   s    r   
successfulzApplyResult.successfulj  s      zz||}r   c                 6   |                                  rJ || _        d| _        | j                                         | j        | j                            |            | j        3	 |                     |           dS #  t          j	                     Y dS xY wdS )zCalled by a Job object to tell the result is ready, and
        provides the value of this result. The object will become
        ready and successful. The collector's notify_ready() method
        will be called, and the callback method tooTN)
r   r{   rw   rz   setr|   notify_readyr}   rQ   	print_exc)r   values     r   r;   zApplyResult._set_valueq  s    
 ::<<
?&O((...>%&u%%%%%&#%%%%%%	 &%s   'A> >Bc                     |                                  rJ t          j                    | _        d| _        | j                                         | j        | j                            |            dS dS )zCalled by a Job object to tell that an exception occurred
        during the processing of the function. The object will become
        ready but not successful. The collector's notify_ready()
        method will be called, but NOT the callback methodFN)	r   sysexc_infor{   rw   rz   r   r|   r   rB   s    r   rk   zApplyResult._set_exception  sj     ::<<\^^
?&O((..... '&r   rb   rK   )r   r	   r
   r   r   r   rH   r   r   r;   rk   r   r   r   r5   r5   7  s         ( ( ( (&I I I I# # # ## # #  & & &"/ / / / /r   r5   c                   2    e Zd ZdZd Zd Zd ZddZd ZdS )	AbstractResultCollectora  ABC to define the interface of a ResultCollector object. It is
    basically an object which knows whuich results it's waiting for,
    and which is able to get notify when they get available. It is
    also able to provide an iterator over the results when they are
    availablec                     || _         dS )
        \param to_notify ApplyResult object to notify when all the
        results we're waiting for become available. Can be None.
        N)
_to_notifyr   	to_notifys     r   r   z AbstractResultCollector.__init__  s    
 $r   c                      t          d          )!  Used to identify which results we're waiting for. Will
        always be called BEFORE the Jobs get submitted to the work
        queue, and BEFORE the __iter__ and _get_result() methods can
        be called
        \param apply_result ApplyResult object to add in our collection
        "Children classes must implement itNotImplementedErrorr   r8   s     r   r~   z'AbstractResultCollector.register_result       ""FGGGr   c                      t          d          )   Called by the ApplyResult object (already registered via
        register_result()) that it is now ready (ie. the Job's result
        is available or an exception has been raised).
        \param apply_result ApplyResult object telling us that the job
        has been processed
        r   r   r   s     r   r   z$AbstractResultCollector.notify_ready  r   r   Nc                      t          d          )z  Called by the CollectorIterator object to retrieve the
        result's values one after another (order defined by the
        implementation)
        \param idx The index of the result we want, wrt collector's order
        \param timeout integer telling how long to wait (in seconds)
        for the result at index idx to be available, or None (wait
        forever)
        r   r   r   idxr   s      r   _get_resultz#AbstractResultCollector._get_result  s     ""FGGGr   c                      t          |           S )z8Return a new CollectorIterator object for this collector)CollectorIteratorrB   s    r   __iter__z AbstractResultCollector.__iter__  s     &&&r   rK   )	r   r	   r
   r   r   r~   r   r   r   r   r   r   r   r     sx         $ $ $H H HH H H	H 	H 	H 	H' ' ' ' 'r   r   c                   ,    e Zd ZdZd Zd ZddZd ZdS )r   zAn iterator that allows to iterate over the result values
    available in the given collector object. Equipped with an extended
    next() method accepting a timeout argument. Created by the
    AbstractResultCollector::__iter__() methodc                 "    || _         d| _        dS )z'\param AbstractResultCollector instancer   N)r|   _idx)r   r-   s     r   r   zCollectorIterator.__init__  s    #			r   c                     | S rK   r   rB   s    r   r   zCollectorIterator.__iter__  rM   r   Nc                    	 | j                             | j        |          }n$# t          $ r d| _        t           d| _         xY w| xj        dz  c_        |                                sJ |                    d          S )zReturn the next result value in the sequence. Raise
        StopIteration at the end. Can raise the exception raised by
        the Jobr   r   )r|   r   r   
IndexErrorrX   r   r   )r   r   r8   s      r   rW   zCollectorIterator.next  s    	?66ty'JJLL 	  	  	 DI	DI		Q		!!#####"""s	    # !Ac                 *    |                                  S rK   )rW   rB   s    r   __next__zCollectorIterator.__next__  s    yy{{r   rK   )r   r	   r
   r   r   r   rW   r   r   r   r   r   r     s_        2 2
  
  # # # #"    r   r   c                   0    e Zd ZdZddZd ZddZddZdS )r0   zAn AbstractResultCollector implementation that collects the
    values of the ApplyResult objects in the order they become ready. The
    CollectorIterator object returned by __iter__() will iterate over
    them in the order they become readyNc                     t                               | |           t          j                    | _        g | _        d| _        dS )r   r   N)r   r   rx   	Condition_cond_collection	_expectedr   s     r   r   z!UnorderedResultCollector.__init__  s=    
 	 ((y999(**
r   c                 &    | xj         dz  c_         dS r   r   N)r   r   s     r   r~   z(UnorderedResultCollector.register_result  s     	!r   c                    | j                                          	 || j        k    rt          |t	          | j                  k     r&| j        |         | j                                          S |t	          | j                  k    rt                      | j                             |           	 | j        |         | j                                          S # t          $ r t          d          w xY w# | j                                          w xY w)a  Called by the CollectorIterator object to retrieve the
        result's values one after another, in the order the results have
        become available.
        \param idx The index of the result we want, wrt collector's order
        \param timeout integer telling how long to wait (in seconds)
        for the result at index idx to be available, or None (wait
        forever)
        )r   z!Timeout while waiting for results)	r   acquirer   r   lenr   releaserH   r   r   s      r   r   z$UnorderedResultCollector._get_result  s    	
	!dn$$  s4+,,,,', J     D,---- ll"
000L+C0
 J    	 " L L L&'JKKKL J    s$   6C0 +AC0 -C C--C0 0Dc                    d}| j                                          	 | j                            |           t	          | j                  dk    }| j                                          | j                                          n# | j                                          w xY w|r0| j        +| j                            t          |                      dS dS dS )r   Fr   N)
r   r   r   rY   r   	notifyAllr   r   r;   r+   )r   r8   
first_items      r   r   z%UnorderedResultCollector.notify_ready  s     

	!##L111d.//14JJ  """J    DJ     	3$/5O&&tDzz22222	3 	355s   AB BrK   r   r	   r
   r   r   r~   r   r   r   r   r   r0   r0     si        + +
     ! ! ! !83 3 3 3 3 3r   r0   c                   .    e Zd ZdZddZd Zd	dZd ZdS )
r)   a  An AbstractResultCollector implementation that collects the
    values of the ApplyResult objects in the order they have been
    submitted. The CollectorIterator object returned by __iter__()
    will iterate over them in the order they have been submittedNTc                     t                               | |           g | _        t          j                    | _        d| _        || _        dS )aq  
        \param to_notify ApplyResult object to notify when all the
        results we're waiting for become available. Can be None.
        \param as_iterator boolean telling whether the result value
        set on to_notify should be an iterator (available as soon as 1
        result arrived) or a list (available only after the last
        result arrived)
        r   N)r   r   _resultsrx   Lock_lock
_remaining_as_iterator)r   r   r(   s      r   r   zOrderedResultCollector.__init__3  sE     	 ((y999^%%
'r   c                 Z    | j                             |           | xj        dz  c_        dS r   )r   rY   r   r   s     r   r~   z&OrderedResultCollector.register_resultB  s.     	\***1r   c                 J    | j         |         }|                    |           |S )r   )r   rH   )r   r   r   ress       r   r   z"OrderedResultCollector._get_resultL  s'     mC 
r   c                 f   d}d}| j                                          	 | j        dk    sJ t          | j                  | j        k    }| xj        dz  c_        | j        dk    }| j                                          n# | j                                          w xY w| j        | j        r+|r)| j                            t          |                      dS | j        sS|rS	 d | j        D             }| j                            |           dS #  | j        
                                 Y dS xY wdS dS dS )r   Fr   r   Nc                 8    g | ]}|                     d           S )r   )r   ).0rs     r   
<listcomp>z7OrderedResultCollector.notify_ready.<locals>.<listcomp>p  s"    ;;;15588;;;r   )r   r   r   r   r   r   r   r   r;   r+   rk   )r   r8   	got_firstgot_lastlsts        r   r   z#OrderedResultCollector.notify_readyY  se    	
	!?Q&&&&T]++t>IOOq OO1,HJ    DJ    ?&  4Y 4**4::66666& 48 44;;T];;;C O..s333335O22444444 '&4 4 4 4s   AA> >BD D*)NTrK   r   r   r   r   r)   r)   -  sf        D D
( ( ( (     4 4 4 4 4r   r)   )r   rx   rQ   api__all__r   	Exceptionr   objectr   r6   rZ   r5   r   r   r0   r)   r   r   r   <module>r      s  J 


            >
"	 	 	 	 	9 	 	 	
s s s s s6 s s sl, , , , , , , ,8       V/ V/ V/ V/ V/& V/ V/ V/r-' -' -' -' -'f -' -' -'`               FG3 G3 G3 G3 G36 G3 G3 G3TG4 G4 G4 G4 G44 G4 G4 G4 G4 G4r   