
    2Vh                        d dl Z d dlZd dlZd dlmZ d dl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 d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ  G d dej<                        ZddZ  G d de      Z!y)    N)partial)backend)	callbacks)
optimizers)tree)config)distribution_lib)trainer)array_slicing)data_adapter_utils)EpochIterator)traceback_utilsc                   n    e Zd Z fdZ	 	 ddZd Zd Zd Zd ZddZ	ddZ
dd	Zdd
Zej                  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zej                  	 	 	 	 	 	 	 	 dd       Zej                  	 dd       Z	 	 	 	 ddZ	 	 	 ddZd Zd Zd Zd Z	 	 	 	 ddZ	 	 	 	 ddZ	 	 	 	 	 d dZ xZS )!
JAXTrainerc                 Z    t         |           d | _        d | _        d | _        d| _        y )NT)super__init__train_functiontest_functionpredict_function_jax_state_synced)self	__class__s    M/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/backend/jax/trainer.pyr   zJAXTrainer.__init__   s.    "! $!%    c	           
      .   i }	| j                   r||	d<    | j                  |||fddi|	\  }
}}|r!| j                  j                          || _        | j	                  ||||||
||      \  }}|r| j                  j                          |\  }}}|}|ro| j
                  ct        t        | j
                  j                  |            }t        j                  |      5  | j
                  j                  |      }ddd       |||
||ffS # 1 sw Y   xY w)z?This method is stateless and is intended for use with jax.grad.trainingreturn_lossesT)xyy_predsample_weightr   Nstate_mapping)_call_has_training_argstateless_call_losses_overrideclearstateless_compute_loss	optimizerlistzip	variablesr   StatelessScope
scale_loss)r   trainable_variablesnon_trainable_variablesmetrics_variablesr   r    r"   r   optimizer_variableskwargsr!   losseslossr-   unscaled_lossmappings                   r   compute_loss_and_updatesz#JAXTrainer.compute_loss_and_updates   sS    &&!)F: 3F$2E2E#3
 	3

 3
/' !!'')$*D!55#' 6 	
i !!'') 	J	57H
 23t~~779LMNG''g> 7~~0067#	
 
 	
