§
    [�’jíR  ã                   óÎ   — d Z ddlZddlm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d
lmZmZmZmZ ddlmZ dee         deeeeef                  fd„Z G d„ d¦  «        ZdS )uª  Centralized offloading logic for continuous batching.

Handles two offloading strategies when the GPU KV cache is full:
  1. CPU offloading: copy the KV cache to a pre-allocated pinned CPU buffer, preserving exact request state.
  2. Soft reset: discard the KV cache and re-prefill from scratch when the request is re-scheduled. This incurs no data
    transfer overhead, but we need to re-run prefill over all initial + generated tokens (so more compute overhead).

The CPU swap pool is a static set of pinned tensors allocated once at init (like vLLM/SGLang). Blocks are tracked
with a simple free set â€” no dynamic allocation or deallocation of tensors ever happens at runtime.
é    N)Únullcontext)Úchainé   )Úis_psutil_availableé   )ÚPagedAttentionCache)ÚDistributedHelper)ÚFutureRequestStateÚRequestStateÚRequestStatusÚlogger)Ú	SchedulerÚindicesÚreturnc                 ó2  — g }| s|S | d         x}}d}t          dt          | ¦  «        ¦  «        D ]>}| |         |dz   k    r%|                     ||||z
  f¦  «         | |         |}}| |         }Œ?|                     ||t          | ¦  «        |z
  f¦  «         |S )z™Groups an index list into (start_index, offset, length) runs of consecutive values, so scattered block copies
    can be performed as a few slice copies.r   r   )ÚrangeÚlenÚappend)r   ÚrunsÚstartÚprevÚoffsetÚis         úlC:\Projects\DSCons\.venv\Lib\site-packages\transformers\generation\continuous_batching\offloading_manager.pyÚcontiguous_runsr   &   s¹   € ð €DØð ØˆØ˜1”:Ð€EˆDØ€FÝ�1•c˜'‘l”lÑ#Ô#ð ð ˆØ�1Œ:˜ ™Ò!Ð!Ø�KŠK˜ ¨¨F©
Ð3Ñ4Ô4Ð4Ø# AœJ¨�6ˆEØ�qŒzˆˆØ‡K‚K�˜¥ G¡¤¨vÑ 5Ð6Ñ7Ô7Ð7Ø€Kó    c                   ó$  — e Zd ZdZdedededz  dedej        j	        dz  de
d	dfd
„Zdedz  ded	efd„Zd„ Zd	efd„Zdee         d	dfd„Zddeded	dfd„Zdd„Zdd„Zdee         d	ee         fd„Zded	eee         ee         f         fd„ZdS )ÚOffloadingManageru/  Manages request offloading and restoration for continuous batching.

    Owns a static CPU swap pool (pre-allocated pinned tensors mirroring the GPU cache layout), performs GPUâ†”CPU block
    copies, decides between CPU offloading and soft reset, and ensures cleanup on cancellation/failure/reset.
    ÚcacheÚ	schedulerÚcpu_offload_space_gibNÚsafety_thresholdÚcompute_streamÚdistributed_helperr   c                 ó  — || _         || _        || _        g | _        g | _        g | _        g | _        g | _        i | _        i | _	        |  
                    ||¦  «        }t          j        |t          j        d¬¦  «        }t          |                     |d¬¦  «                             ¦   «         ¦  «        | _        |d uo|dk    }| j        dk    r|rt%          j        d|d›d�¦  «         d S | j        |j        |j        |j        f}	|j        D ]j}
