
    bi              
          d dl Z d dlZd dlmZ d dlmZ d dlmZmZm	Z	m
Z
mZ d dlZddlmZ ddlmZmZ  e       r d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ  ej:                  e      Z G d de      Z  G d d      Z!	 	 dde"dejF                  jH                  dee"e%ejL                  f   de
d   fdZ' G d d      Z(dee"ef   dee"ef   fdZ) G d d      Z*y)    N)OrderedDict)combinations)AnyDictListOptionalUnion   )	ModelHook)is_accelerate_availablelogging)add_hook_to_moduleremove_hook_from_module)PartialState)send_to_device)clear_device_cache)convert_file_size_to_intc                       e Zd ZdZdZ	 	 	 ddeeeee	j                  f      deed      ded   fd	Zdd
ZddZd Zd Zy)CustomOffloadHooka  
    A hook that offloads a model on the CPU until its forward pass is called. It ensures the model and its inputs are
    on the given device. Optionally offloads other models to the CPU before the forward pass is called.

    Args:
        execution_device(`str`, `int` or `torch.device`, *optional*):
            The device on which the model should be executed. Will default to the MPS device if it's available, then
            GPU 0 if there is a GPU, and finally to the CPU.
    FNexecution_deviceother_hooksUserCustomOffloadHookoffload_strategyAutoOffloadStrategyc                 h    ||nt               j                  | _        || _        || _        d | _        y N)r   default_devicer   r   r   model_id)selfr   r   r   s       i/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/modular_pipelines/components_manager.py__init__zCustomOffloadHook.__init__5   s6     5E4P 0VbVdVsVs& 0    c                     || _         y r   r   )r   r   s     r    set_strategyzCustomOffloadHook.set_strategy@   s
     0r"   c                 `    | j                   g | _         | j                   j                  |       y)zM
        Add a hook to the list of hooks to consider for offloading.
        N)r   appendr   hooks     r    add_other_hookz CustomOffloadHook.add_other_hookC   s,     #!D%r"   c                 $    |j                  d      S )Ncpu)to)r   modules     r    	init_hookzCustomOffloadHook.init_hookK   s    yyr"   c           
      0   |j                   | j                  k7  rL| j                  $| j                  D cg c](  }|j                  j                   | j                  k(  s'|* }}t	        j
                         }| j                  )| j                  || j                  || j                        }t	        j
                         }t        j                  d| j                   d||z
  dd       |D ]O  }t        j                  d| j                   d| j                   d|j                   d	       |j                          Q |r
t                |j                  | j                         t        || j                        t        || j                        fS c c}w )
N)hooksr   modelr   z* time taken to apply offload strategy for : .2fz secondszmoving z to z, offloading z to cpu)devicer   r   r2   timeperf_counterr   r   loggerinfooffloadr   r-   r   )r   r.   argskwargsr)   hooks_to_offload
start_timeend_times           r    pre_forwardzCustomOffloadHook.pre_forwardN   ss   ==D111+595E5E#tTIZIZ^b^s^sIsD#t #t!..0
((4'+'<'<.!%$)-)>)>	 (= ($  ,,.@rS[^hShjmQnnvw - #DKK!$--T5J5J4K=Y]YfYfXggno LLN	# $&(IId++,dD$9$9:N6SWShSh<iii1 $us   (FF)NNN)r   r   r)   r   )__name__
__module____qualname____doc__no_gradr   r	   strinttorchr5   r   r!   r%   r*   r/   r@    r"   r    r   r   (   sw     G EI?C<@		"5c5<<)?#@A	 d#:;<	 ##89		1& jr"   r   c                   0    e Zd ZdZd Zd Zd Zd ZddZy)	r   z
    A simple hook grouping a model and a `CustomOffloadHook`, which provides easy APIs for to call the init method of
    the hook or remove it entirely.
    c                 .    || _         || _        || _        y r   r   r2   r)   )r   r   r2   r)   s       r    r!   zUserCustomOffloadHook.__init__r   s     
	r"   c                 N    | j                   j                  | j                         y r   )r)   r/   r2   r   s    r    r:   zUserCustomOffloadHook.offloadw   s    		DJJ'r"   c                 z    t        | j                  | j                         | j                  | j                  _        y r   )r   r2   r)   r   rO   s    r    attachzUserCustomOffloadHook.attachz   s$    4::tyy1!]]		r"   c                 P    t        | j                         d | j                  _        y r   )r   r2   r)   r   rO   s    r    removezUserCustomOffloadHook.remove~   s    

+!		r"   c                 :    | j                   j                  |       y r   )r)   r*   r(   s     r    r*   z$UserCustomOffloadHook.add_other_hook   s    		  &r"   NrA   )	rB   rC   rD   rE   r!   r:   rQ   rS   r*   rJ   r"   r    r   r   l   s     