7 7s   DDc                    t        j                  t        | j                  |      D cg c]	  \  }}||f c}}      5 }	| j                  j                  |t        j                  |      d   j                  d          | j                  ||||      }
d d d        g }| j                  D ]2  }	j                  |      }||j                  }|j                  |       4 
|fS c c}}w # 1 sw Y   VxY w)Nr#   r   )r"   )r   r.   r,   r2   _loss_trackerupdate_stater   flattenshapecompute_metricsget_current_valuevalueappend)r   r2   r7   r   r    r!   r"   ref_vvscopelogsnew_metrics_variablesnew_vs                r   _update_metrics_variablesz$JAXTrainer._update_metrics_variablesZ   s    ## !$D$:$:<M NE1 

 		E
 ++T\\!_Q-?-E-Ea-H ,  ''1fmDD		E !#++ 	0E++E2E}!((/		0
 ***!		E 		Es   C$
 AC**C3c           
      `   |\  }}}}t        j                  |      \  }}}	t        j                  | j                  d      }
 |
||||||	d|      \  \  }}}|\  }}}}| j
                  j                  |||      \  }}| j                  ||||||	      \  }}| j                  ||||      }||fS )NT)has_aux)r   r3   )	r   unpack_x_y_sample_weightjaxvalue_and_gradr9   r*   stateless_applyrI   _enforce_jax_state_sharding)r   statedatar0   r1   r3   r2   r   r    r"   grad_fnr6   auxgradsr7   r!   rF   s                    r   
train_stepzJAXTrainer.train_stepp   s    	
#0II$O1m$$))4
 %# 3	
sU  	L 79J NN**(;
	

 #'"@"@}aFM#
 00#	
 U{r   c           	          |\  }}}t        j                  |      \  }}}| j                  ||||||d      \  }	}
|
\  }}}}| j                  ||||||      \  }}| j	                  ||d |      \  }}}}|||f}||fS )NF)r   r0   r1   r3   r2   )r   rL   r9   rI   rP   )r   rQ   rR   r0   r1   r2   r   r    r"   r6   rT   r7   r!   rF   _s                  r   	test_stepzJAXTrainer.test_step   s    
 		
#0II$O1m11# 2 
	c  	L 79J #'"@"@}aFM#
 ,, 3$; $/	 - 
	
#  #

 U{r   c                     |\  }}i }| j                   rd|d<   t        j                  |      \  }}} | j                  |||fi |\  }}| j	                  d |d d       \  }}}}||fS )NFr   rX   )r%   r   rL   r&   rP   )	r   rQ   rR   r0   r1   r4   r   rY   outputss	            r   predict_stepzJAXTrainer.predict_step   s    7<44&&!&F:$==dC1a+>4+>+>!8!,
?E,
(( ,, $$; $"	 - 
	
# ///r   c                       j                   dkD  rC|r9d  j                  s! j                  rt        j                         fd}|S  fd}|S fd}|S )N   c                 T    | d   }| dd  D ]  }t        j                  d ||      } |S )Nr   r_   c                 D    t         j                  j                  | |g      S N)rM   numpyconcatenate)t1t2s     r   <lambda>z@JAXTrainer._make_function.<locals>.concatenate.<locals>.<lambda>   s    399+@+@"b+J r   )r   map_structure)r\   outputnext_outputs      r   rd   z.JAXTrainer._make_function.<locals>.concatenate   s@    $QZF'.qr{ !%!3!3J"'" "Mr   c                     t        |      } | |      \  }} |g}	 t        j                  dz
        D ]*  }t        |      } | |      \  }} |j                  |       , 	  |      }|| fS # t        $ r Y w xY wNr_   )nextrangesteps_per_executionrB   StopIteration)	rQ   iteratorrR   r\   rY   _outputsrd   r   step_functions	         r   iterator_stepz0JAXTrainer._make_function.<locals>.iterator_step   s    >D%25$%?NGU&iG!&t'?'?!'C!D 5A#'>D.;E4.HOHe#NN845 *'2G"E>) ) s   AA/ /	A;:A;c                     t        |      } | |      \  }} 	 t        j                  dz
        D ]  }t        |      } | |      \  }}  	 || fS # t        $ r Y || fS w xY wrl   )rm   rn   ro   rp   )rQ   rq   rR   r\   rY   r   rs   s        r   rt   z0JAXTrainer._make_function.<locals>.iterator_step   s    >D%25$%?NGU!&t'?'?!'C!D HA#'>D-:5$-GNGUH
 #E>) ) "E>)s   4A 	A"!A"c                 (     | t        |            S rb   )rm   )rQ   rq   rs   s     r   rt   z0JAXTrainer._make_function.<locals>.iterator_step  s    $UDN;;r   )ro   run_eagerlyjit_compilerM   jit)r   rs   concatenate_outputsrt   rd   s   ``  @r   _make_functionzJAXTrainer._make_function   sb    ##a'"" ''D,<,<"%''+"6K*@ !	*  < r   c                     | j                   |sy | j                  s.| j                  r"t        j                  | j
                  d      }n| j
                  }| j                  |      }|| _         y Nr   donate_argnums)r   rw   rx   rM   ry   rV   r{   )r   forcerV   rs   s       r   make_train_functionzJAXTrainer.make_train_function  s[    *5D$4$4
 CJJ++J7+r   c                     | j                   |sy | j                  s.| j                  r"t        j                  | j
                  d      }n| j
                  }| j                  |      }|| _         y r}   )r   rw   rx   rM   ry   rZ   r{   )r   r   rZ   rs   s       r   make_test_functionzJAXTrainer.make_test_function   s[    )%D$4$4
 qAII++I6*r   c                       j                   |s j                   S  fd} j                  s# j                  rt        j                  |d      } j                  |d      fd}| _         y )Nc                 @    j                  | |      \  }}|| d   |ffS )Nr   )r]   )rQ   rR   r\   r1   r   s       r   r]   z6JAXTrainer.make_predict_function.<locals>.predict_step4  s0    /3/@/@/M,G,U1X'>???r   r   r~   T)rz   c                 $     | |      \  }} || fS rb    )rQ   rq   r\   _step_functions      r   rs   z7JAXTrainer.make_predict_function.<locals>.step_function?  s    +E8<NGUE>!r   )r   rw   rx   rM   ry   r{   )r   r   r]   rs   r   s   `   @r   make_predict_functionz JAXTrainer.make_predict_function0  so      ,U(((	@ D$4$477<BL,,d - 
	" !.r   c                    | j                  d       t        j                         }|r||k  rt        j                  d|z         |}d | _        |r#|!t        j                  |||f|      \  \  }}}}|t        j                  |      \  }}}t        ||||||	|
| j                        }| j                  |       |j                          t        |t        j                         s)t        j                   |d|dk7  |||j"                  |       }| j%                          | j'                          d	| _        i }d	}|j+                          | j,                  xs |}	 t/        ||      D ]  }| j1                          |j3                  |       d| _        |j7                         5  |D ]  \  }}|j9                  |       | j4                  r| j;                  ddddd
      }d	| _        | j=                  |      \  }}|\  }}}} |||| d| _        |jA                  ||       | j(                  s n d d d        | jC                          tE        | jG                              }!|| jI                  ||      rtK        | dd       %t        |xs || j                  |d	      | _        | jM                  |xs |||dd      }"|"jO                         D #$ci c]  \  }#}$d|#z   |$ }"}#}$|!jQ                  |"       |jS                  ||!       |!}| j(                  s n d}| jC                          t        | jT                  tV        jX                        r*|dkD  r%| jT                  j[                  | j\                         tK        | dd       | `|r|j_                  |       d | _        | ja                          | jb                  S # 1 sw Y   xY wc c}$}#w # | jC                          t        | jT                  tV        jX                        r*|dkD  r%| jT                  j[                  | j\                         tK        | dd       | `|r|j_                  |       d | _        | ja                          w xY w)NfitzLimiting epochs to %d)validation_split)r   r    r"   
