o
    }oi/                     @   sZ   d dl Z d dlZd dlmZmZ d dlZd dlZd dlmZ d dlm	Z	 G dd dZ
dS )    N)DictList)AutoencoderKL)nnc                   @   s   e Zd ZdZd&dededdfdd	Zd
d Zd'dejfddZ	dd Z
dd Zdd Zdd Zdd Zdee deddfddZdd Zd(d d!Zedefd"d#Zedefd$d%ZdS ))VAEGeneratoras  
    A class for generating and searching different Variational Autoencoder (VAE) configurations.

    This class provides functionality to generate various VAE architecture configurations
    given a specific input resolution and compression ratio. It allows searching through a
    design space to find configurations that match given parameter and memory budgets.
          input_resolutioncompression_ratioreturnNc                 C   sD   |dkr|dv s
J n|dkr|dv sJ nt d|| _|| _d S )Nr   )   r      )r   r       z3Higher resolution than 2028 is not implemented yet!)NotImplementedError_input_resolution_compression_ratio)selfr	   r
    r   Z/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/diffusion/vae/autovae.py__init__"   s   
zVAEGenerator.__init__c                 C   s(   t dd| j| j}|jt jdd}|S )z
        Generate a random input tensor with the specified input resolution.

        The tensor is placed on the GPU in half-precision (float16).
              cudadtypedevice)torchrandr	   tofloat16)r   random_tensorr   r   r   _generate_input-   s   zVAEGenerator._generate_inputmodelc                 C   s&   |dusJ dt dd | D S )z
        Count the number of trainable parameters in a given model.

        Args:
            model (nn.Module): The model for which to count parameters.

        Returns:
            int: The number of trainable parameters.
        Nz3Please provide a nn.Module to count the parameters.c                 s   s    | ]
}|j r| V  qd S N)requires_gradnumel).0pr   r   r   	<genexpr>B   s    z1VAEGenerator._count_parameters.<locals>.<genexpr>)sum
parameters)r   r"   r   r   r   _count_parameters7   s   
zVAEGenerator._count_parametersc                 C   s(   ddddg g ddddddd	d
g d}|S )z
        Load a base configuration skeleton for the VAE.

        Returns:
            dict: A dictionary representing the base configuration JSON skeleton.
        r   z0.20.0.dev0z../sdxl-vae/siluFr   r   r   gy&1?)_class_name_diffusers_version_name_or_pathact_fnblock_out_channelsdown_block_typesforce_upcastin_channelslatent_channelslayers_per_blocknorm_num_groupsout_channelssample_sizescaling_factorup_block_typesr   )r   skeletonr   r   r   _load_base_json_skeletonD   s"   z%VAEGenerator._load_base_json_skeletonc                    s\   t   } fdd|D }t tj| }g }|D ]}dd t||D }|| q|S )a0  
        Generates all possible combinations from a search space dictionary.

        Args:
            attr (dict): A dictionary where each key has a list of possible values.

        Returns:
            List[Dict]: A list of dictionaries, each representing a unique combination of attributes.
        c                    s   g | ]} | qS r   r   )r&   keyattrr   r   
<listcomp>i   s    z;VAEGenerator._generate_all_combinations.<locals>.<listcomp>c                 S   s   i | ]\}}||qS r   r   )r&   r?   valuer   r   r   
<dictcomp>n   s    z;VAEGenerator._generate_all_combinations.<locals>.<dictcomp>)listkeys	itertoolsproductzipappend)r   rA   rF   choicesall_combinationscombination_dictscombinationcombination_dictr   r@   r   _generate_all_combinations^   s   
z'VAEGenerator._generate_all_combinationsc                 C   sH   |   }|d |d< |d |d< |d |d< |d |d< |d |d< |S )a  
        Assign a chosen set of attributes to the base VAE configuration skeleton.

        Args:
            choice (dict): A dictionary of attributes to assign to the skeleton.

        Returns:
            dict: A dictionary representing the updated VAE configuration.
        r3   r<   r2   r7   r6   )r>   )r   choicesearch_space_skletonr   r   r   _assign_attributess   s   