(+"'r"   r   r   r2   r   r   r   c                 \    t        ||      }t        | ||      }|j                          |S )N)r   r   rM   )r   r   rQ   )r   r2   r   r   r)   	user_hooks         r    custom_offload_with_hookrW      s2     .>QabD%xu4PIr"   c                       e Zd ZdZddZd Zy)r   z
    Offload strategy that should be used with `CustomOffloadHook` to automatically offload models to the CPU based on
    the available memory on the device.
    c                 $    t        |      | _        y r   )r   memory_reserve_margin)r   rZ   s     r    r!   zAutoOffloadStrategy.__init__   s    %=>S%T"r"   c           
      Z   t        |      dk(  rg S |j                         }t        j                  j	                  |j
                        d   }|| j                  z
  }||k  rg S ||z
  }t        j                  d|dz  dd       t        t        |D ci c]'  }|j                  |j                  j                         ) c}j                         d d            }	d	 }
 |
|	|      }|t        j                  d
       |}|S |D cg c]  }|j                  |v s| }}|S c c}w c c}w )Nr   z2 search for models to offload in order to free up    @r4   z
 GB memoryc                     | d   S )N   rJ   )xs    r    <lambda>z.AutoOffloadStrategy.__call__.<locals>.<lambda>   s
    ad r"   T)keyreversec                      t         j                               }d}t        d      }t        dt	        |      dz         D ]9  }t        ||      D ](  }t         fd|D              }||k  r|||k  s%|}|}* ; |S )a  
            search the optimal combination of models to offload to cpu, given a dictionary of module sizes and a
            minimum memory offload size. the combination of models should add up to the smallest modulesize that is
            larger than `min_memory_offload`
            Ninfr^   c              3   (   K   | ]	  }|     y wr   rJ   ).0candidate_model_idmodule_sizess     r    	<genexpr>zNAutoOffloadStrategy.__call__.<locals>.search_best_candidate.<locals>.<genexpr>   s      )=O%78)   )listkeysfloatrangelenr   sum)rh   min_memory_offload	model_idsbest_candidate	best_sizercandidate_model_idscandidate_sizes   `       r    search_best_candidatez;AutoOffloadStrategy.__call__.<locals>.search_best_candidate   s     \..01I!NeI1c)nq01 
7+7	1+E 	7'%( )Sf) &N &(:: )1^i5O-@N(6I	7
7 "!r"   zJno combination of models to offload to cpu is found, offloading all models)ro   get_memory_footprintrI   cudamem_get_infoindexrZ   r8   r9   dictsortedr   r2   itemswarning)r   r1   r   r2   r   current_module_sizemem_on_devicerq   r)   rh   rx   best_offload_model_idsr=   s                r    __call__zAutoOffloadStrategy.__call__   s>   u:?I#88:

//0@0F0FGJ%(B(BB.I0=@HI[^eIefiHjjtuv NSTd

 ? ? AATZZ\"
	". "7|EW!X!)NNgh$   27b$--Ka:abbO UJ  cs   ,D#D(D(N)3GB)rB   rC   rD   rE   r!   r   rJ   r"   r    r   r      s    U8 r"   dreturnc                    i }| j                         D ]?  \  }}t        |t              rt        |      n|}||vrg ||<   ||   j	                  |       A dt
        t           dt        fd}i }|j                         D ]=  \  }} ||      }|r)t        | |d      t              rt        |      n|}|||<   9|d<   ? |S )a%  Summarizes a dictionary by finding common prefixes that share the same value.

    For a dictionary with dot-separated keys like: {
        'down_blocks.1.attentions.1.transformer_blocks.0.attn2.processor': [0.6],
        'down_blocks.1.attentions.1.transformer_blocks.1.attn2.processor': [0.6],
        'up_blocks.1.attentions.0.transformer_blocks.0.attn2.processor': [0.3],
    }

    Returns a dictionary where keys are the shortest common prefixes and values are their shared values: {
        'down_blocks': [0.6], 'up_blocks': [0.3]
    }
    rl   r   c                    | syt        |       dk(  r| d   S | D cg c]  }|j                  d       }}d}t        | D ]   }t        t        |            dk(  r|dz  }  n |dk(  rydj	                  |d   d|       S c c}w )zCFind the shortest common prefix among a list of dot-separated keys. r^   r   .N)ro   splitzipsetjoin)rl   k	key_partscommon_lengthpartss        r    find_common_prefixz=summarize_dict_by_value_and_parts.<locals>.find_common_prefix   s    t9>7N ,00aQWWS\0	0 )_ 	E3u:!#"		 A xx	!^m455 1s   A?r   r   )r   
isinstancerk   tupler'   r   rG   )	r   value_to_keysra   valuevalue_tupler   summaryrl   prefixs	            r    !summarize_dict_by_value_and_partsr      s     Mggi /
U&0&=eEl5m+)+M+&k"))#.	/6c 6s 62 G*002  T#D))3Ad1gJ)ED%;E#GFOGBK  Nr"   c                      e Zd ZdZg dZd Z	 	 	 	 ddee   dee   dee   dee   fd	Z	e
d
efd       Zd dededee   fdZd
edefdZd d
efdZ	 	 	 	 d!dee   dee   dee   defdZd"deeeej*                  f   fdZd Z	 d d
edeeeee   f      deeeef      fdZd Z	 	 	 	 dd
ee   dee   dee   dee   def
dZd#deeee   f   dee   fdZd$dee   dee   fdZd dee   dee   fdZy)%ComponentsManagera  
    A central registry and management system for model components across multiple pipelines.

    [`ComponentsManager`] provides a unified way to register, track, and reuse model components (like UNet, VAE, text
    encoders, etc.) across different modular pipelines. It includes features for duplicate detection, memory
    management, and component organization.

    <Tip warning={true}>

        This is an experimental feature and is likely to change in the future.

    </Tip>

    Example:
        ```python
        from diffusers import ComponentsManager

        # Create a components manager
        cm = ComponentsManager()

        # Add components
        cm.add("unet", unet_model, collection="sdxl")
        cm.add("vae", vae_model, collection="sdxl")

        # Enable auto offloading
        cm.enable_auto_cpu_offload(device="cuda")

        # Retrieve components
        unet = cm.get_one(name="unet", collection="sdxl")
        ```
    )	r   
added_time
collection
class_namesize_gbadaptershas_hookr   
ip_adapterc                 z    t               | _        t               | _        t               | _        d | _        d| _        y )NF)r   
componentsr   collectionsmodel_hooks_auto_offload_enabledrO   s    r    r!   zComponentsManager.__init__C  s.    %-%-&=%*"r"   Nnamer   load_idr   c                    || j                   }|rKt               }|j                         D ]-  \  }}| j                  |      }||k(  s|j	                  |       / nt        |j                               }|rFt               }	|j                         D ](  \  }}|| j                  |   v s|	j	                  |       * nt        |j                               }	|rQt               }
|j                         D ]3  \  }}t        |d      s|j                  |k(  s#|
j	                  |       5 nt        |j                               }
|j                  |	      j                  |
      }|S )z
        Lookup component_ids by name, collection, or load_id. Does not support pattern matching. Returns a set of
        component_ids
        _diffusers_load_id)
r   r   r   _id_to_nameaddrl   r   hasattrr   intersection)r   r   r   r   r   ids_by_namecomponent_id	component	comp_nameids_by_collectionids_by_load_ididss               r    _lookup_idszComponentsManager._lookup_idsK  sO    J%K+5+;+;+= 2'i ,,\:	$OOL12
 joo/0K #+5+;+;+= 8'i4#3#3J#??%)),78 !$JOO$5 6 UN#-#3#3#5 -i9&:;	@\@\`g@g"&&t,- !!23N&&'89FF~V
r"   r   c                 H    dj                  | j                  d      d d       S )N_)r   r   )r   s    r    r   zComponentsManager._id_to_names  s#    xx**3/455r"   r   c           
         | dt        |       }d}| j                  j                         D ]b  \  }}||k(  s| j                  |      }||k(  r"t        j                  d| d| d       |}d} n!t        j                  d| d| d	| d
       d t        |d      r||j                  dk7  rm| j                  |j                        }	|	D 
cg c]
  }
|
|k7  s	|
 }	}
|	r:dj                  |	      }t        j                  d| d|j                   d| d       || j                  |<   t        j                         | j                  |<   |r|| j                  vrt               | j                  |<   || j                  |   vr| j                  ||      }|D ]2  }t        j                  d| d| d|        | j                  ||       4 | j                  |   j                  |       t        j!                  d| d| d|        nt        j!                  d| d| d       | j"                  r|r| j%                  | j&                         |S c c}
w )a  
        Add a component to the ComponentsManager.

        Args:
            name (str): The name of the component
            component (Any): The component to add
            collection (Optional[str]): The collection to add the component to

        Returns:
            str: The unique component ID, which is generated as "{name}_{id(component)}" where
                 id(component) is Python's built-in unique identifier for the object
        r   TzComponentsManager: component 'z' already exists as ''Fz%ComponentsManager: adding component 'z' as 'z', but it is duplicate of 'zK'To remove a duplicate, call `components_manager.remove('<component_id>')`.r   null)r   , z!', but it has duplicate load_id 'z' with existing components: zL. To remove a duplicate, call `components_manager.remove('<component_id>')`.r   r   z%ComponentsManager: removing existing z from collection '': z$ComponentsManager: added component 'z' in collection ')idr   r   r   r8   r   r   r   r   r   r6   r   r   r   remove_from_collectionr   r9   r   enable_auto_cpu_offload_auto_offload_device)r   r   r   r   r   is_new_componentcomp_idcompr   components_with_same_load_idr   existingcomp_ids_in_collections                r    r   zComponentsManager.addw  s    qI0 "__224 	MGTy  ,,W5	$NN%CD6I^_f^ggh#ij#*L',$NN?vVL>Ytu|t} ~e f	 923	8T8TX^8^+/+;+;ID`D`+;+a(9U+l2Y[_kYkB+l(+l+99%AB;L>Ijkt  lH  lH  kI  Ie  fn  eo oa b )2%(,		%!1!11/2u  ,4#3#3J#??)-)9)9tPZ)9)[&5 EGNN?vEWXbWccfgnfop //DE   ,00>:4&@QR\Q]]`am`no KK>tfF<.XYZ[%%*:(()B)BCG ,ms   
IIc                    || j                   vrt        j                  d| d       y|| j                   |   vrt        j                  d| d| d       y| j                   |   j                  |       | j                   j	                         D cg c]  \  }}||v s| }}}|s+t        j                  d| d       | j                  |       yyc c}}w )	z7
        Remove a component from a collection.
        zCollection ' ' not found in ComponentsManagerNComponent 'z' not found in collection 'r   z'ComponentsManager: removing component 'z' from ComponentsManager)r   r8   r   rS   r   )r   r   r   collcomps
comp_collss         r    r   z(ComponentsManager.remove_from_collection  s     T---NN\*5UVWt//
;;NN[6QR\Q]]^_`$++L9.2.>.>.D.D.F`{tU,Z_J_d`
`NND\NRjklKK%  as   CCc                    || j                   vrt        j                  d| d       y| j                   j                  |      }| j                  j                  |       | j
                  D ]2  }|| j
                  |   v s| j
                  |   j                  |       4 | j                  r| j                  | j                         yt        |t        j                  j                        r|j                  d       ~ddl}|j!                          t        j"                  j%                         rt        j"                  j'                          yy)z
        Remove a component from the ComponentsManager.

        Args:
            component_id (str): The ID of the component to remove
        r   r   Nr,   r   )r   r8   r   popr   r   rS   r   r   r   r   rI   nnModuler-   gccollectrz   is_availableempty_cache)r   r   r   r   r   s        r    rS   zComponentsManager.remove  s    t.NN[6VWXOO''5	L)** 	BJt//
;;  ,33LA	B %%(()B)BC)UXX__5U#JJLzz&&(

&&( )r"   namesreturn_dict_with_namesc                 6	   	  j                  ||      }|D ci c]  }| j                  |    }} fd}	 |||      S t        t              st	        dt               d      |j                         D 	ci c]  }	|	 j                  |	       c}	d"fd	j                  d      }
|
rdd d	v rj                  d	      }i }|j                         D ]:  \  	}t        d
 |D              t        	fd|D              }|
r| }|s6||	<   < |
rdnd}rdnd}t        j                  d| | d| dt        |j                                       nt        fdj!                         D              r|j                         D 	ci c]  \  }	}|	   k(  |
k7  r|	| }}	}|
r4t        j                  d dt        |j                                       nut        j                  d dt        |j                                       nAj#                  d      rdd }|j                         D 	ci c]  \  }	}|	   j                  |      |
k7  r|	|! }}	}|
r4t        j                  d| dt        |j                                       nt        j                  d| dt        |j                                       nj                  d      rj#                  d      rdd ndd }|j                         D 	ci c]  \  }	}||	   v |
k7  r|	| }}	}|
r3t        j                  d| dt        |j                                       nt        j                  d| dt        |j                                       nt        fdj!                         D              r|j                         D 	ci c]  \  }	}|	   v |
k7  r|	| }}	}|
r3t        j                  d dt        |j                                       nBt        j                  d dt        |j                                       nt	        d d      |st	        d  d!       |||      S c c}w c c}	w c c}}	w c c}}	w c c}}	w c c}}	w )#ai  
        Search components by name with simple pattern matching. Optionally filter by collection or load_id.

        Args:
            names: Component name(s) or pattern(s)
                Patterns:
                - "unet" : match any component with base name "unet" (e.g., unet_123abc)
                - "!unet" : everything except components with base name "unet"
                - "unet*" : anything with base name starting with "unet"
                - "!unet*" : anything with base name NOT starting with "unet"
                - "*unet*" : anything with base name containing "unet"
                - "!*unet*" : anything with base name NOT containing "unet"
                - "refiner|vae|unet" : anything with base name exactly matching "refiner", "vae", or "unet"
                - "!refiner|vae|unet" : anything with base name NOT exactly matching "refiner", "vae", or "unet"
                - "unet*|vae*" : anything with base name starting with "unet" OR starting with "vae"
            collection: Optional collection to filter by
            load_id: Optional load_id to filter by
            return_dict_with_names:
                                    If True, returns a dictionary with component names as keys, throw an error if
                                    multiple components with the same name are found If False, returns a dictionary
                                    with component IDs as keys

        Returns:
            Dictionary mapping component names to components if return_dict_with_names=True, or a dictionary mapping
            component IDs to components if return_dict_with_names=False
        )r   r   c                     |rEi }| j                         D ].  \  }}j                  |      }||v rt        d| d      |||<   0 |S | S )a7  
            Create a dictionary mapping component names to components if return_dict_with_names=True, or a dictionary
            mapping component IDs to components if return_dict_with_names=False, throw an error if duplicate component
            names are found when return_dict_with_names=True
            7Duplicate component names found in the search results: ], please set `return_dict_with_names=False` to return a dictionary with component IDs as keys)r   r   
ValueError)r   r   dict_to_returnr   r   r   r   s         r    get_return_dictz<ComponentsManager.search_components.<locals>.get_return_dict  s~     &!#%/%5%5%7 5MGT $ 0 0 9I N2(UV_U`  a~    15N9-5 &%!!r"   NzInvalid type for `names: z, only support stringc                     |    }|r||k(  S |j                  d      r|dd }|j                  |      S |j                  d      r|j                  d      r|dd n|dd }||v S ||k(  S )aA  
            Helper function to check if a component matches a pattern based on its base name.

            Args:
                component_id: The component ID to check
                pattern: The pattern to match against
                exact_match: If True, only exact matches to base_name are considered
            *Nr   r^   )endswith