batch_sizesteps_per_epochshuffleclass_weightro   rq   Tr   )add_historyadd_progbarverboseepochsstepsmodelFr0   r1   r3   r2   purge_model_variablesrX   _eval_epoch_iterator)r   r    r"   r   ro   r   r   )r   r    r"   r   r   r   return_dict_use_cached_eval_datasetval_)rF   )2_assert_compile_calledr   
max_epochswarningswarnr   r   train_validation_splitr   rL   JAXEpochIteratorro   _symbolic_buildreset
isinstancecallbacks_moduleCallbackListnum_batches$_record_training_state_sharding_specr   stop_trainingon_train_begin_initial_epochrn   reset_metricson_epoch_beginr   catch_stop_iterationon_train_batch_begin_get_jax_stater   
_jax_stateon_train_batch_endjax_state_syncdict_get_metrics_result_or_logs_should_evalgetattrevaluateitemsupdateon_epoch_endr*   optimizers_module	Optimizerfinalize_variable_valuestrainable_weightson_train_end_clear_jax_state_shardinghistory)%r   r   r    r   r   r   r   r   validation_datar   r   r"   initial_epochr   validation_stepsvalidation_batch_sizevalidation_freqr   val_xval_yval_sample_weightepoch_iteratortraining_logstraining_finishedepochsteprq   rQ   rF   r0   r1   r3   r2   
epoch_logsval_logsnamevals%                                        r   r   zJAXTrainer.fitE  s   ( 	##E*&&(
*v-MM1J>?F$(! 7 44A}%8H%A}
 &
 #;;OL	! *'!+% $ 8 8	
 	n5 )%5%B%BC(55 #qL$00I 	113  ""!  "++<}l	-}f5 Y""$((/)-&#88: '"*8 &"h!66t<  11$($7$7488<48266: %8 %E 6;D2&*&9&9%&Je "/3/- 4G7N3F1B	+ "44T4@-- "M&"'"Z ##% "$"B"B4"HI
 #.43D3D?4 t%;TBJ4D##*;'<'J
040H0H,<$)51  $}}&7#8#FJ."+$(15  - 	 H =ENN<L /8tSs* H   %%h/&&uj9 *%%sYt !% !4>>+<+F+FGQJ778N8NO t3T:F- &&M&:"DO**,||O'" '"X  !4>>+<+F+FGQJ778N8NO t3T:F- &&M&:"DO**,s@   AO $B	O.O1B(O O)4O O O	O BQ5c	           	      B   | j                  d       |	j                  dd      }
|	rt        d|	       |
r| j                  }nt	        |||||d| j
                        }| j                  |       |j                          t        |t        j                        s(t        j                  ||dk7  |d|j                  | 	      }| j                          | j                          d| _        |j                          i }| j!                          d