| j                             t          j        |	|j        d¬	¦  «        ¦  «         | j                             t          j        |	|j        d¬	¦  «        ¦  «         Œkd
|j        |j        |j        f}t7          |j        |j        ¦  «        D ]I\  }}| j                              |j        |Ž ¦  «         | j                              |j        |Ž ¦  «         ŒJt=          t?          | j        ¦  «        ¦  «        | _        | j        d         }d|                      ¦   «         z  | !                    ¦   «         z  tE          |j        ¦  «        z  }t%          j#        d| j        › d|dz  d›d�¦  «         d S )NÚcpu©ÚdtypeÚdeviceT)Úon_cpur   úcpu_offload_space=ú.1fz8 GiB is too small for even one block. No CPU offloading.)r(   Ú
pin_memoryéÿÿÿÿé   zCPU swap pool initialized: z	 blocks (é   @ú.2fz GiB pinned))$r   r    Ú_compute_streamÚ_cpu_key_cacheÚ_cpu_value_cacheÚ_gpu_key_viewsÚ_gpu_value_viewsÚ_free_cpu_blocksÚ_request_id_to_cpu_blocksÚ!_request_id_to_group_block_countsÚ_compute_num_cpu_blocksÚtorchÚtensorÚint32ÚintÚtp_all_reduce_minÚitemÚ_num_cpu_blocksr   ÚwarningÚ
block_sizeÚnum_key_value_headsÚhead_dimÚ	key_cacher   Úemptyr(   ÚzipÚvalue_cacheÚviewÚlistr   ÚnumelÚelement_sizer   Úinfo)Úselfr   r    r!   r"   r#   r$   Únum_cpu_blocksÚoffloading_enabledÚcpu_cache_shapeÚ_Úblock_shapeÚk_cacheÚv_cacheÚcache_tensorÚsize_in_bytess                   r   Ú__init__zOffloadingManager.__init__>   sÇ  € ð ˆŒ
Ø"ˆŒà-ˆÔð 35ˆÔØ46ˆÔØ24ˆÔØ46ˆÔØ+-ˆÔØ?AˆÔ&ØGIˆÔ.ð ×5Ò5Ð6KÐM]Ñ^Ô^ˆÝœ n½E¼KÐPUÐVÑVÔVˆÝ"Ð#5×#GÒ#GÈÐ_cÐ#GÑ#dÔ#d×#iÒ#iÑ#kÔ#kÑlÔlˆÔà2¸$Ð>Ð\ÐCXÐ[\ÒC\ÐØÔ 1Ò$Ð$Ø!ð Ý”ð)Ð)>Ðjð )ð )ð )ñô ð ð �4ð  Ô/°Ô1AÀ5ÔC\Ð^cÔ^lÐmˆØ”ð 	kð 	kˆAØÔ×&Ò&¥u¤{°?È%Ì+ÐbfÐ'gÑ'gÔ'gÑhÔhÐhØÔ!×(Ò(­¬°_ÈEÌKÐdhÐ)iÑ)iÔ)iÑjÔjÐjÐjð ˜5Ô+¨UÔ-FÈÌÐWˆÝ # E¤O°UÔ5FÑ GÔ Gð 	Eð 	EÑˆG�WØÔ×&Ò& | w¤|°[Ð'AÑBÔBÐBØÔ!×(Ò(¨¨¬°{Ð)CÑDÔDÐDÐDõ !%¥U¨4Ô+?Ñ%@Ô%@Ñ AÔ AˆÔð Ô*¨1Ô-ˆØ˜L×.Ò.Ñ0Ô0Ñ0°<×3LÒ3LÑ3NÔ3NÑNÕQTÐUZÔUdÑQeÔQeÑeˆÝŒØt¨$Ô*>ÐtÐtÈÐZaÑIbÐtÐtÐtÐtñ	
ô 	
ð 	
ð 	
ð 	
r   c                 óŽ  — |�t          |dz  ¦  «        nd}t          ¦   «         r0ddl}|                     ¦   «         j        }t          ||z  ¦  «        }nd}|�8|�6||k    r/|dz  }t          j        d|d›d|d›d|dz  d›d	|d›d
�	¦  «         |}nG|�t          j        d¦  «         n0|�|}t          j        d|dz  d›d
�¦  «         nt          d¦  «        ‚dt          | j	        j
        ¦  «        z  | j	        j        z  | j	        j        z  | j	        j        z  | j	        j        j        z  }|dk    rt!          d¦  «        ‚||z  S )z?Returns the number of blocks that can fit in the CPU swap pool.Nr0   r   r+   r,   z GiB exceeds z.0%z of total RAM (z GiB). Clamping to z GiB.u{   psutil is not available â€” cpu_offload_space_safety_threshold cannot be enforced. Install psutil to enable the safety cap.z1Auto-sizing CPU swap pool from safety threshold: r1   ztcpu_offload_space=None requires psutil to auto-size the CPU swap pool. Install psutil or pass an explicit GiB value.r/   z9The number of bytes per block is 0. This is not possible.)r>   r   ÚpsutilÚvirtual_memoryÚ	availabler   rB   ÚImportErrorr   r   rF   rC   rD   rE   r(   ÚitemsizeÚ
ValueError)	rO   r!   r"   Úoffload_bytesr[   Ú	total_ramÚ	max_bytesÚclamped_gibÚbytes_per_blocks	            r   r:   z)OffloadingManager._compute_num_cpu_blocksy   s÷  € ð CXÐBc�Ð1°WÑ=Ñ>Ô>Ð>Ðimˆõ Ñ Ô ð 	ØˆMˆMˆMà×-Ò-Ñ/Ô/Ô9ˆIÝ˜IÐ(8Ñ8Ñ9Ô9ˆIˆIàˆIð Ð$¨Ð)>Ø˜yÒ(Ð(Ø'¨7Ñ3�Ý”ð]Ð)>Ðuð ]ð ]ÐQaÐuð ]ð ]Ø! WÑ-Ð\ð]ð ]ØFQÐ\ð]ð ]ð ]ñô ð ð !*�øàÐ&ÝŒNð;ñô ð ð ð
 Ð"Ø%ˆMÝŒNÐoÈyÐ\cÑOdÐoÐoÐoÐoÑpÔpÐpÐpõ ð&ñô ð ð Ý�$”*Ô&Ñ'Ô'ñ(àŒjÔ#ñ$ð ŒjÔ,ñ-ð ŒjÔ!ñ	"ð
 ŒjÔÔ'ñ(ð 	ð ˜aÒÐÝÐXÑYÔYÐYØ Ñ/Ð/r   c                 ót   — | j         �$t          j                             | j         ¦  «        nt	          ¦   «         S )zdReturns a context manager that runs enclosed ops on the compute stream, or a no-op when none is set.)r2   r;   ÚcudaÚstreamr   ©rO   s    r   Ú_stream_ctxzOffloadingManager._stream_ctx®   s/   € à:>Ô:NÐ:Z�uŒz× Ò  Ô!5Ñ6Ô6Ð6Õ`kÑ`mÔ`mÐmr   c                 ó   — | j         }|j        }|sdS | j                             ¦   «         }t	          d„ |D ¦   «         ¦  «        }t          |j        ¦  «        }g }||k    r‰|r‡|t          |¦  «        z
  dk    rq|                     ¦   «         \  }}|                     |¦  «         ||z  }|| j         	                    |j
        ¦  «        z  }||k    r|r|t          |¦  «        z
  dk    °q|sdS |                     ¦   «          |                      |¦  «        }	|D �] }|j
        }