zVAEGenerator._assign_attributesc                 C   s`   i }dgd g|d< dgd g|d< g dg dg dg d	g|d
< g d|d< g d|d< |S )z
        Define the search space for a 16x compression ratio at 1024 resolution.

        Returns:
            dict: A dictionary defining lists of possible attribute values.
        DownEncoderBlock2D   r3   UpDecoderBlock2Dr<   )         rY   rY   )rW   rX   rY   rY   r   )rW   rX   rY   r   r   )@   rW   rX   rY   rY   r2   r      r   r7      r   r   rZ   r6   r   r   rA   r   r   r   _search_space_16x1024   s   z"VAEGenerator._search_space_16x1024c                 C   sZ   i }dgd g|d< dgd g|d< g dg dg dg|d	< g d
|d< g d|d< |S )z
        Define the search space for an 8x compression ratio at 1024 resolution.

        Returns:
            dict: A dictionary defining lists of possible attribute values.
        rT   r^   r3   rV   r<   )rW   rX   rY   rY   )rW   rX   rY   r   )rZ   rW   rX   rY   r2   r[   r7   r]   r6   r   r_   r   r   r   _search_space_8x1024   s   z!VAEGenerator._search_space_8x1024datamodec                 C   s\   |dkr|j dd d d
S |dkr|j dd d d
S |dkr*|j dd d d
S td	)a)  
        Sort the list of design configurations in place based on a chosen mode.

        Args:
            data (List[Dict]): A list of dictionaries representing design configurations.
            mode (str): The sorting criterion. Can be 'abs_param_diff', 'abs_cuda_mem_diff', or 'mse'.
        abs_param_diffc                 S      t | d S )N
param_diffabsxr   r   r   <lambda>       z2VAEGenerator._sort_data_in_place.<locals>.<lambda>)r?   abs_cuda_mem_diffc                 S   re   )Ncuda_mem_diffrg   ri   r   r   r   rk      rl   msec                 S   s   | d d | d d  d S )Nrf   r\   rn   r   ri   r   r   r   rk      s    zGInvalid mode. Choose from 'abs_param_diff', 'abs_cuda_mem_diff', 'mse'.N)sort
ValueError)r   rb   rc   r   r   r   _sort_data_in_place   s   z VAEGenerator._sort_data_in_placec           	      C   s   d}t ||D ]\}}||d| 7 }qt| tdt|  |D ]}|d d|d  }||d d|d  7 }t| q#dS )	a  
        Print a formatted table of the design choices.

        Args:
            data (List[Dict]): The data to print, each entry a design configuration.
            headers (List[str]): Column headers.
            col_widths (List[int]): Widths for each column.
         <-rf   r   rn   r   N)rI   printr)   )	r   rb   headers
col_widths
header_rowheaderwidthitemrowr   r   r   _print_table   s   

zVAEGenerator._print_tabler   c              
   C   s  |dkr|dkrt dg }| jdkr"| jdkr"|  }| |}n| jdkr5| jdkr5|  }| |}|  }|jtj	dd}g }|D ]}d}d}	| 
|}
td t| t|
}|jtj	dd}| |}|d	 }tj  tj  tjjtjjjtjjjgd
d
d
d1}t }t  ||j }W d   n1 sw   Y  tj  t }W d   n1 sw   Y  || d }tj }|d }|| }|| }	|||	|
d td|  td| d td|dd t| j ddd td qEd}|dkrd}n
|dkrd}nd}td | !|| ddg}dd g}| "||| t|d d! }|S )"a  
        Search through available VAE design choices to find one that best matches
        the given parameter and memory budgets.

        Args:
            parameters_budget (float, optional): The target number of parameters (in millions).
            cuda_max_mem (float, optional): The target maximum GPU memory usage (in MB).

        Returns:
            AutoencoderKL: The chosen VAE configuration that best matches the provided budgets.
        r   zAPlease specify a valid parameter budget or cuda max memory budgetr   r   r   r   r   z--------------------i@B T)
activitiesprofile_memoryrecord_shapes
with_stackNi  i   )rf   rn   designz  Total params: z  Max GPU Memory Usage: z MBz  Total Execution Time: z.2fz mscuda_time_total
   )sort_by	row_limitrd   rm   ro   z####################zparam_diff (M)zcuda_mem_diff (MB)      r   )#rq   r	   r
   ra   rP   r`   r!   r   r   r   rS   rv   r   from_configr+   r   reset_peak_memory_statssynchronizeprofilerprofileProfilerActivityCPUCUDAtimeperf_counterno_gradencodelatent_distsamplemax_memory_allocatedrJ   key_averagestablerr   r~   )r   parameters_budgetcuda_max_memsearch_space_choicessearch_space
inp_tensordesign_choicesrQ   parameters_budget_diffcuda_max_mem_diffcurt_design_jsonvaetotal_paramsprof
start_time_end_timetotal_execution_time_msr   	sort_moderw   rx   r   r   r   search_for_target_vae   s   













z"VAEGenerator.search_for_target_vaec                 C      | j S )zp
        Get the input resolution for the VAE.

        Returns:
            int: The input resolution.
        )r   r   r   r   r   r	   -     zVAEGenerator.input_resolutionc                 C   r   )zt
        Get the compression ratio for the VAE.

        Returns:
            float: The compression ratio.
        )r   r   r   r   r   r
   7  r   zVAEGenerator.compression_ratio)r   r   r#   )r   r   )__name__
__module____qualname____doc__intr   r!   r   Moduler+   r>   rP   rS   r`   ra   r   r   strrr   r~   r   propertyr	   floatr
   r   r   r   r   r      s"    

^	r   )rG   r   typingr   r   r   torch.profiler	diffusersr   r   r   r   r   r   r   <module>   s   