startswith)r   patternexact_match	base_namer   search
base_namess         r    matches_patternz<ComponentsManager.search_components.<locals>.matches_pattern4  s     #<0I )++ !!#& " ++F33 ##C(*1*:*:3*?2WQR[** )++r"   !r^   |c              3   f   K   | ])  }|j                  d       xs |j                  d         + yw)r   N)r   r   )rf   terms     r    ri   z6ComponentsManager.search_components.<locals>.<genexpr>]  s+     !eW[ts';'Qt}}S?Q"R!es   /1c              3   2   K   | ]  } |        y wr   rJ   )rf   r   r   r   r   s     r    ri   z6ComponentsManager.search_components.<locals>.<genexpr>`  s     $cUY_WdK%P$cs   zNOT r   zexactly matchingzmatching any of patternszGetting components  r3   c              3   (   K   | ]	  }|k(    y wr   rJ   rf   r   r   s     r    ri   z6ComponentsManager.search_components.<locals>.<genexpr>n  s     I	)#Irj   z4Getting all components except those with base name 'r   z#Getting components with base name 'r   r   z&Getting components NOT starting with 'z"Getting components starting with 'z#Getting components NOT containing 'zGetting components containing 'c              3   &   K   | ]  }|v  
 y wr   rJ   r   s     r    ri   z6ComponentsManager.search_components.<locals>.<genexpr>  s     I	)#Is   zComponent or pattern 'r   z&No components found matching pattern 'r   )F)r   r   r   rG   r   typerl   r   r   r   r   allanyr8   r9   rk   valuesr   )r   r   r   r   r   selected_idsr   r   r   r   is_not_patterntermsmatchesr   should_includelog_msg