|
|	v r£d|_        |j        t          j        k    rs|j        t          |j        ¦  «        t          |j        ¦  «        z   k    r-|xj        dz  c_        |j        p|j        d         }|g|_        n|j        dd…         |_        t          j        |_        |}n%|                     ¦   «         }t          j        |_        |                     |
¦  «         |                     |¦  «         �Œd|_        t9          j        t<          j        ¦  «        r�| j                             ¦   «         }t9          j         dt          |¦  «        › dt          |	¦  «        › d	t          |¦  «        t          |	¦  «        z
  › d
t          |¦  «        › d|› d�¦  «         t          |¦  «        S )aÓ  Evict enough active requests that, at the next batch, every remaining starved request can allocate the
        blocks it needs. Victims are taken from the starved requests reported by the scheduler, newest first, so the
        batch that was just scheduled is never touched and the demand directly bounds the amount of offloading.
        Tries CPU offloading first; victims that do not fit in the pool are soft reset. Returns the number of evicted
        requests.r   c              3   ó    K  — | ]	\  }}|V — Œ
d S )N© )Ú.0rS   Úblocks_neededs      r   ú	<genexpr>z5OffloadingManager.offload_requests.<locals>.<genexpr>À   s'   è è € ÐCÐCÑ'7 q¨-�]ÐCÐCÐCÐCÐCÐCr   r   r.   NTz
Offloaded z requests (z	 to CPU, z soft reset): z starved requests remain for z free blocks.)!r    Ústarved_requestsr   Úget_num_free_blocksÚsumr   Úactive_requestsÚpopr   Úblocks_in_useÚ
request_idÚreverseÚ_offload_to_cpuÚallocated_blocksÚ_statusr   ÚDECODINGÚposition_offsetÚinitial_tokensÚgenerated_tokensÚremaining_prefill_tokensÚtokens_to_processÚPENDINGÚ!create_equivalent_initial_requestÚFINISHEDÚfinish_requestÚadd_waiting_requestÚblock_new_requestsr   ÚisEnabledForÚloggingÚINFOrN   )rO   r    ÚstarvedÚfree_blocksÚdemandÚ
num_activeÚvictimsÚstatero   Úcpu_offloadedrw   Úlast_true_tokenÚ	new_states                r   Úoffload_requestsz"OffloadingManager.offload_requests²   s  € ð ”Nˆ	ØÔ,ˆØð 	Ø�1ð ”j×4Ò4Ñ6Ô6ˆÝÐCÐC¸7ÐCÑCÔCÑCÔCˆÝ˜Ô2Ñ3Ô3ˆ
Ø&(ˆØ�{Ò"Ð" wÐ"°:ÅÀGÁÄÑ3LÈqÒ3PÐ3PØ#*§;¢;¡=¤=Ñ ˆE�=Ø�NŠN˜5Ñ!Ô!Ð!Ø�mÑ#ˆFØ˜4œ:×3Ò3°EÔ4DÑEÔEÑEˆKð	 �{Ò"Ð" wÐ"°:ÅÀGÁÄÑ3LÈqÒ3PÐ3Pð
 ð 	Ø�1Ø�ŠÑÔÐð ×,Ò,¨WÑ5Ô5ˆàð 	5ñ 	5ˆEØÔ)ˆJØ˜]Ð*Ð*à)*�Ô&Ø”=¥MÔ$:Ò:Ð:ð Ô,µ°EÔ4HÑ0IÔ0IÍCÐPUÔPfÑLgÔLgÑ0gÒgÐgØÐ-Ô-°Ñ2Ð-Ô-Ø+0Ô+AÐ+YÀUÔEYÐ[]Ô*^˜Ø:IÐ9J˜Ô6Ð6ð :?Ô9PÐQRÐQRÐQRÔ9S˜Ô6õ !.Ô 5�”Ø!�	�	à!×CÒCÑEÔE�	Ý -Ô 6�”Ø×$Ò$ ZÑ0Ô0Ð0Ø×)Ò)¨)Ñ4Ô4Ð4Ñ4à'+ˆ	Ô$ÝÔ�wœ|Ñ,Ô,ð 	Øœ*×8Ò8Ñ:Ô:ˆKÝŒKðf�S ™\œ\ð fð fµc¸-Ñ6HÔ6Hð fð fÕSVÐW^ÑS_ÔS_ÕbeÐfsÑbtÔbtÑStð fð fÝ # G¡¤ðfð fØKVðfð fð fñô ð õ �7‰|Œ|Ðr   Úrequests_in_batchc                 óÊ  — | j         }g }g }|D �]Z}|j        }|j        sŒ| j                             |j        ¦  «        }| j                             |j        ¦  «        }|                     |¦  «         d}	t          |¦  «        D ]j\  }
}|j	        |
         j
                             |j        g ¦  «        }|                     |d|…         ¦  «         t          |	t          |¦  «        ¦  «        }	Œkd|_        |	|_        |j        r|xj        |j        |j        z  z  c_        t'          j        d|j        › dt          |j        ¦  «        › dt          |j        ¦  «        › d�¦  «         �Œ\|sdS t          |¦  «        }t/          |¦  «        }| j         }|                      ¦   «         5  t3          j        |t2          j        ¬¦  «                             |j        d	¬
