
    jn&              	          d dl Z d dlmZmZ d dlmZ d dlmZmZm	Z	m
Z
 d dlmZ d dlmZ d Zd Zd Zd	 Zd
ej        de	fdZ	 dd
ej        de	dedefdZdd
ej        de	defdZdd
ej        de	defdZ G d de          ZdS )    N)partialreduce)product)CallableLiteralTupleUnion)Modulec                 <   t          || z            }|r-t          j        |t          j                  | dz
  |dz
  z  z  }n<d|z  }|dz
  |z  | z
  dz   dz  }t          j        |t          j                  |z  |z
  }dg|z  }	d|	|<   |                    |	          S )Ndtype      )intmxarangefloat32reshape)
Nscalealign_cornersdimndimsMindicesstepstartshapes
             `/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/mlx/nn/layers/upsample.py_scaled_indicesr!      s    EAIA @)ARZ000QUq1u4EF5ya%4!#a'1,)ARZ00047%?C%KEE#J??5!!!    c                 B   t          || z            }t          j        |t          j                  }|| k    r#|dz   | |z  z  dz
  }|                                }n|| |z  z  }dg|z  }d||<   |                    t          j                                      |          S )Nr   g      ?r   r   )r   r   r   r   roundastypeuint32r   )r   r   r   r   r   r   r   s          r    _nearest_indicesr'      s    EAIAi,,,G1uuS=QU+c1--//QU#C%KEE#J>>")$$,,U333r"   c                 j   t          | ||||          }t          j        |d| dz
            }t          j        |          }t          j        |          }||z
  }t          j        |d          }|                    t          j                  d|z
  f|                    t          j                  |ffS )Nr   r   a_mina_maxr   )r!   r   clipfloorceilexpand_dimsr%   r&   )	r   r   r   r   r   r   	indices_l	indices_rweights	            r    _linear_indicesr3   (   s    asEBBGggQa!e444G!!I  Iy F^FB''F 
		")	$	$a&j1			")	$	$f- r"   c                 N   t          | ||||          }t          j        |          }t          j        |dz             }|dz
  }|dz   }	t          t          j        d          d             }
 |
||d          d         } |
||d          d         } |
||d          d         } |
||	d          d         }t          j        |d| dz
  	          }t          j        |d| dz
  	          }t          j        |d| dz
  	          }t          j        |	d| dz
  	          }	|                    t          j                  |f|                    t          j                  |f|                    t          j                  |f|	                    t          j                  |ffS )
Nr   T)	shapelessc                     d}t          j        | |z
            }|dk    r|dz   |z  |dz   z
  |z  |z  dz   }n|dz
  |z  dz   |z  dz
  |z  }|S )Ng      r   g       @g      @         )r   abs)indgriddistaxr2   s         r    _get_weightz#_cubic_indices.<locals>._get_weight=   sq     F3:1993w!mq3w/14q81<FFA{Q!+a/14Fr"   )r=   ).Nr   r   r)   )r!   r   r-   r   compiler,   r%   r&   )r   r   r   r   r   r   
indices_l1
indices_r1
indices_l2
indices_r2r@   	weight_l1	weight_r1	weight_l2	weight_r2s                  r    _cubic_indicesrJ   6   s   asEBBG'""J'A+&&JaJaJRZ4(((	 	 )(	 GZa888CIGZa888CIGZa888CIGZa888CI 1AE:::J1AE:::J1AE:::J1AE:::J 
		29	%	%y1			29	%	%y1			29	%	%y1			29	%	%y1	 r"   r?   scale_factorc           	         | j         dz
  }|t          |          k    rt          d          t          t	          t
          |                    |k    rt          | j                  }t          |          D ]}|	                    dd|z  z   d           | 
                    |          } t          |          D ] }t          ||                   |dd|z  z   <   !t          j        | |          } t          |          D ]6}||dz   xx         ||dz            z  cc<   |                    |dz              7| 
                    |          } | S | j        ^}}}t          d           g}t          t!          ||                    D ]-\  }	\  }
}|                    t%          |
||	|                     .t          |          }| |         S )Nr   7A scale needs to be provided for each spatial dimensionr   )ndimlen
ValueErrortuplemapr   listr   rangeinsertr   r   broadcast_topopslice	enumeratezipappendr'   )r?   rK   dimsr   dBr   Cr   inss               r    upsample_nearestrc   \   s   6A:Ds<    RSSS Sl##$$44QWt 	' 	'ALLQUA&&&&IIet 	4 	4A"<?33E!a!e)OAu%%t 	 	A!a%LLLE!a%L(LLLIIa!eIIe 7Aq;;-"3q,#7#788 	< 	<IAv1NN+Aq!T::;;;;..zr"   F
indices_fnr   c           
      <   | j         dz
  }|t          |          k    rt          d          | j        ^}}}g }t	          t          ||                    D ]*\  }	\  }
}|                     ||
|||	|                     +g }g }t          | D ]g}t          | \  }}|                    | t          d           f|z                       |                    t          t          j        |                     ht          d t          ||          D                       S )Nr   rM   c              3   &   K   | ]\  }}||z  V  d S )N ).0wixis      r    	<genexpr>z_interpolate.<locals>.<genexpr>   s*      ;;62rrBw;;;;;;r"   )rN   rO   rP   r   rY   rZ   r[   r   rX   r   operatormulsum)r?   rK   rd   r   r\   r^   r   r_   r   r`   ra   rb   samplesweights
idx_weightidxr2   s                    r    _interpolaters   z   s3    6A:Ds<    RSSSwHA1 Gs1l3344 A A	6Aqzz!Qq$??@@@@ GGw' 5 5
:&Vq%++#-.///vhlF334444 ;;S'%:%:;;;;;;r"   c                 2    t          | |t          |          S N)r?   rK   rd   r   )rs   r3   r?   rK   r   s      r    upsample_linearrw      s%    
!"#	   r"   c                 2    t          | |t          |          S ru   )rs   rJ   rv   s      r    upsample_cubicry      s%    
!!#	   r"   c                        e Zd ZdZ	 	 ddeeef         ded         def fdZ	d	e
fd
Zdej        d	ej        fdZ xZS )Upsamplea
  Upsample the input signal spatially.

    The spatial dimensions are by convention dimensions ``1`` to ``x.ndim -
    2``. The first is the batch dimension and the last is the feature
    dimension.

    For example, an audio signal would be 3D with 1 spatial dimension, an image
    4D with 2 and so on and so forth.

    There are three upsampling algorithms implemented nearest neighbor upsampling,
    linear interpolation, and cubic interpolation. All can be applied to any number
    of spatial dimensions. The linear interpolation will be bilinear, trilinear etc
    when applied to more than one spatial dimension. And cubic interpolation will be
    bicubic when there are 2 spatial dimensions.

    .. note::
       When using one of the linear or cubic interpolation modes the ``align_corners``
       argument changes how the corners are treated in the input image. If
       ``align_corners=True`` then the top and left edge of the input and
       output will be matching as will the bottom right edge.

    Parameters:
        scale_factor (float or tuple): The multiplier for the spatial size.
            If a ``float`` is provided, it is the multiplier for all spatial dimensions.
            Otherwise, the number of scale factors provided must match the
            number of spatial dimensions.
        mode (str, optional): The upsampling algorithm, either ``"nearest"``,
            ``"linear"`` or ``"cubic"``. Default: ``"nearest"``.
        align_corners (bool, optional): Changes the way the corners are treated
            during ``"linear"`` and ``"cubic"`` upsampling.  See the note above and the
            examples below for more details.  Default: ``False``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn as nn
        >>> x = mx.arange(1, 5).reshape((1, 2, 2, 1))
        >>> x
        array([[[[1],
                 [2]],
                [[3],
                 [4]]]], dtype=int32)
        >>> n = nn.Upsample(scale_factor=2, mode='nearest')
        >>> n(x).squeeze()
        array([[1, 1, 2, 2],
               [1, 1, 2, 2],
               [3, 3, 4, 4],
               [3, 3, 4, 4]], dtype=int32)
        >>> b = nn.Upsample(scale_factor=2, mode='linear')
        >>> b(x).squeeze()
        array([[1, 1.25, 1.75, 2],
               [1.5, 1.75, 2.25, 2.5],
               [2.5, 2.75, 3.25, 3.5],
               [3, 3.25, 3.75, 4]], dtype=float32)
        >>> b = nn.Upsample(scale_factor=2, mode='linear', align_corners=True)
        >>> b(x).squeeze()
        array([[1, 1.33333, 1.66667, 2],
               [1.66667, 2, 2.33333, 2.66667],
               [2.33333, 2.66667, 3, 3.33333],
               [3, 3.33333, 3.66667, 4]], dtype=float32)
    nearestFrK   moder|   linearcubicr   c                 @   t                                                       |dvrt          d|           t          |t          t
          f          r(t          t          t          |                    | _        nt          |          | _        || _	        || _
        d S )Nr~   z1[Upsample] Got unsupported upsampling algorithm: )super__init__rP   