match_typer   r   r   r   r   s   ``       `         @@@r    search_componentsz#ComponentsManager.search_components  s   F '':w'O5ABa++B
B	"( =":/EFF E3'8eEZ[\\ ISHYZWgt//88Z
	,< ))#.!"IE %<KK$EG!+!1!1!3 ,!!e_d!ee "%$c]b$c!c ")7%7N!'+GG$, !/fBG/:+@ZJKK-gYzl!E7"TRYR^R^R`MaLbcd IZ5F5F5HII &0%5%5%7!GTw'50^C G  RSXRYY\]abibnbnbp]q\rstA%DQXQ]Q]Q_L`Kabc ^^C 3BZF &0%5%5%7!GTg&11&9^K G 
 DVHCPTU\UaUaUcPdOefg@DQXQ]Q]Q_L`Kabc c"$)NN3$7U1R[U12YF &0%5%5%7!GTj11nD G 
 A&TRYR^R^R`MaLbcd=fXSgllnI]H^_` IZ5F5F5HII &0%5%5%7!GTZ00^C G 
 A%DQXQ]Q]Q_L`Kabc=eWCW\\^H\G]^_ 5eW<\]^^EeWANOOw(>??i C< [~s#   Q9Q>R$R	RRr5   c                 z   t               st        d      | j                  j                         D ]D  \  }}t	        |t
        j                  j                        s+t        |d      s8t        |d       F | j                          t        |      }t        j                  |      }|j                  $t        j                  |j                   dd       }g }| j                  j                         D ]J  \  }}t	        |t
        j                  j                        s+t        ||||	      }|j!                  |       L |D ]\  }|D cg c]	  }||us| }	}|	D ]A  }
