
    ijE8                         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Z eej                   d      sd	 ej                   _        d
 Z ed       G d de	             Zy# e$ r Y !w xY w)    N)backend)tree)keras_export)MonitorCallback)
saving_lib)ocprecord_scalarc                       y N )argskwargss     y/var/www/html/emotional.easysim.app/public_html/venv/lib/python3.12/site-packages/keras/src/callbacks/orbax_checkpoint.py<lambda>r      s        c                     t        j                          dk(  r| j                         }d}n| j                  d      }d}|rd }t        j                  ||      S |S )z8Get the complete model state as a nested tree structure.jaxFnumpy_array)value_formatTc                     t        | t        j                        r| j                  dk(  r| j	                         S t        | t        j
                        r| j	                         S | S )Nr   )
isinstancenpndarrayndimitemgeneric)objs    r   convert_scalarsz(_get_state_tree.<locals>.convert_scalars*   sE    #rzz*sxx1}xxz!C,xxz!
r   )r   get_state_treer   map_structure)model
state_treedid_numpy_conversionr   s       r   _get_state_treer$      se     E!))+
$))})E
# 	 !!/:>>r   zkeras.callbacks.OrbaxCheckpointc                        e Zd ZdZ	 	 	 	 	 	 	 	 	 d fd	Z fdZd ZddZd Zd Z	d Z
dd	Zdd
ZddZddZd Z xZS )OrbaxCheckpointa`  Callback to save and load model state using Orbax with a similar API to
    ModelCheckpoint.

    This callback saves the model's weights and optimizer state asynchronously
    using Orbax, allowing training to continue without blocking for I/O.

    **Multi-host Support**: When running in a multi-host distributed training
    environment with JAX backend, this callback automatically coordinates
    checkpointing across all hosts to ensure consistency and proper
    synchronization. Multi-host checkpointing is only supported on JAX.

    Example:

    ```python
    model.compile(loss=..., optimizer=..., metrics=['accuracy'])

    EPOCHS = 10
    checkpoint_dir = '/tmp/ckpt'
    orbax_checkpoint_callback = keras.callbacks.OrbaxCheckpoint(
        directory=checkpoint_dir,
        monitor='val_accuracy',
        mode='max',
        save_best_only=True)

    # Model is saved at the end of every epoch, if it's the best seen so far.
    model.fit(epochs=EPOCHS, callbacks=[orbax_checkpoint_callback])

    # Alternatively, save checkpoints every N batches -
    orbax_checkpoint_callback = keras.callbacks.OrbaxCheckpoint(
        directory=checkpoint_dir,
        save_freq=100)  # Save every 100 batches

    model.fit(epochs=EPOCHS, callbacks=[orbax_checkpoint_callback])
    ```

    Args:
        directory: path to the directory where to save the checkpoints.
        monitor: The metric name to monitor (e.g., 'val_loss').
        verbose: Verbosity mode, 0 or 1.
        save_best_only: if `save_best_only=True`, it only saves when the model
            is considered the "best" based on the monitored quantity.
        mode: one of {'auto', 'min', 'max'}. Used with `save_best_only`.
        save_freq: `'epoch'` or integer. Frequency to save checkpoints.
        max_to_keep: Integer, maximum number of recent checkpoints to keep.
            If None, keeps all. Defaults to 1.
        save_on_background: Boolean, whether to save asynchronously in the
            background. Defaults to True.
        initial_value_threshold: Floating point initial "best" value for the
            monitor, used with `save_best_only`.
    c                 .   t        j                          t        |   |||       || _        || _        || _        || _        || _        |	| _	        |
| _
        d| _        d | _        d| _        g | _        | j                         | _        | j                  dk7  r3t#        | j                  t$              st'        d| j                   d      g }|8|j)                  t         j*                  j,                  j/                  |             d }|r=t1        |      dk(  r|d   }n)t         j*                  j,                  j3                  |      }t         j*                  j5                  ||t         j*                  j6                  j9                  d            | _        y )Nr   epochzUnrecognized save_freq: z2. Expected save_freq are 'epoch' or integer values   )	directorypreservation_policysave_decision_policy)r   
initializesuper__init__r*   verbosesave_best_only	save_freqmax_to_keepsave_on_backgroundsave_weights_only_batches_seen_since_last_saving_last_batch_seen_total_batches_seen_async_futures_is_multihost_initialized_multihost_initializedr   int
ValueErrorappendtrainingpreservation_policiesLatestNlenAnyPreservationPolicyCheckpointersave_decision_policiesFixedIntervalPolicycheckpointer)selfr*   monitorr0   r1   moder2   initial_value_thresholdr3   r4   r5   policiesr+   	__class__s                r   r/   zOrbaxCheckpoint.__init__n   s|    	 	$(?@","&"4!2/0, $#$   '+&D&D&F#>>W$Z-L*4>>*: ;C C  "OO22::;G #8}!&.qk# LL66LL  $  LL55 3!$!D!D!X!X" 6 
r   c                     t         |   |       t        |d      r2|j                  %t	        |j                  j
                        | _        y y y )N	optimizer)r.   	set_modelhasattrrO   r<   
iterationsr8   )rH   r!   rM   s     r   rP   zOrbaxCheckpoint.set_model   sC    % 5+&5??+F'*5??+E+E'FD$ ,G&r   c                 r    t        j                          dk7  ryt        j                  }|j                         S )z/Check if multi-host environment is initialized.r   F)r   r   	multihost%is_jax_distributed_client_initializedrH   rT   s     r   r:   z)OrbaxCheckpoint._is_multihost_initialized   s0     ??%MM	 >>@@r   c                 l    | j                   syt        j                  }|xs d}|j                  |       y)z'Synchronize all processes across hosts.Norbax_checkpoint_sync)r;   r   rT   sync_global_processes)rH   keyrT   sync_keys       r   _sync_processeszOrbaxCheckpoint._sync_processes   s0    **MM	11''1r   c                     | j                   S )ak  Return True if multi-host checkpointing is enabled and initialized.

        This method can be used to check if the callback is operating in
        a multi-host distributed training environment. Multi-host checkpointing
        is only supported on JAX backend.

        Returns:
            bool: True if multi-host support is active, False otherwise.
        )r;   )rH   s    r   is_multihost_enabledz$OrbaxCheckpoint.is_multihost_enabled   s     ***r   c                 `    | j                   syt        j                  }|j                  d      S )a  Return True if this process is the primary host in multi-host setup.

        In multi-host environments, only the primary host typically handles
        logging and coordination tasks. Multi-host checkpointing is only
        supported on JAX backend.

        Returns:
            bool: True if this is the primary host, False otherwise.
            Always returns True in single-host environments.
        Tr   )primary_host)r;   r   rT   is_primary_hostrV   s     r   ra   zOrbaxCheckpoint.is_primary_host   s-     **MM	((a(88r   c                 (   | j                   dk(  ry| j                  || j                  k  r|dz   }n|| j                  z
  }| xj                  |z  c_        || _        | xj                  |z  c_        | j                  | j                   k\  rd| _        yy)z&Check if we should save on this batch.r(   Fr)   r   T)r2   r7   r6   r8   )rH   batchadd_batchess      r   _should_save_on_batchz%OrbaxCheckpoint._should_save_on_batch   s    >>W$  (ET5J5J,J!)K$"7"77K,,;, %  K/ //4>>A34D0r   c                 8   t        | j                        }| j                  r|d   |d   d}n|}d|i}| j                  sOt        j                  | j                        \  }}d|i|d<   t        j
                  | j                        }|||d<   t        j                         5  | j                   }	|	r| j                  j                  ||       n7| j                  j                  ||      }