| _        |j%                         5  |D ]  \  }}|j'                  |       | j"                  r| j)                  d
d
d
d
      }d| _        | j+                  |      \  }}|\  }}}|||d| _        |j/                  ||       | j                  s n d d d        | j1                          | j3                  |      }|j5                  |       d | _        |
s| j7                          |r|S | j9                  |      S # 1 sw Y   ixY w)Nr   r   FzArguments not recognized: )r   r    r"   r   r   r   ro   r   r   r_   r   r   r   r   r   Tr0   r1   r2   r   r0   r1   r2   )r   pop
ValueErrorr   r   ro   r   r   r   r   r   r   r   r   stop_evaluatingon_test_beginr   r   r   on_test_batch_beginr   r   r   on_test_batch_endr   r   on_test_endr   _flatten_metrics_in_order)r   r   r    r   r   r"   r   r   r   r4   use_cached_eval_datasetr   rF   r   rq   rQ   r0   r1   r2   s                      r   r   zJAXTrainer.evaluate  sC    	##J/"(**-G"O9&BCC"!66N .+% %$($<$<N 	n5 )%5%B%BC(55#qL$00I 	113!$!!%002 #	"0 "h--d3)) //,004*..2	 0 E .3D*"00Ae
 	'+% ,?/F):# ++D$7''E"#	L 	//5d#&**,K--d33a#	 #	s   #BH*HHc                    t        |||d| j                        }t        d | j                         D              sb|D ]M  \  }}t	        j
                  t        |            \  }}}t        j                         5   | |       d d d         n |j                          t        |t        j                        s(t        j                  ||dk7  |d|j                  |       }| j                          | j                          d| _        |j#                          d }	d| _        d }
d }|j'                         5  |D ]  \  }}|j)                  |       | j$                  r| j+                  ddd	      }d| _        | j-                  |      \  }}|\  }}||d
| _         |	||
      }
|j1                  |d|i       | j                   s n d d d        | j3                          |j5                          d | _        | j7                          t9        j:                  t<        j>                  |
      S # 1 sw Y   xY w# 1 sw Y   rxY w)NF)r   r   r   r   ro   c              3   4   K   | ]  }|j                     y wrb   built.0layers     r   	<genexpr>z%JAXTrainer.predict.<locals>.<genexpr>z       C55;;C   r   r_   r   c                 n    |t        j                  d |       }|S t        j                  | d ||        |S )Nc                     | gS rb   r   )batch_outputs    r   rg   z?JAXTrainer.predict.<locals>.append_to_outputs.<locals>.<lambda>  s    , r   c                 $    | j                  |      S rb   )rB   )ri   r   s     r   rg   z?JAXTrainer.predict.<locals>.append_to_outputs.<locals>.<lambda>  s    |1L r   )r   rh   map_structure_up_to)batch_outputsr\   s     r   append_to_outputsz-JAXTrainer.predict.<locals>.append_to_outputs  sG    ,,7! N ((!L!	 Nr   T)r0   r1   r   r0   r1   r\   ) r   ro   all_flatten_layersr   rL   rm   r   r.   r   r   r   r   r   r   r   stop_predictingon_predict_beginr   r   on_predict_batch_beginr   r   r   on_predict_batch_endr   on_predict_endr   r   r   nprd   )r   r   r   r   r   r   r   rY   rq   r   r\   r1   r   rQ   r   r0   s                   r   predictzJAXTrainer.predictm  sS   
 *!! $ 8 8
 CD,@,@,BCC- 8,EEN1a ++- G   ")%5%B%BC(55#qL$00I 	113""$$""$	 "&"&002 	"0 h006)) //,004.2 0 E
 .3D*'+'<'<UH'M$u '+ ,? 0G	# ,M7C ..ti5OP''7	< 	  "&&(''r~~wOOQ L	 	s   9	H*4BH7H7*H4	7I c                    | j                  d       |)t        d d|       t        j                  |      fd}| j	                  t         |                    | j                          | j                          | j                  ddddd      }d| _	        | j                  | |             \  }}|\  }	}
}}|	|
||d	| _        | j                          t        j                  d
 |      }|r|S | j                  |      S )Ntrain_on_batchzkArguments `sample_weight` and `class_weight` cannot be specified at the same time. Received: sample_weight=z, class_weight=c               3   .   K   t         f       y wrb   _distribute_datar"   r   r    s   r   rR   z'JAXTrainer.train_on_batch.<locals>.data       "Aq-#899   