¦  «        }||j        |j        |j        f}t3          j         ||j!        |j        ¬¦  «        }tE          | j#        | j$        ¦  «        }tE          | j%        | j&        ¦  «        }tO          ||¦  «        D ]R\  }}|D ]3\  }}}||||z   …          (                    ||||z   …         d	¬
¦  «         Œ4| )                    d||¦  «         ŒS	 ddd¦  «         n# 1 swxY w Y   tU          | j+        |z   ¦  «        | _+        dS )zÀRestore KV caches from CPU for any CPU-offloaded requests in the scheduled batch. Indices are accumulated
        per group across all requests, then copied in one batched operation per layer.r   NFzRestored CPU-offloaded request z with z prefill tokens and z generated tokens.©r(   T©Únon_blockingr'   ),r   r�   Úis_cpu_offloadedr8   ru   rw   r9   ÚextendÚ	enumerateÚgroup_cache_managersÚblock_tableÚgetÚmaxr   rz   Úallow_block_sharingÚcomplete_blocksr}   rC   r   Údebugr~   r   r   rj   r;   Ú	as_tensorÚlongÚtor)   rD   rE   rG   r(   r   r3   r4   r5   r6   rH   Úcopy_Úindex_copy_Úsortedr7   )rO   r•   r   Úall_cpu_indicesÚall_gpu_indicesÚfuture_stater�   Úcpu_indicesÚgroup_countsÚmax_allocated_blocksÚ	group_idxÚnÚ
gpu_blocksr   Úgpu_idsÚstaging_shapeÚstagingÚ
cpu_cachesÚ	gpu_viewsÚ	cpu_cacheÚgpu_viewr   r   Úlengths                           r   Úrestore_scheduled_requestsz,OffloadingManager.restore_scheduled_requestsò   sw  € ð ”
ˆØ%'ˆØ%'ˆà-ð 	ñ 	ˆLà Ô&ˆEØÔ)ð Øð Ô8×<Ò<¸UÔ=MÑNÔNˆKØÔA×EÒEÀeÔFVÑWÔWˆLØ×"Ò" ;Ñ/Ô/Ð/ð $%Ð Ý )¨,Ñ 7Ô 7ð Rð R‘�	˜1Ø"Ô7¸	ÔBÔN×RÒRÐSXÔScÐegÑhÔh�
Ø×&Ò& z°"°1°"¤~Ñ6Ô6Ð6õ (+Ð+?ÅÀZÁÄÑ'QÔ'QÐ$Ð$à%*ˆEÔ"Ø%9ˆEÔ"àÔ(ð ZØÐ,Ô,°Ô0EÈÔIYÑ0YÑYÐ,Ô,ÝŒLðG°%Ô2Bð Gð GÍ#ÈeÔNbÑJcÔJcð Gð GÝ˜5Ô1Ñ2Ô2ðGð Gð Gñô ð ñ ð ð 	Ø�4õ �Ñ Ô ˆÝ˜Ñ/Ô/ˆØ”
ˆØ×ÒÑÔð 		:ð 		:Ý”o o½U¼ZÐHÑHÔH×KÒKÈEÌLÐgkÐKÑlÔlˆGØ Ô 0°%Ô2KÈUÌ^Ð\ˆMÝ”k -°u´{È5Ì<ÐXÑXÔXˆGÝ˜tÔ2°DÔ4IÑJÔJˆJÝ˜dÔ1°4Ô3HÑIÔIˆIÝ'*¨:°yÑ'AÔ'Að :ð :Ñ#�	˜8Ø-1ð rð rÑ)�E˜6 6Ø˜F V¨f¡_Ð4Ô5×;Ò;¸IÀeÈeÐV\ÉnÐF\Ô<]ÐlpÐ;ÑqÔqÐqÐqØ×$Ò$ Q¨°Ñ9Ô9Ð9Ð9ð:ð		:ð 		:ð 		:ñ 		:ô 		:ð 		:ð 		:ð 		:ð 		:ð 		:ð 		:øøøð 		:ð 		:ð 		:ð 		:õ !' tÔ'<¸Ñ'NÑ OÔ OˆÔÐÐs   Æ'DJ<Ê<K ËK Fr�   Úkeep_unsortedc                 ó”   — |j         r>|                      |j        ¦  «         d|_         |s| j                             ¦   «          dS dS dS )z=Free CPU blocks for a single request (e.g., on cancellation).FN)rš   Ú_return_cpu_blocksrw   r7   Úsort)rO   r�   r¼   s      r   Úfree_request_cpu_cachez(OffloadingManager.free_request_cpu_cache,  sc   € àÔ!ð 	-Ø×#Ò# EÔ$4Ñ5Ô5Ð5Ø%*ˆEÔ"Ø ð -ØÔ%×*Ò*Ñ,Ô,Ð,Ð,Ð,ð		-ð 	-ð-ð -r   c                 ó¨   — | j         j                             ¦   «         D ]}|                      |d¬¦  «         Œ| j                             ¦   «          dS )zPFree all CPU-offloaded caches in the waiting queue (e.g., on fail_all or reset).T)r¼   N)r    Úwaiting_requestsÚvaluesrÀ   r7   r¿   )rO   r�   s     r   Úfree_all_waiting_cpu_cachesz-OffloadingManager.free_all_waiting_cpu_caches4  s[   € à”^Ô4×;Ò;Ñ=Ô=ð 	Cð 	CˆEØ×'Ò'¨¸TÐ'ÑBÔBÐBÐBØÔ×"Ò"Ñ$Ô$Ð$Ð$Ð$r   c                 óÞ   — |                       ¦   «          | j                             ¦   «          | j                             ¦   «          t	          t          | j        ¦  «        ¦  «        | _        dS )z8Reset CPU offloading state for a new generation session.N)rÄ   r8   Úclearr9   rK   r   rA   r7   ri   s    r   ÚresetzOffloadingManager.reset:  s_   € à×(Ò(Ñ*Ô*Ð*ØÔ&×,Ò,Ñ.Ô.Ð.ØÔ.×4Ò4Ñ6Ô6Ð6Ý $¥U¨4Ô+?Ñ%@Ô%@Ñ AÔ AˆÔÐÐr   r�   c           	      ó&  — g }g }t          | j        ¦  «        }|D ]¾}g }g }| j        j        D ]Y}|j                             |j        g ¦  «        }	|                     |	¦  «         |                     t          |	¦  «        ¦  «         ŒZ|rPt          |¦  «        t          |¦  «        z   |k    r-|                     |||f¦  «         |                     |¦  «         Œ¿|st          ¦   «         S t          |¦  «        }
| j        d|
…         }| j        |
d…         | _        t          |¦  «        }|                      ¦   «         5  t          j        |t          j        ¬¦  «                             | j        j        d¬¦  «        }t#          | j        | j        ¦  «        }t#          | j        | j        ¦  «        }t-          ||¦  «        D ]Q\  }}|                     d|¦  «        }|D ]3\  }}}||||z   …                              ||||z   …         d¬¦  «         Œ4ŒR	 ddd¦  «         n# 1 swxY w Y   d}|D ]U\  }}}|||t          |¦  «        z   …         | j        |j        <   || j        |j        <   d|_        |t          |¦  «        z  }ŒVd„ |D ¦   «         S )a¯  Copy the KV cache blocks of as many victims as fit in the CPU swap pool from GPU to the pool, in one
        batched, non-blocking copy per layer. Returns the request ids that were offloaded.

        All transfers are enqueued on the compute stream with pinned destinations, so the host never waits on them:
        correctness is guaranteed by stream ordering, since restores and cache writes go through the same stream.
        Nr—   Tr˜   r   c                 ó$   — h | ]\  }}}|j         ’ŒS rm   )rw   )rn   r�   rS   s      r   ú	<setcomp>z4OffloadingManager._offload_to_cpu.<locals>.<setcomp>u  s!   € Ð>Ð>Ð>¡[ U¨A¨q�Ô Ð>Ð>Ð>r   )r   r7   r   r�   rž   rŸ   rw   r›   r   Úsetr   rj   r;   r¤   r¥   r¦   r)   r   r5   r6   r3   r4   rH   Úindex_selectr§   r8   r9   rš   )rO   r�   Ú	offloadedr«   Úfree_pool_blocksr�   Úgpu_indicesÚgroup_block_countsÚcmÚblocksr±   rª   r   r³   r·   r¶   r¹   r¸   Úgathered_blocksr   r   rº   s                         r   ry   z!OffloadingManager._offload_to_cpuA  s(  € ð FHˆ	Ø%'ˆÝ˜tÔ4Ñ5Ô5ÐØð 
	4ð 
	4ˆEØˆKØ!#ÐØ”jÔ5ð 7ð 7�Øœ×+Ò+¨EÔ,<¸bÑAÔA�Ø×"Ò" 6Ñ*Ô*Ð*Ø"×)Ò)­#¨f©+¬+Ñ6Ô6Ð6Ð6àð 4�s ?Ñ3Ô3µc¸+Ñ6FÔ6FÑFÐJZÒZÐZØ× Ò  %¨Ð6HÐ!IÑJÔJÐJØ×&Ò& {Ñ3Ô3Ð3øð ð 	Ý‘5”5ˆLõ �Ñ Ô ˆØÔ/°°°Ô3ˆØ $Ô 5°a°b°bÔ 9ˆÔÝ˜Ñ/Ô/ˆð ×ÒÑÔð 		ð 		Ý”o o½U¼ZÐHÑHÔH×KÒKÈDÌJÔL]ÐlpÐKÑqÔqˆGÝ˜dÔ1°4Ô3HÑIÔIˆIÝ˜tÔ2°DÔ4IÑJÔJˆJÝ'*¨9°jÑ'AÔ'Að ð Ñ#�˜)Ø"*×"7Ò"7¸¸7Ñ"CÔ"C�Ø-1ð ð Ñ)�E˜6 6Ø˜e e¨f¡nÐ4Ô5×;Ò;Ø'¨°¸&±Ð(@ÔAÐPTð <ñ ô ð ð ððð			ð 		ð 		ñ 		ô 		ð 		ð 		ð 		ð 		ð 		ð 		øøøð 		ð 		ð 		ð 		ð ˆØ6?ð 	'ð 	'Ñ2ˆE�;Ð 2Ø?NÈvÐX^ÕadÐepÑaqÔaqÑXqÐOqÔ?rˆDÔ*¨5Ô+;Ñ<ØGYˆDÔ2°5Ô3CÑDØ%)ˆEÔ"Ø•c˜+Ñ&Ô&Ñ&ˆFˆFØ>Ð>°IÐ>Ñ>Ô>Ð>s   Ä?CH"È"H&È)H&rw   c                 ó¦   — | j                              |¦  «        }| j                             |¦  «        }| j                             |¦  «         ||fS )z<Return CPU blocks to the free pool without copying anything.)r8   ru   r9   r7   r›   )rO   rw   Úcpu_idsr®   s       r   r¾   z$OffloadingManager._return_cpu_blocksw  sP   € àÔ0×4Ò4°ZÑ@Ô@ˆØÔ=×AÒAÀ*ÑMÔMˆØÔ×$Ò$ WÑ-Ô-Ð-Ø˜Ð$Ð$r   )F)r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Úfloatr;   rg   ÚStreamr	   rY   r>   r:   rj   r”   rK   r
   r»   r   ÚboolrÀ   rÄ   rÇ   rË   Ústrry   Útupler¾   rm   r   r   r   r   7   sÎ  € € € € € ðð ð9
à"ð9
ð ð9
ð  % t™|ð	9
ð
  ð9
ð œ
Ô)¨DÑ0ð9
ð .ð9
ð 
ð9
ð 9
ð 9
ð 9
ðv30¸UÀT¹\ð 30Ð]bð 30Ðgjð 30ð 30ð 30ð 30ðjnð nð nð> #ð >ð >ð >ð >ð@8P¸DÐASÔ<Tð 8PÐY]ð 8Pð 8Pð 8Pð 8Pðt-ð -¨Lð -Èð -ÐZ^ð -ð -ð -ð -ð%ð %ð %ð %ðBð Bð Bð Bð4? t¨LÔ'9ð 4?¸cÀ#¼hð 4?ð 4?ð 4?ð 4?ðl%¨Sð %°U¸4À¼9ÀdÈ3ÄiÐ;OÔ5Pð %ð %ð %ð %ð %ð %r   r   )rÙ   r‰   Ú
contextlibr   Ú	itertoolsr   r;   Úutilsr   r   r   Údistributedr	   Úrequestsr
   r   r   r   r    r   rK   r>   rÞ   r   r   rm   r   r   ú<module>rä      s%  ðð	ð 	ð €€€Ø "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð à €€€à (Ð (Ð (Ð (Ð (Ð (Ø &Ð &Ð &Ð &Ð &Ð &Ø *Ð *Ð *Ð *Ð *Ð *Ø MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MÐ MØ  Ð  Ð  Ð  Ð  Ð  ð˜T #œYð ¨4°°c¸3À°mÔ0DÔ+Eð ð ð ð ð"E%ð E%ð E%ð E%ð E%ñ E%ô E%ð E%ð E%ð E%r   