
    2Vh)                         d dl Zd dlmZ d dlmZ d dlmZ d dlmZ dZ ed      d        Z	 ed	      dd
       Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)    Nbackend)ops)tree)keras_export   z$keras.utils.unpack_x_y_sample_weightc                    t        | t              rt        |       } t        | t              s| ddfS t        |       dk(  r| d   ddfS t        |       dk(  r| d   | d   dfS t        |       dk(  r| d   | d   | d   fS d|  }t	        |      )a%  Unpacks user-provided data tuple.

    This is a convenience utility to be used when overriding
    `Model.train_step`, `Model.test_step`, or `Model.predict_step`.
    This utility makes it easy to support data of the form `(x,)`,
    `(x, y)`, or `(x, y, sample_weight)`.

    Example:

    >>> features_batch = ops.ones((10, 5))
    >>> labels_batch = ops.zeros((10, 5))
    >>> data = (features_batch, labels_batch)
    >>> # `y` and `sample_weight` will default to `None` if not provided.
    >>> x, y, sample_weight = unpack_x_y_sample_weight(data)
    >>> sample_weight is None
    True

    Args:
        data: A tuple of the form `(x,)`, `(x, y)`, or `(x, y, sample_weight)`.

    Returns:
        The unpacked tuple, with `None`s for `y` and `sample_weight` if they are
        not provided.
    N   r   r      z[Data is expected to be in format `x`, `(x,)`, `(x, y)`, or `(x, y, sample_weight)`, found: )
isinstancelisttuplelen
ValueError)data	error_msgs     c/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/trainers/data_adapters/data_adapter_utils.pyunpack_x_y_sample_weightr      s    4 $T{dE"dD!!	TaQt$$	TaQa$''	TaQa$q'**	..2V	5  Y
    z"keras.utils.pack_x_y_sample_weightc                 R    |t        | t        t        f      s| S | fS || |fS | ||fS )a}  Packs user-provided data into a tuple.

    This is a convenience utility for packing data into the tuple formats
    that `Model.fit()` uses.

    Example:

    >>> x = ops.ones((10, 1))
    >>> data = pack_x_y_sample_weight(x)
    >>> isinstance(data, ops.Tensor)
    True
    >>> y = ops.ones((10, 1))
    >>> data = pack_x_y_sample_weight(x, y)
    >>> isinstance(data, tuple)
    True
    >>> x, y = data

    Args:
        x: Features to pass to `Model`.
        y: Ground-truth targets to pass to `Model`.
        sample_weight: Sample weight for each element.

    Returns:
        Tuple in the format used in `Model.fit()`.
    )r   r   r   xysample_weights      r   pack_x_y_sample_weightr   6   sA    6 	y
 !eT]+H4K		1v1m$$r   c                 <    t        | t              rt        |       S | S )zFDatasets will stack any list of tensors, so we convert them to tuples.)r   r   r   )