data_batchTFr   rX   c                 ,    t        j                  |       S rb   r   arrayr   s    r   rg   z+JAXTrainer.train_on_batch.<locals>.<lambda>      BHHQK r   )r   r   r   class_weight_to_sample_weightsr   rm   r   r   r   r   r   r   r   r   rh   r   )r   r   r    r"   r   r   rR   rQ   rF   r0   r1   r3   r2   s    ```         r   r   zJAXTrainer.train_on_batch  sD    	##$45#( //<o >$$0>3  /MM<M	: 	TV5113  " ## $$( $""' $ 
 "'))%8e 	
# $7'>#6!2	
 	 !!"7>K--d33r   c                    | j                  d       fd}| j                  t         |                    | j                          | j	                          | j                  dddd      }d| _        | j                  | |             \  }}|\  }}	}
||	|
d| _        | j                          t        j                  d |      }|r|S | j                  |      S )	Ntest_on_batchc               3   .   K   t         f       y wrb   r  r  s   r   rR   z&JAXTrainer.test_on_batch.<locals>.data  r  r  r  TFr   r   c                 ,    t        j                  |       S rb   r	  r  s    r   rg   z*JAXTrainer.test_on_batch.<locals>.<lambda>-  r  r   )r   r   rm   r   r   r   r   r   r   r   r   rh   r   )r   r   r    r"   r   rR   rQ   rF   r0   r1   r2   s    ```       r   r  zJAXTrainer.test_on_batch  s     	##O4	: 	TV5113! ## $$(""'	 $ 
 "'((7e KPG46G#6'>!2

 	 !!"7>K--d33r   c                    t        d | j                         D              s%t        j                         5   |        d d d        | j	                          | j                          | j                  dddd      }d| _        fd}| j                  | |             \  }}|\  }}||d| _	        | j                          t        j                  d |      }|S # 1 sw Y   xY w)Nc              3   4   K   | ]  }|j                     y wrb   r   r   s     r   r   z.JAXTrainer.predict_on_batch.<locals>.<genexpr>3  r   r   TFr   c               3      K    f y wrb   r   r  s   r   rR   z)JAXTrainer.predict_on_batch.<locals>.dataB  s     $Js   