|
j"                  j$                  |j"                  j$                  k(  s1|j'                  |
       C ^ || _        d| _        || _        yc c}w )
a  
        Enable automatic CPU offloading for all components.

        The algorithm works as follows:
        1. All models start on CPU by default
        2. When a model's forward pass is called, it's moved to the execution device
        3. If there's insufficient memory, other models on the device are moved back to CPU
        4. The system tries to offload the smallest combination of models that frees enough memory
        5. Models stay on the execution device until another model needs memory and forces them off

        Args:
            device (Union[str, int, torch.device]): The execution device where models are moved for forward passes
            memory_reserve_margin (str): The memory reserve margin to use, default is 3GB. This is the amount of
                                        memory to keep free on the device to avoid running out of memory during model
                                        execution (e.g., for intermediate activations, gradients, etc.)
        z7Make sure to install accelerate to use auto_cpu_offload_hf_hookT)recurse)rZ   N:r   r$   )r   ImportErrorr   r   r   rI   r   r   r   r   disable_auto_cpu_offloadr   r5   r|   r   rW   r'   r)   r   r*   r   r   r   )r   r5   rZ   r   r   r   	all_hooksr)   hr   
other_hooks              r    r   z)ComponentsManager.enable_auto_cpu_offload  s   " '(WXX#446 	AOD))UXX__5')Z:X'	4@	A 	%%'.EZ[f%<<\\V[[M1#"67F	#446 	'OD))UXX__5/iZjk  &	'
  	4D&/A1D=1AKA) 4