maybe_lists    r   list_to_tupler   `   s    *d#Z  r   c                    t        d t        j                  |       D              }t        |      dkD  rZd}t	        g d|       D ]<  \  }}dj                  d t        j                  |      D              }|d| d| d	z  }> t        |      y )
Nc              3   L   K   | ]  }t        |j                  d            ywr   N)intshape.0is     r   	<genexpr>z)check_data_cardinality.<locals>.<genexpr>h   s     B!c!''!*oB   "$r
   zWData cardinality is ambiguous. Make sure all arrays contain the same number of samples.r   z, c              3   L   K   | ]  }t        |j                  d            ywr!   )strr#   r$   s     r   r'   z)check_data_cardinality.<locals>.<genexpr>o   s!      $%AGGAJr(   'z	' sizes: 
)setr   flattenr   zipjoinr   )r   num_samplesmsglabelsingle_datasizess         r   check_data_cardinalityr6   g   s    Bt||D/ABBK
;!G 	 #&&A4"H 	1E;II )-k)B E QugYugR00C		1
 o r   c                    t        j                  |       }t        j                  |j                  d   ft        j                               }t        |j                        dkD  rA|j                  d   dk7  rt        j                  |d      }nt        j                  |d      }t        j                  |      j                  d      }t        |j                  d         D ]#  }|j                  t        ||         d      ||<   % |S )Nr   r#   dtyper
   axisint32g      ?)r   convert_to_numpynponesr#   r   floatxr   argmaxsqueezeroundastyperangegetr"   )r   class_weighty_numpyr   r&   s        r   class_weight_to_sample_weightsrJ   v   s     ""1%GGG7==#3"5W^^=MNM
7==A==!iib1Gjjr2Ghhw&&w/G7==#$ B'++C
OSAaBr   c                 F    ddl m fd}t        j                  |g|  S )a  Return the common tensor spec for a list of batches.

    Args:
        batches: list of structures of tensors. The structures must be
            identical, but the shape at each leaf may be different.
    Returns: the common tensor spec for all the batches.
    r   
tensorflowc                  H   | d   }t        |j                        }|dk  r%t        d| dt        |j                         d      | D ]+  }t        |j                        |k7  st        d| d|        g }t        | D cg c]  }t	        |j                         c} D ]<  }t        |      }|j                  t        |      dk(  r|j                         nd        > d |d<   t        j                  j                        }t        |j                        r3j                  |||j                  |j                  j                        S t        |j                         st#        |      st%        |      rj'                  ||	      S j)                  ||	      S c c}w )
Nr   r
   zWWhen passing a dataset to a Keras model, the arrays must be at least rank 1. Received: z	 of rank .zsWhen passing a dataset to a Keras model, the corresponding arrays in each batch must have the same rank. Received: z and )r#   r9   ragged_rankrow_splits_dtyper8   )r   r#   r   r/   r   r-   appendpopr   standardize_dtyper9   r   RaggedTensorRaggedTensorSpecrP   
row_splitsSparseTensoris_scipy_sparseis_jax_sparseSparseTensorSpec
TensorSpec)	tensorsr   ranktr#   dimsdims_setr9   tfs	           r   get_single_tensor_specz/get_tensor_spec.<locals>.get_single_tensor_spec   s   AJ177|!81129S\N!M   	A177|t# ''(cqc3 	  9A$qww-9: 	ID4yHLL3x=A+=4H	I a))!''2a)&&MM!"!3!3	 '   q"//*q!Q&&U%&@@==uE=::) :s   F)keras.src.utils.module_utilsrM   r   map_structure)batchesrc   rb   s     @r   get_tensor_specrg      s'     >&;P 4?w??r   c              #   t   K   dd l dd lmc m fd}| D ]  }t	        j
                  ||        y w)Nr   c                     t        | j                  j                  t        j                  f      r| S t        |       rt        |       S t        |       rt        |       S t        j                  |       S N)
r   Array	JAXSparser?   ndarrayrY   scipy_sparse_to_jax_sparseis_tensorflow_sparsetf_sparse_to_jax_sparseasarrayr   jax
jax_sparses    r   convert_to_jax_compatiblez3get_jax_iterator.<locals>.convert_to_jax_compatible   s[    a#))Z%9%92::FGHQ-a00!!$*1--::a= r   )rs   jax.experimental.sparseexperimentalsparser   re   )iterableru   batchrs   rt   s      @@r   get_jax_iteratorr{      s<     00!  C  !:EBBCs   48c              #   P   K   d }| D ]  }t        j                  ||        y w)Nc                     t        | t        j                        s<t        | d      r0t	        |       r| j                         } t        j                  |       } | S )N	__array__)r   r?   rm   hasattris_torch_tensorcpurq   r   s    r   r>   z,get_numpy_iterator.<locals>.convert_to_numpy   sA    !RZZ( q+&"1%AJJqMr   )r   re   )ry   r>   rz   s      r   get_numpy_iteratorr      s0     	  :  !1599:s   $&c                     dd l mc m} ddlm  G fdd|j
                        } ||       }|j                  |d       S )Nr   convert_to_tensorc                       e Zd Zd Z fdZy)6get_torch_dataloader.<locals>.ConverterIterableDatasetc                     || _         y rj   )ry   )selfry   s     r   __init__z?get_torch_dataloader.<locals>.ConverterIterableDataset.__init__   s	    $DMr   c              3   `   K   | j                   D ]  }t        j                  |        y wrj   )ry   r   re   )r   rz   r   s     r   __iter__z?get_torch_dataloader.<locals>.ConverterIterableDataset.__iter__   s0      C(():EBBCs   +.N)__name__
