o
    tBh6                     @   s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZddl	m
Z
mZ ddgZdadaejdd dkrcd d	lmZ d d
lmZmZ d dlmZmZ edg7 Zejdkr]eddg7 Zd+ddZn.ejdkrsd dlZe ZdZnd dlmZ ejZdZeZdd Zdd Zdd Zd+ddZd,ddZdd  Z d,d!d"Z!d#d$ Z"d%d& Z#G d'd( d(eZ$G d)d* d*e$Z%ejdkr	 e$ Z&e&ej'j(d< e% ej'j(d< dS dS )-    )divisionN   )LokyProcessLokyInitMainProcesslokyloky_init_main         )get_context)assert_spawningset_spawning_popen)get_spawning_popenBaseContextspawnwin32fork
forkserverc                 C   sN   | pt pd} | dkrtdt zt| }W |S  ty&   td| tw )Nr   r   zu`fork` start method should not be used with `loky` as it does not respect POSIX. Try using `spawn` or `loky` instead.,Unknown context '{}'. Value should be in {}.)_DEFAULT_START_METHODwarningswarnUserWarningmp_get_context
ValueErrorformatSTART_METHODS)methodcontext r    |/var/www/html/riverr-enterprise-integrations-main/venv/lib/python3.10/site-packages/joblib/externals/loky/backend/context.pyr   )   s   
r   spawning_popen)Popenprocess_handlec                   C   s   t ttd S N)getattr_tls
popen_attrr    r    r    r!   r   G   s   r   c                 C   s   t tt|  d S r%   )setattrr'   r(   )popenr    r    r!   r   J   s   r   c                 C   s    t  d u rtdt| j d S )NzF%s objects should only be shared between processes through inheritance)r   RuntimeErrortype__name__)objr    r    r!   r   M   s   
r   c                 C   s8   | pt pd} | dkrt S | dkrt S td| t)Nr   r   r   )r   LokyContextLokyInitMainContextr   r   r   )r   r    r    r!   r   T   s   Fc                 C   s<   t d ur
|s
td| d u s| tv sJ d| t| a d S )Nzcontext has already been setz4'{}' is not a valid start_method. It should be in {})r   r+   r   r   )r   forcer    r    r!   set_start_method_   s   r2   c                   C   s   t S r%   )r   r    r    r    r!   get_start_methodj      r3   c                 C   s   zt  }W n ty   d}Y nw t|}t||}| rTt \}}||k r-t|d}|S |dkrR|durKtdt	| d  t
jdkrKt|j t|d}|S |S t|d}|S )a8  Return the number of CPUs the current process can use.

    The returned number of CPUs accounts for:
     * the number of CPUs in the system, as given by
       ``multiprocessing.cpu_count``;
     * the CPU affinity settings of the current process
       (available with Python 3.4+ on some Unix systems);
     * CFS scheduler CPU bandwidth limit (available on Linux only, typically
       set by docker and similar container orchestration systems);
     * the value of the LOKY_MAX_CPU_COUNT environment variable if defined.
    and is given as the minimum of these constraints.

    If ``only_physical_cores`` is True, return the number of physical cores
    instead of the number of logical cores (hyperthreading / SMT). Note that
    this option is not enforced if the number of usable cores is controlled in
    any other way such as: process affinity, restricting CFS scheduler policy
    or the LOKY_MAX_CPU_COUNT environment variable. If the number of physical
    cores is not found, return the number of logical cores.
 
    It is also always larger or equal to 1.
    r   	not foundNzFCould not find the number of physical cores for the following reason:
z
Returning the number of logical cores instead. You can silence this warning by setting LOKY_MAX_CPU_COUNT to the number of cores you want to use.)r
      )mp	cpu_countNotImplementedError_cpu_count_usermin_count_physical_coresmaxr   r   strsysversion_info	tracebackprint_tb__traceback__)only_physical_corescpu_count_mpcpu_count_useraggregate_cpu_countcpu_count_physical	exceptionr8   r    r    r!   r8   n   s8   





r8   c           
      C   s  ddl }| }ttdrz	ttd}W n	 ty   Y nw | }d}d}tj|rwtj|rwt|d}t	|
 }W d   n1 sFw   Y  t|d}t	|
 }W d   n1 saw   Y  |dkrw|dkrwt	||| }t	tjd| }	t|||	S )z%Number of user defined available CPUsr   Nsched_getaffinityz#/sys/fs/cgroup/cpu/cpu.cfs_quota_usz$/sys/fs/cgroup/cpu/cpu.cfs_period_usrLOKY_MAX_CPU_COUNT)mathhasattroslenrJ   r9   pathexistsopenintreadceilenvirongetr;   )
rE   rM   cpu_count_affinitycpu_count_cfscfs_quota_fnamecfs_period_fnamefhcfs_quota_uscfs_period_uscpu_count_lokyr    r    r!   r:      s,   
r:   c               
   C   s>  d} t dur