??33tyy7Q7QQ''
34	4 %%)"$*! Bs   
	F8F8c                     | j                   d| _        y| j                   D ]"  }|j                          |j                          $ | j                   r
t	                d| _         d| _        y)zF
        Disable automatic CPU offloading for all components.
        NF)r   r   r:   rS   r   r(   s     r    r	  z*ComponentsManager.disable_auto_cpu_offload  sc     #).D&$$ 	DLLNKKM	  %*"r"   fieldsr   c           
      T   || j                   vrt        d| d      | j                   |   }|7t        |t              r|g}|D ]  }|| j                  vst        d| d       || j
                  |   dj                  | j                  j                         D cg c]  \  }}||v s| c}}      xs dd}t        |t        j                  j                        rt        |d      }d}	|r,t        |j                  d	      r|j                  j                  }	|j                  |j                   j"                  |j%                         d
z  d||	d       t        |d      r&t'        |j(                  j+                               |d<   t        |d      rt        |d      rt-        j.                  |j0                        }
|
j3                         D cg c]  }|j                   j"                   }}t5        d |D              ra|
j                         D ci c]6  \  }}t        |d      r%d|j                   j"                  v r||j6                  8 }}}|rt9        |      |d<   |)|j                         D ci c]  \  }}||v s|| c}}S |S c c}}w c c}w c c}}w c c}}w )a  Get comprehensive information about a component.

        Args:
            component_id (str): Name of the component to get info for
            fields (Optional[Union[str, List[str]]]):
                   Field(s) to return. Can be a string for single field or list of fields. If None, uses the
                   available_info_fields setting.

        Returns:
            Dictionary containing requested component metadata. If fields is specified, returns only those fields.
            Otherwise, returns all fields.
        r   r   NzField 'z$' not found in available_info_fieldsr   )r   r   r   r  r   r\   )r   r   r   r   r   peft_configr   _load_ip_adapter_weightsattn_processorsc              3   $   K   | ]  }d |v  
 yw)	IPAdapterNrJ   )rf   ptypes     r    ri   z3ComponentsManager.get_model_info.<locals>.<genexpr>(  s     I{e+Is   scaler  r   )r   r   r   rG   _available_info_fieldsr   r   r   r   rI   r   r   r   r  r   update	__class__rB   ry   rk   r  rl   copydeepcopyr  r   r   r  r   )r   r   r  r   fieldr   r   r9   r   r   
processorsvprocessor_typesr   scaless                  r    get_model_infoz ComponentsManager.get_model_info  s   " t.{<.8XYZZOOL1	 &#&  \ ; ;;$wug5Y%Z[[\ %//,7))T=M=M=S=S=U$okdEYeinYnT$op 	
 i1y*5H#GI$6$68JK#,#5#5#F#F KK"+"5"5">">(==?7K $ ((8 y-0#'	(=(=(B(B(D#EZ  y"<=')UfBg!]]9+D+DE
AKARARAT"UA1;;#7#7"U"UIII %/$4$4$6 Aq"1g.;!++BVBV3V 177
F 
 -Nv-V\* %)ZZ\ATQQ&[AqDAAK[ %p< #V Bs$   J*JJ;J;J$J$c                    | j                   syd }d }| j                   j                         D cg c]:  }t        |t        j                  j
                        rt        |d      r ||      < }}|r/t        dg|D cg c]  }t        t        |             c}z         nd}i }| j                   j                         D ]N  }g ||<   | j                  j                         D ]  \  }	}