__module____qualname__r   r   r   s   r   ConverterIterableDatasetr      s    	%	Cr   r   )
batch_size)torch.utils.datautilsr   keras.src.backend.torch.corer   IterableDataset
DataLoader)ry   
torch_datar   datasetr   s       @r   get_torch_dataloaderr      sB    ))>C:#=#= C 'x0G  T ::r   c                    t        | d      r|| j                  j                  dv r!dt        | j                  j                        v S | j                  j
                  D ]*  }|j                  dv sdt        |j                        v s* y y)N	__class__)rU   rX   tensorflow.python.TensorTF)r   r   r   r*   r   __mro__valueparents     r   is_tensorflow_tensorr      s    uk"??##'GG'3u/I/I+JJJoo-- 	F8,1E!!J 2 		
 r   c                     t        | d      r<| j                  j                  dk(  xr! dt        | j                  j                        v S y)Nr   rU   r   Fr   r   r   r*   r   r   s    r   is_tensorflow_raggedr      E    uk"OO$$6 H$EOO,F,F(GG	
 r   c                     t        | d      r<| j                  j                  dk(  xr! dt        | j                  j                        v S y)Nr   rX   r   Fr   r   s    r   ro   ro     r   r   c                     t        | d      rE| j                  j                  D ],  }|j                  dk(  st	        |j
                        dk(  s, y t        |       S )Nr   rk   rs   T)r   r   r   r   r*   r   rZ   r   s     r   is_jax_arrayr     sS    uk"oo-- 	F')c&2C2C.D.M	 r   c                 x    t        | d      r.t        | j                  j                        j	                  d      S y)Nr   zjax.experimental.sparseF)r   r*   r   r   
startswithr   s    r   rZ   rZ     s6    uk"5??--.99%
 	
 r   c                     t        | d      rQ| j                  j                  D ]8  }|j                  dk(  st	        |j
                        j                  d      s8 y y)Nr   r   torchTF)r   r   r   r   r*   r   endswithr   s     r   r   r     sV    uk"oo-- 	F(*s63D3D/E/N/N0 		
 r   c                 z    t        | j                  j                        j                  d      xr t	        | d      S )Nzscipy.sparsetocoo)r*   r   r   r   r   r   s    r   rY   rY   )  s6    q{{%%&11.A g	7G r   c                 &   ddl m} | j                         }t        j                  t        j
                  |j                  d      t        j
                  |j                  d      fd      }|j                  ||j                  |j                        S )Nr   rL   r
   r;   )rd   rM   r   r?   concatenateexpand_dimsrowcolrX   r   r#   )r   rb   cooindicess       r   scipy_sparse_to_tf_sparser   /  sc    =
'')Cnn		#R^^CGGQ%?@qG ??7CHHcii88r   c                     dd l }dd lmc m} |j	                  |j                  d      d         5  |j                  j                  |       cd d d        S # 1 sw Y   y xY w)Nr   r   r   )rs   rv   rw   rx   default_devicelocal_devicesBCOOfrom_scipy_sparserr   s      r   rn   rn   9  sS    00			C--e-<Q?	@ 40034 4 4s   AA c                 J   dd l }dd lmc m} t	        j
                  | j                        }t	        j
                  | j                        }|j                  |j                  d      d         5  |j                  ||f| j                        cd d d        S # 1 sw Y   y xY w)Nr   r   r   )r#   )rs   rv   rw   rx   r?   rq   valuesr   r   r   r   r#   )r   rs   rt   r   r   s        r   rp   rp   A  s    00ZZ!Fjj#G			C--e-<Q?	@ A0@A A As   0BB"c                 p    ddl m} |j                  | j                  | j                  | j
                        S )Nr   rL   )rd   rM   rX   r   r   r#   )r   rb   s     r   jax_sparse_to_tf_sparser   K  s$    =??199affagg66r   )NN)numpyr?   	keras.srcr   r   r   keras.src.api_exportr   NUM_BATCHES_FOR_TENSOR_SPECr   r   r   r6   rJ   rg   r{   r   r   r   r   ro   r   rZ   r   rY   r   rn   rp   r    r   r   <module>r      s        -  45'  6' T 23&% 4&%R$2@jC$: ;$	 94A7r   