t | fS zxtjdkr.tjdddd}|jd }dd	 |D }t	|}nHtjd
krTtjdddd}|jd }dd |D }t
tt|}n"tjdkrntjdddd}|jd}t|}ntdtj|dk rtd|W n ty } z
|} d}W Y d}~nd}~ww |a || fS )a  Return a tuple (number of physical cores, exception)

    If the number of physical cores is found, exception is set to None.
    If it has not been found, return ("not found", exception).

    The number of physical cores is cached to avoid repeating subprocess calls.
    Nlinuxzlscpu --parse=core T)capture_outputzutf-8c                 S   s   h | ]	}| d s|qS )#)
startswith).0liner    r    r!   	<setcomp>   s    z(_count_physical_cores.<locals>.<setcomp>r   z&wmic CPU Get NumberOfCores /Format:csvc                 S   s&   g | ]}|r|d kr| dd qS )zNode,NumberOfCores,r   )split)rf   lr    r    r!   
<listcomp>   s    z)_count_physical_cores.<locals>.<listcomp>darwinzsysctl -n hw.physicalcpuzunsupported platform: {}r   zfound {} physical cores < 1r5   )physical_cores_cacher?   platform
subprocessrunrj   stdoutdecode
splitlinesrP   summaprT   r9   r   r   	Exception)rI   cpu_inforH   er    r    r!   r<      sP   







r<   c                   @   s  e Zd ZdZdZeZeeZd#ddZ	d$ddZ
ejdd	 d
k rd	 dd Zdd Zd%ddZejdkr:	 dd Zn*	 ddlmZ eejZeejZeejZeejZeejZeejZeejZejdkr	 d&ddZdd Zdd Zdd Zd$dd Zd!d" ZdS dS )'r/   z#Context relying on the LokyProcess.r   r   Nc                 C   s   ddl m} ||||  dS )Returns a queue objectr   )Queuereducersctx)queuesr{   r   )selfmaxsizer}   r{   r    r    r!   r{     s   zLokyContext.Queuec                 C   s   ddl m} |||  dS )rz   r   )SimpleQueuer|   )r   r   r   )r   r}   r   r    r    r!   r     s   zLokyContext.SimpleQueuer   r	   c                 C   s   | S r%   r    r   r    r    r!   r     r4   zLokyContext.get_contextc                 C   s   | j S r%   )_namer   r    r    r!   r3     s   zLokyContext.get_start_methodTc                 C   s
   t |S )z1Returns two connection object connected by a pipe)r7   Pipe)r   duplexr    r    r!   r     s   
zLokyContext.Piper   c                 C   s   ddl m} | }|  |S )zReturns a manager objectr   )LokyManager)managersr   start)r   r   mr    r    r!   Manager#  s   zLokyContext.Manager)synchronizer   c                 C   s   ddl m} ||dS )zReturns a semaphore objectr   )	Semaphore)value)r   r   )r   r   r   r    r    r!   r   :  s   
zLokyContext.Semaphorec                 C      ddl m} ||S )z"Returns a bounded semaphore objectr   )BoundedSemaphore)r   r   )r   r   r   r    r    r!   r   ?     zLokyContext.BoundedSemaphorec                 C      ddl m} | S )zReturns a lock objectr   )Lock)r   r   )r   r   r    r    r!   r   D     zLokyContext.Lockc                 C   r   )zReturns a recurrent lock objectr   )RLock)r   r   )r   r   r    r    r!   r   I  r   zLokyContext.RLockc                 C   r   )zReturns a condition objectr   )	Condition)r   r   )r   lockr   r    r    r!   r   N  r   zLokyContext.Conditionc                 C   r   )zReturns an event objectr   )Event)r   r   )r   r   r    r    r!   r   S  r   zLokyContext.Event)r   Nr%   )T)r   )r-   
__module____qualname____doc__r   r   Processstaticmethodr8   r{   r   r?   r@   r   r3   r   ro   r   multiprocessingr   r   r   r   r   r   r   r7   r    r    r    r!   r/     sB    














r/   c                   @   s   e Zd ZdZdZeZdS )r0   a  Extra context with LokyProcess, which does load the main module

    This context is used for compatibility in the case ``cloudpickle`` is not
    present on the running system. This permits to load functions defined in
    the ``main`` module, using proper safeguards. The declaration of the
    ``executor`` should be protected by ``if __name__ == "__main__":`` and the
    functions and variable used from main should be out of this block.

    This mimics the default behavior of multiprocessing under Windows and the
    behavior of the ``spawn`` start method on a posix system for python3.4+.
    For more details, see the end of the following section of python doc
    https://docs.python.org/3/library/multiprocessing.html#multiprocessing-programming
    r   N)r-   r   r   r   r   r   r   r    r    r    r!   r0   Y  s    r0   r%   )F))
__future__r   rO   r?   rp   rA   r   r   r7   processr   r   r   r   rn   r@   r   r   multiprocessing.contextr   r   r   r   ro   	threadinglocalr'   r(   multiprocessing.forkingr#   objectr2   r3   r8   r:   r<   r/   r0   ctx_lokyr   _concrete_contextsr    r    r    r!   <module>   sX   





;"7W
