o
    i e                     @   sl   d Z ddlZddlZddlm  mZ dd Zdd Z				dd	d
Z	dddZ
dd ZG dd dZdS )zUtils for running models in a distribution setting.

Mostly from
https://github.com/tensorflow/models/blob/master/official/utils/misc/distribution_utils.py.
    Nc                 C   sB   t jjjjt jjjjt jjjjd}| |vrtd| ||  S )aK  Return a CollectiveCommunication based on all_reduce_alg.

    Args:
      all_reduce_alg: a string specifying which collective communication to
        pick, or None.

    Returns:
      tf.distribute.experimental.CollectiveCommunication object

    Raises:
      ValueError: if `all_reduce_alg` not in [None, "ring", "nccl"]
    )NringncclzqWhen used with `multi_worker_mirrored`, valid values for all_reduce_alg are [`ring`, `nccl`].  Supplied value: {})	tf
distributeexperimentalCollectiveCommunicationAUTORINGNCCL
ValueErrorformat)all_reduce_alg collective_communication_options r   U/var/www/myenv/lib/python3.10/site-packages/keras/src/benchmarks/distribution_util.py_collective_communication   s   


r   c                 C   sF   | du rdS t jjt jjd}| |vrtd| ||  }||dS )a  Return a CrossDeviceOps based on all_reduce_alg and num_packs.

    Args:
      all_reduce_alg: a string specifying which cross device op to pick, or
        None.
      num_packs: an integer specifying number of packs for the cross device op.

    Returns:
      tf.distribute.CrossDeviceOps object or None.

    Raises:
      ValueError: if `all_reduce_alg` not in [None, "nccl",
        "hierarchical_copy"].
    N)r   hierarchical_copyzqWhen used with `mirrored`, valid values for all_reduce_alg are [`nccl`, `hierarchical_copy`].  Supplied value: {})	num_packs)r   r   NcclAllReduceHierarchicalCopyAllReducer   r   )r   r   mirrored_all_reduce_optionscross_device_ops_classr   r   r   _mirrored_cross_device_ops7   s   
r   mirrored   c                 C   s   |dk rt d|  } | dkr|dkrt d|dS | dkr+tjjjt|dS | d	krG|dkr9tjd
S |dkrAt dtjdS | dkrg|dkrSd
g}n	dd t	|D }tjj
|t||dS t d|  )aK  Return a DistributionStrategy for running the model.

    Args:
      distribution_strategy: a string specifying which distribution strategy to
        use. Accepted values are "off", "one_device", "mirrored", and
        "multi_worker_mirrored" -- case insensitive. "off" means not to use
        Distribution Strategy.
      num_gpus: Number of GPUs to run this model.

    Returns:
      tf.distribute.DistibutionStrategy object.
    Raises:
      ValueError: if `distribution_strategy` is "off" or "one_device" and
        `num_gpus` is larger than 1; or `num_gpus` is negative.
    r   z`num_gpus` can not be negative.offr   zNWhen {} GPUs are specified, distribution_strategy flag cannot be set to `off`.Nmulti_worker_mirrored)communication
one_devicezdevice:CPU:0z=`OneDeviceStrategy` can not be used for more than one device.zdevice:GPU:0r   c                 S   s   g | ]}d | qS )zdevice:GPU:%dr   ).0ir   r   r   
<listcomp>   s    z-get_distribution_strategy.<locals>.<listcomp>)devicescross_device_opsz$Unrecognized Distribution Strategy: )r   lowerr   r   r   r   MultiWorkerMirroredStrategyr   OneDeviceStrategyrangeMirroredStrategyr   )distribution_strategynum_gpusr   r   r"   r   r   r   get_distribution_strategyW   sF   r+   c                 C   s   t tjdd}|r"t|d dg t|d dg  }|S | rS| d}t|}|dkr9|dk r9td	|dkr?dn|}t d|id|d
dtjd< |S d}|S )zSet multi-worker cluster spec in TF_CONFIG environment variable.

    Args:
      worker_hosts: comma-separated list of worker ip:port pairs.

    Returns:
      Number of workers in the cluster.
    	TF_CONFIGz{}clusterchiefworker,r   r   z2Must specify task_index when number of workers > 1)typeindex)r.   task)	jsonloadsosenvirongetlensplitr   dumps)worker_hosts
task_index	tf_confignum_workersworkersr   r   r   configure_cluster   s,   	

rB   c                 C   s   | r|   }|S t }|S N)scopeDummyContextManager)strategystrategy_scoper   r   r   get_strategy_scope   s
   rH   c                   @   s   e Zd Zdd Zdd ZdS )rE   c                 C      d S rC   r   )selfr   r   r   	__enter__      zDummyContextManager.__enter__c                 G   rI   rC   r   )rJ   argsr   r   r   __exit__   rL   zDummyContextManager.__exit__N)__name__
__module____qualname__rK   rN   r   r   r   r   rE      s    rE   )r   r   Nr   )Nr,   )__doc__r5   r7   tensorflow.compat.v2compatv2r   r   r   r+   rB   rH   rE   r   r   r   r   <module>   s   !

A!	