| j                  j                  |
       ddd       y# 1 sw Y   yxY w)	zASave a checkpoint at the given step with multi-host coordination.trainable_variablesnon_trainable_variables)rg   rh   pytreeconfigmodel_configNassets)r$   r!   r5   r   _serialize_model_as_json_save_assets_to_dictr   Contextr4   rG   save_checkpointablessave_checkpointables_asyncr9   r>   )rH   steplogsr"   composite_statepayloadconfig_json_assets_dictuse_syncfutures              r   _save_checkpointz OrbaxCheckpoint._save_checkpoint   s    %TZZ0
 !!'12G'H+5-,O )O _-%%'@@LNK'/&=GN#$99$**EK&$/! [[] 	3222H !!66tWE**EE' ##**62	3 	3 	3s   #A$DDc                 l   | j                  |      rd}| j                  rr|r|j                  | j                        nd }|+t	        j
                  d| j                   d| dd       d}n&| j                  || j                        sd}n|| _        |r | j                  }| j                  ||       y y y )	NTCan save best model only with z# available, skipping save at batch .   
stacklevelFrr   rs   )
re   r1   getrI   warningswarn_is_improvementbestr8   r{   )rH   rc   rs   should_savecurrentrr   s         r   on_train_batch_endz"OrbaxCheckpoint.on_train_batch_end-  s    %%e,K""48$((4<<0d?MM8 G==BG1F#$
 #(K--gtyyA"'K !(DI//%%4d%; % -r   c                    | j                   | j                          | j                  dk(  }|r~| j                  rr|r|j	                  | j
                        nd }|+t        j                  d| j
                   d| dd       d}n&| j                  || j                        sd}n|| _	        |r| j                  ||       y y )	Nr(   r}   z# available, skipping save at epoch r~   r   r   Fr   )
monitor_op_set_monitor_opr2   r1   r   rI   r   r   r   r   r{   )rH   r(   rs   r   r   s        r   on_epoch_endzOrbaxCheckpoint.on_epoch_endE  s    ??"  " nn/ 4..04dhht||,$G4T\\N C..3WA7 
 $))'499=# $	!!u4!8 r   c                 z    	 | j                   j                          | j                  d       y # t        $ r Y w xY w)Ncheckpoint_cleanup)rG   close	Exceptionr\   )rH   rs   s     r   on_train_endzOrbaxCheckpoint.on_train_end`  s>    	##%
 	12	  		s   . 	::c                     | j                   D ]  }|j                           | j                   j                          | j                  j	                          | j                  d       y)zWait for any in-progress checkpoint operations to complete.
        This method blocks until all asynchronous checkpoint save operations
        have completed across all hosts in a multi-host setup.
        checkpoint_wait_completeN)r9   resultclearrG   waitr\   )rH   rz   s     r   wait_until_finishedz#OrbaxCheckpoint.wait_until_finishedk  sY     )) 	FMMO	!!# 	  	78r   )	val_lossr   Fautor(   Nr)   TFr   )__name__
__module____qualname____doc__r/   rP   r:   r\   r^   ra   re   r{   r   r   r   r   __classcell__)rM   s   @r   r&   r&   9   sg    1l  $G
RG	A2
+9 &+3Z<096	39r   r&   )r   numpyr   	keras.srcr   r   keras.src.api_exportr   $keras.src.callbacks.monitor_callbackr   keras.src.savingr   keras.src.utils.module_utilsr   r   rQ   
monitoringr	   ImportErrorr$   r&   r   r   r   <module>r      s        - ( ,	3>>?3'C$
< /09o 9 19G  		s   )A1 1A98A9