r   c                 ,    t        j                  |       S rb   r	  r  s    r   rg   z-JAXTrainer.predict_on_batch.<locals>.<lambda>L  s    RXXa[ r   )r   r   r   r.   r   r   r   r   r   r   r   r   rh   )r   r   rQ   rR   r   r0   r1   s    `     r   predict_on_batchzJAXTrainer.predict_on_batch2  s    CD,@,@,BCC'') Q113""$## $$(#"'	 $ 
 "'	  $44UDFCu7<44#6'>
 	**+@-P1 s   	CC#c                    t        | dd       r| j                  ry | j                  j                  dd       }| j                  j                  dd       }| j                  j                  dd       }| j                  j                  dd       }|r/t	        | j
                  |      D ]  \  }}|j                  |        |r/t	        | j                  |      D ]  \  }}|j                  |        |r9t	        | j                  j                  |      D ]  \  }}|j                  |        |r/t	        | j                  |      D ]  \  }}|j                  |        d| _        y )Nr   r0   r1   r3   r2   T)r   r   r   getr,   r0   assignr1   r*   r-   r2   )r   r0   r1   r3   r2   rC   rD   s          r   r   zJAXTrainer.jax_state_syncO  sL   t\40D4J4J"oo112GN"&//"5"5%t#
 #oo112GN OO//0CTJ 8 8:MN  qQ ",,.E  q Q   8 8:MN  qQ  6 68IJ  qQ !%r   c                    | j                   D cg c]  }|j                  j                   c}| _        | j                  D cg c]  }|j                  j                   c}| _        t        | d      rJ| j                  >| j                  j                  D cg c]  }|j                  j                   c}| _	        ng | _	        | j                  D cg c]  }|j                  j                   c}| _        y c c}w c c}w c c}w c c}w )Nr*   )r0   rA   sharding_trainable_variable_shardingsr1   !_non_trainable_variable_shardingshasattrr*   r-   _optimizer_variable_shardingsr2   _metrics_variable_shardings)r   rD   s     r   r   z/JAXTrainer._record_training_state_sharding_speci  s    &*&>&>.
!"AGG.
* '+&B&B2
!"AGG2
. 4%$..*D*...*B*B2%&  2D. 24D.&*&<&<,
!"AGG,
(.
2
2
,
s   C8C=DDc                 <    d | _         d | _        d | _        d | _        y rb   )r  r  r  r   r   s    r   r   z$JAXTrainer._clear_jax_state_shardingz  s"    -1*15.-1*+/(r   c                    |xs g }|xs g }|xs g }|xs g }t        t        |            D ]5  }t        j                  j	                  ||   | j
                  |         ||<   7 t        t        |            D ]5  }t        j                  j	                  ||   | j                  |         ||<   7 t        t        |            D ]5  }t        j                  j	                  ||   | j                  |         ||<   7 t        t        |            D ]5  }t        j                  j	                  ||   | j                  |         ||<   7 ||||fS )a  Enforce the sharding spec constraint for all the training state.

        Since the output of the train/eval step will be used as inputs to next
        step, we need to ensure that they have the same sharding spec, so that
        jax.jit won't have to recompile the train/eval function.

        Note that this function will also rely on the recorded sharding spec
        for each of states.

        This function is expected to be called within the jitted train/eval
        function, especially around the end of the function.
        )	rn   lenrM   laxwith_sharding_constraintr  r  r  r   )r   r0   r1   r3   r2   is         r   rP   z&JAXTrainer._enforce_jax_state_sharding  ss   & 27R"9"?R17R-3s./0 	A%(WW%E%E#A&(J(J1(M&"	 s234 	A),)I)I'*66q9*#A&	
 s./0 	A%(WW%E%E#A&(J(J1(M&"	 s,-. 	A#&77#C#C!!$d&F&Fq&I$a 	
  #	
 	
r   c                     |r| j                   D ]	  }d|_         |r| j                  D ]	  }d|_         |r"| j                  j                  D ]	  }d|_         |r| j
                  D ]	  }d|_         yy)a  Remove all the model variable for memory saving.

        During JAX training, since the training function is stateless, we have
        to pass in and get the model weights over and over, during which the
        copy of the weights that attached to the Variable are still and
        occupying extra memory. We remove those variable to save memory (for
        better memory utilization) at the beginning of the epoch, and reattach
        the value back to variables at the end of the epoch, via
        `jax_state_sync()`.
        N)r0   _valuer1   r*   r-   r2   )r   r0   r1   r3   r2   rD   s         r   _purge_model_variablesz!JAXTrainer._purge_model_variables  s    " --   "11   ^^--   ++    r   c                 .   g }|r3|j                  | j                  D cg c]  }|j                   c}       |r3|j                  | j                  D cg c]  }|j                   c}       |r=|j                  | j                  j
                  D cg c]  }|j                   c}       |r3|j                  | j                  D cg c]  }|j                   c}       |r| j                  ||||       t        |      S c c}w c c}w c c}w c c}w )NrX   )	rB   r0   rA   r1   r*   r-   r2   r*  tuple)r   r0   r1   r3   r2   r   rQ   rD   s           r   r   zJAXTrainer._get_jax_state  s     LL4+C+CDa!''DE"LL4+G+GHa!''HILL4>>+C+CDa!''DELL4+A+ABa!''BC ''$7(?$7"3	 (  U| EHDBs   DDDD)FN)F)NNNr_   autoNg        NTNNr   NNNr_   )NNNr-  NNNF)Nr-  NN)NNNF)NNF)NNNN)FFFF)FFFFF)__name__
__module____qualname__r   r9   rI   rV   rZ   r]   r{   r   r   r   r   filter_tracebackr   r   r   r   r  r  r   r   r   rP   r*  r   __classcell__)r   s   @r   r   r      s`   &  9
v+,*X(T0.1f, + .* %% 
"#{ &{z %% 
g4 &g4R %%HL[P &[P@ ;4@ (4T:&4
"0 ! $ .
d " %! @ " %!#r   r   c                 &   t        j                         W|t        j                  fd|       }t	        t
        j                  j                        }t        j                  || |      S t        j                  t        j                  |       S )Nc                 :    j                  | j                        S rb   )get_data_layoutr>   ddistributions    r   rg   z"_distribute_data.<locals>.<lambda>  s    ,66qww? r   )batch_dim_name)
r	   r8  r   rh   r   jax_distribution_libdistribute_data_inputr9  rM   
device_put)rR   layoutsjax_dist_data_inputr8  s      @r   r  r    s    #002L?((?G & 66'66
 !!"5tWEEcnnd33r   c                   $    e Zd Zd Zd Zd Zd Zy)r   c                 ,    t        | j                        S rb   )rm   _epoch_iteratorr"  s    r   __next__zJAXEpochIterator.__next__  s    D(())r   c                     t        j                         }|| j                  |      S | j                  | j                  j                               S rb   )r	   r8  _get_distributed_iterator_prefetch_numpy_iteratordata_adapterget_jax_iterator)r   r8  s     r   _get_iteratorzJAXEpochIterator._get_iterator  sL    '446#11,??,,..0
 	