||
v s||   j                  |	         ||   rIdg||<   P |j                         D 	cg c]  }|D ]  }	|	  }}}	|rt        dt        d |D                    nd}t        dt        d	 | j                   j                         D                    t        d
t        d | j                   j                         D                    ddd||d}dt        |j                               t        |      dz  z   dz
  z  dz   }dt        |j                               t        |      dz  z   dz
  z  dz   }d|z   }| j                   j                         D ci c]-  \  }}t        |t        j                  j
                        s+||/ }}}| j                   j                         D ci c]-  \  }}t        |t        j                  j
                        r+||/ }}}|r|d|z   z  }|dd|d    dddd|d    ddz  }|dd|d    dddd|d    ddz  }|d d|d!    ddd"d|d#    dd$z  }||z  }|j                         D ]-  \  }}| j                  |      } |||      }t        |d      rt        |j                         nd} ||      }||   r||   d%   nd}||d|d    dd|d&   d|d    ddz  }||d|d    dd|d|d    ddz  }||d'   d|d!    d(d|d|d#    dd| dz  }t#        dt        ||               D ]^  }||   |   }|dd|d    dddd|d    ddz  }|dd|d    dddd|d    ddz  }|dd|d!    dddd|d#    dd| dz  }` 0 ||z  }|r|r|dz  }|d)|z   z  }|d*d|d    dddd|d    dd$z  }||z  }|j                         D ]  \  }}| j                  |      }||   r||   d%   nd}||d|d    dd|j$                  j&                  d|d    dd| dz  }t#        dt        ||               D ](  }||   |   }|dd|d    dddd|d    dd| dz  }*  ||z  }|d+z  }| j                   D ]v  }| j                  |      }||j)                  d,      |j)                  d-      s:|d| d.z  }|j)                  d,      |d/|d,    dz  }|j)                  d-      sr|d0z  }x |S c c}w c c}w c c}	}w c c}}w c c}}w )1NzComponents:
==================================================
No components registered.
==================================================c                 4    t        | d      r| j                  S y)Nr   N/A)r   r   )r   s    r    get_load_idz/ComponentsManager.__repr__.<locals>.get_load_id?  s    y"67 333r"   c                     |d   st        t        | dd            S t        t        | dd            }t        |d   xs d      }| d| dS )Nr   r5   r$  r   ())rG   getattr)r   r9   r5   exec_devices       r    format_devicez1ComponentsManager.__repr__.<locals>.format_deviceE  sY    
#79h>??WY%@A!$'9":"CeD ;-q11r"   r      r$  
   c              3   D   K   | ]  }t        t        |              y wr   )ro   rG   )rf   cs     r    ri   z-ComponentsManager.__repr__.<locals>.<genexpr>a  s     (NSV(Ns    c              3   2   K   | ]  }t        |        y wr   )ro   )rf   r   s     r    ri   z-ComponentsManager.__repr__.<locals>.<genexpr>d  s     KDc$iKs      c              3   Z   K   | ]#  }t        |j                  j                         % y wr   )ro   r  rB   )rf   r   s     r    ri   z-ComponentsManager.__repr__.<locals>.<genexpr>e  s!      myY%8%8%A%A!B ms   )+   )r   classr5   dtypesizer   r   =   r^   
-zComponents:
zModels:
Name_ID<r   r   z | Classr4  zDevice: act(exec)r5   Dtyper5  z	Size (GB)r6  zLoad IDr   z | Collection
r   r   r   r4   zOther Components:
IDzO
Additional Component Info:
==================================================
r   r   z:
z  Adapters: z  IP-Adapter: Enabled
)r   r   r   rI   r   r   r   maxro   rG   rl   r   r   r'   rp   r!  r5  rn   r  rB   get)r   r%  r+  r   load_idslidmax_load_id_lencomponent_collectionsr   r   r   collsall_collectionsmax_collection_len
col_widthssep_line	dash_lineoutputr   r  modelsothersr9   
device_strr5  r   first_collectionir   s                                r    __repr__zComponentsManager.__repr__9  s<   Z		2 "__335
)UXX__5')Ma:b 	"
 

 NV#rdx%Hc#c(m%HHI[] !#OO((* 	6D*,!$'#//557 =e5=)$/66t<= )./4g%d+	6 .C-I-I-K^EX]^PT4^4^^SbSS(No(N%NOhj b#KDOO4H4H4JKKLS mTXTcTcTjTjTl mmn&,

 #j//12S_q5HH1LMPTT3z0023c*o6IIAMNQUU	 8+ $(??#8#8#:]41ajEHHOO>\!Q$]]#'??#8#8#:a41a*QPUPXPXP_P_B`!Q$aa kI--F1Z%5$6`"67s71ZPWEXDYYYBY:ZZ]^^F,Qz(/C.D@,DESQRS]^eSfRgggPgHhhkllFQz&'9&: $:;3y:V_K`JaaaHa>bbqrrFiF $*<<> mi**40*9d;