isinstancerS   rQ   rR   floatrK   r}   r   )selfrK   r}   r   	__class__s       r    r   zUpsample.__init__   s     	555WQUWWXXXlT5M22 	4 %c%&>&> ? ?D %l 3 3D	*r"   returnc                 6    d| j          d| j        d| j         S )Nzscale_factor=z, mode=z, align_corners=)rK   r}   r   )r   s    r    _extra_reprzUpsample._extra_repr   s9    2D- 2 2di 2 2!/2 2	
r"   r?   c                    |j         dz
  }|dk    rt          d|j          d          | j        }t          |t                    r)t          |          |k    rt          d| d|           n|f|z  }| j        dk    rt          ||          S | j        dk    rt          ||| j	                  S | j        d	k    rt          ||| j	                  S t          d
| j                   )Nr   r   zg[Upsample] The input should have at least 1 spatial dimension which means it should be at least 3D but zD was providedzH[Upsample] One scale per spatial dimension is required but scale_factor=z+ and the number of spatial dimensions were r|   r   r   zUnknown interpolation mode: )rN   rP   rK   r   rQ   rO   r}   rc   rw   r   ry   	Exception)r   r?   r\   rK   s       r    __call__zUpsample.__call__   s.   vz199*6* * *   (lE** 	2<  D(( .$0. .'+. .   ) )?T1L9	!!#A|444Y("""1lD4FGGGY'!!!!\43EFFFF49FFGGGr"   )r|   F)__name__
__module____qualname____doc__r	   r   r   r   boolr   strr   r   arrayr   __classcell__)r   s   @r    r{   r{      s        ; ;@ 7@#	+ +E5L)+ 23+ 	+ + + + + + 
S 
 
 
 
H"( Hrx H H H H H H H Hr"   r{   )F)rl   	functoolsr   r   	itertoolsr   typingr   r   r   r	   mlx.corecorer   mlx.nn.layers.baser
   r!   r'   r3   rJ   r   rc   r   rs   rw   ry   r{   rg   r"   r    <module>r      s    % % % % % % % %       2 2 2 2 2 2 2 2 2 2 2 2       % % % % % %" " "
4 
4 
4  # # #L     > SX< <	x<$<2:<KO< < < <4 rx u T     bh e D    oH oH oH oH oHv oH oH oH oH oHr"   