r   c              #      K   d}| j                   j                         D ]+  }|t        j                  fd|      }t	        ||       - yw)zALazily compute layouts to reduce host to device transfer latency.Nc                 N    j                  | j                        j                  S rb   )r5  r>   backend_layoutr6  s    r   rg   z<JAXEpochIterator._get_distributed_iterator.<locals>.<lambda>  s!    l::$n r   )rF  rG  r   rh   r  )r   r8  r=  rR   s    `  r   rD  z*JAXEpochIterator._get_distributed_iterator  sX     %%668 	2D,,% 	 #411	2s   AAc              #      K   t        j                         dfd	} |d       rj                           |d       ryyw)a  Shard and prefetch batches on device.

        Most of the implementation has been borrowed from
        `flax.jax_utils.prefetch_to_device`

        This utility takes an iterator and returns a new iterator which fills an
        on device prefetch buffer. Eager prefetching can improve the performance
        of training loops significantly by overlapping compute and data
        transfer.
           c                 p    t        j                  |       D ]  }j                  t        |              y rb   )	itertoolsislicerB   r  )nrR   numpy_iteratorqueues     r   enqueuez:JAXEpochIterator._prefetch_numpy_iterator.<locals>.enqueue%  s1    !((; 5-d345r   )rQ  r_   N)rM  )collectionsdequepopleft)r   rR  rT  rS  s    ` @r   rE  z)JAXEpochIterator._prefetch_numpy_iterator  s@      !!#
	5 	!--/!AJ s   AA
A
N)r.  r/  r0  rB  rH  rD  rE  r   r   r   r   r     s    *
2r   r   rb   )"rU  rO  r   	functoolsr   rM   rc   r   	keras.srcr   r   r   r   r   r   keras.src.backendr   r	   r:  keras.src.distributionkeras.src.trainersr
   base_trainer keras.src.trainers.data_adaptersr   r   !keras.src.trainers.epoch_iteratorr   keras.src.utilsr   Trainerr   r  r   r   r   r   <module>rb     sa        
   3 5  $ F 3 6 : ? ; +O%% Od4$1} 1r   