07	70KIOO,QV%i0 F[[_E`#8#>q#Afk T!Jt$4#5P!56c$|:LQzZaObNcccLc9ddghhZ*X*>)?p'?@E!JW^L_K```I`CaadeeT)_Qz&/A.B#,EFc'RST^_hTiSjjjQjIkkno  oA  AC  D  D q#&;D&A"BC mA!6t!<Q!?JAj&6%7p#7 8BqGAT@UUU>U;VVYZZFAj&:%;0#; <C1ZPWEXDYYYBY?ZZ]^^FAj&8%9#9 :#b:iCXBYYY@Y=ZZ]^h]iikllF	mm( iF $+i77Fa
4 0112#ga
7@S?TTT=T5UUdeeFiF $*<<> ii**40 F[[_E`#8#>q#Afk T!Jt$4#5P!56c):M:M:V:VWXYcdkYlXmmmVm9nnq  sC  rD  DF  G  G q#&;D&A"BC iA!6t!<Q!?JAj&6%7p#7 8BqGAT@UUU>U;VVYZdYeeghhFii iF 	DDOO 	8D&&t,DTXXj%9%ER^I_BtfC.(88J'3T*-=,>bAAF88L)77F	8 [

 &I _( ^as)   ?W&>W+
$W0	,W66W6,W<W<c           	      |   ||||t        d      |,|| j                  vrt        d| d      | j                  |   S | j                  |||      }|st        d| d      t        |      dkD  r(t        d| dt	        |j                                      t        t        |j                                     S )	a  
        Get a single component by either:
        - searching name (pattern matching), collection, or load_id.
        - passing in a component_id
        Raises an error if multiple components match or none are found.

        Args:
            component_id (Optional[str]): Optional component ID to get
            name (Optional[str]): Component name or pattern
            collection (Optional[str]): Optional collection to filter by
            load_id (Optional[str]): Optional load_id to filter by

        Returns:
            A single component

        Raises:
            ValueError: If no components match or multiple components match
        zFIf searching by component_id, do not pass name, collection, or load_idr   r   zNo components found matching 'r   r^   z$Multiple components found matching 'r   )	r   r   r  ro   rk   rl   nextiterr   )r   r   r   r   r   resultss         r    get_onezComponentsManager.get_one  s    4 #)9Z=SW^Wjeff #4??2 ;|n<\!]^^??<00((z7C=dV1EFFw<!CD6TRYR^R^R`MaLbcddD)*++r"   c                     t               }t        |t              s|g}|D ]$  }|j                  | j	                  ||             & t        |      S )a4  
        Get component IDs by a list of names, optionally filtered by collection.

        Args:
            names (Union[str, List[str]]): List of component names
            collection (Optional[str]): Optional collection to filter by

        Returns:
            List[str]: List of component IDs
        r   )r   r   rk   r  r   )r   r   r   r   r   s        r    get_idszComponentsManager.get_ids  sS     e%&GE 	KDJJt''Tj'IJ	KCyr"   r   c                     |D ci c]  }|| j                   |    }}|rEi }|j                         D ].  \  }}| j                  |      }||v rt        d| d      |||<   0 |S |S c c}w )al  
        Get components by a list of IDs.

        Args:
            ids (List[str]):
                List of component IDs
            return_dict_with_names (Optional[bool]):
                Whether to return a dictionary with component names as keys:

        Returns:
            Dict[str, Any]: Dictionary of components.
                - If return_dict_with_names=True, keys are component names.
                - If return_dict_with_names=False, keys are component IDs.

        Raises:
            ValueError: If duplicate component names are found in the search results when return_dict_with_names=True
        r   r   )r   r   r   r   )	r   r   r   r   r   r   r   r   r   s	            r    get_components_by_idsz'ComponentsManager.get_components_by_ids  s    $ 9<<"b$//"--<
<!N!+!1!1!3 1 ,,W5	.$QR[Q\  ]z  {  -1y)1 "! =s   A'c                 H    | j                  ||      }| j                  |      S )a  
        Get components by a list of names, optionally filtered by collection.

        Args:
            names (List[str]): List of component names
            collection (Optional[str]): Optional collection to filter by

        Returns:
            Dict[str, Any]: Dictionary of components with component names as keys

        Raises:
            ValueError: If duplicate component names are found in the search results
        )rY  r[  )r   r   r   r   s       r    get_components_by_namesz)ComponentsManager.get_components_by_names  s%     ll5*-))#..r"   )NNNNr   )NNNT)rz   r   NN)T) rB   rC   rD   rE   r  r!   r   rG   r   r   staticmethodr   r   r   r   rS   boolr  r	   rH   rI   r5   r   r	  r   r   r!  rR  rW  rY  r[  r]  rJ   r"   r    r   r     s2   @
+ #$(!%,0&sm& SM& #	&
 [)&P 6# 6 6E E E# EN&3 &C &$)3 )B  $$(!%'+x@}x@ SMx@ #	x@
 !%x@t++eCell4J.K ++Z+( 37OO sDI~./O 
$sCx.	!	OdBL '+"$(!%+,sm+, sm+, SM	+,
 #+, 
+,ZU3S	>2 xPS} $c HUYN B/T#Y /HSM /r"   r   r^  )+r  r6   r   r   	itertoolsr   typingr   r   r   r   r	   rI   r1   r   utilsr   r   accelerate.hooksr   r   accelerate.stater   accelerate.utilsr   accelerate.utils.memoryr   accelerate.utils.modelingr   
get_loggerrB   r8   r   r   rG   r   r   rH   r5   rW   r   r   r   rJ   r"   r    <module>rj     s      # " 3 3   L-/:B			H	%Aj	 AjH' ': 7;8<			88??	 Cell23	 45		C  C P8c3h 8DcN 8vV/ V/r"   