o
    8wiA                     @   s  d dl Z d dlmZmZmZmZ d dlmZ d dlm	Z	m
Z
mZ d dlZd dlmZ d dlmZ d dlmZmZmZmZmZmZ d dlmZ d dlZd d	lmZmZmZ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)m*Z* eee+ee	df ed f Z,e) Z-de,dee
e. ddf fddZ/de,de.fddZ0	d'de1ddde2dee fddZ3	d(dedeeef de
e% defdd Z4	d(dedeeef de
e% de5e5e	 e6e+e	f f fd!d"Z7	d(dedeeef de
e% de6e+e	f fd#d$Z8de1de2fd%d&Z9dS ))    N)	GeneratorIterableMappingSized)fields)AnyOptionalUnion)is_dataclass_instance)Tensor)BatchSampler
DataLoaderIterableDatasetRandomSamplerSamplerSequentialSampler)	TypeGuard)_reinstantiate_wrapped_cls_replace_value_in_saved_argshas_iterable_dataset	sized_len)PossibleUserWarning)_IndexBatchSamplerWrapper)RunningStage)MisconfigurationException)WarningCacherank_zero_warnBTypebatchreturnc                 c   s    t | tr| jdkrdV  d S | dV  d S t | ttfr;t | ts;t | tr-|  } | D ]	}t|E d H  q/d S t	| rSt
| D ]}tt| |jE d H  qCd S d V  d S )Nr      )
isinstancer   ndimsizer   r   strvalues_extract_batch_sizer
   r   getattrname)r   samplefield r+   ]/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/pytorch_lightning/utilities/data.pyr&   +   s    




r&   c                 C   sr   d}d}zt | D ]}|du r|}q	||kr!td| d  nq	W n ty.   t|w |du r7t||S )zUnpack a batch to find a ``torch.Tensor``.

    Returns:
        ``len(tensor)`` when found, or ``1`` when it hits an empty or non iterable.

    zWe could not infer the batch_size from the batch. Either simplify its structure or provide the batch_size as `self.log(..., batch_size=batch_size)`.NzZTrying to infer the `batch_size` from an ambiguous collection. The batch size we found is zK. To avoid any miscalculations, use `self.log(..., batch_size=batch_size)`.)r&   warning_cachewarnRecursionErrorr   )r   	error_msg
batch_sizebsr+   r+   r,   extract_batch_size>   s,   r3   F
dataloaderstrategyzpl.strategies.Strategy2allow_zero_length_dataloader_with_multiple_devicesc                 C   s   t | }|du r
dS |jtj||jddd}|dkr&tdt| j d |dkrE|dkrEt| j}|s=td	| d
td| d t	| rMtd dS )zIChecks if a given object has ``__len__`` method implemented on all ranks.NF)devicesum)	reduce_opr   zTotal length of `zA` across ranks is zero. Please make sure this was your intention.`zW` within local rank has zero length. Please make sure that it returns at least 1 batch.zb` across ranks is zero, but local rank has zero length. Please be cautious of uneven batch length.zYour `IterableDataset` has `__len__` defined. In combination with multi-process data loading (when num_workers > 1), `__len__` could be inaccurate if each worker is not configured independently to avoid having duplicate data.T)
r   reducetorchtensorroot_devicer   type__name__RuntimeErrorr   )r4   r5   r6   local_lengthtotal_lengthdataloader_cls_namer+   r+   r,   has_len_all_ranks]   s,   


rE   samplermodec                 C   s&   t | ||\}}t| g|R i |S N)$_get_dataloader_init_args_and_kwargsr   )r4   rF   rG   dl_args	dl_kwargsr+   r+   r,   _update_dataloader   s   rL   c              
      s  t | tstd|  dt| d}|r!| j}| j| j | j}ndd t| 	 D d }| j
d< d tt| jj}tdd	 | D }|ro|r_|d
d ttjj	 D  n|ttjj |dd  |sfdd|	 D d fdd	 D d}d|}t |trd d< d d< n	t| ||  fdd| D }	|	rt|	}
| jj}ddd	 |
D }td| d|
 d| d| d	|stt B |  }|rt|}| jj}td| d| d| d|fS )NzThe dataloader z0 needs to subclass `torch.utils.data.DataLoader`__pl_saved_argsc                 S   s    i | ]\}}| d s||qS )_)
startswith.0kvr+   r+   r,   
<dictcomp>   s     z8_get_dataloader_init_args_and_kwargs.<locals>.<dictcomp>multiprocessing_contextr+   c                 s   s    | ]	}|j |ju V  qd S rH   )kindVAR_KEYWORDrQ   pr+   r+   r,   	<genexpr>       z7_get_dataloader_init_args_and_kwargs.<locals>.<genexpr>c                 S   s"   i | ]\}}|j |jur||qS r+   )defaultemptyrP   r+   r+   r,   rT      s    selfc                    s*   h | ]\}}| v r|j  | ur|qS r+   )r\   )rQ   r(   rY   )attrsr+   r,   	<setcomp>   s   * z7_get_dataloader_init_args_and_kwargs.<locals>.<setcomp>datasetc                    s   i | ]\}}| v r||qS r+   r+   rP   )non_defaultsr+   r,   rT      s    batch_samplerrF   c                    sD   h | ]}|j |j|jfv r |j|ju r |jvr |j vr|jqS r+   )rV   POSITIONAL_ONLYPOSITIONAL_OR_KEYWORDr\   r]   r(   rX   )	arg_namesrK   r+   r,   r`      s    

z, c                 s   s    | ]	}d | dV  qdS )z`self.r:   Nr+   )rQ   arg_namer+   r+   r,   rZ      r[   z,Trying to inject custom `Sampler` into the `z` instance. This would fail as some of the `__init__` arguments are not available as instance attributes. The missing attributes are z. If you instantiate your `zZ` inside a `*_dataloader` hook of your module, we will do this for you. Otherwise, define z inside your `__init__`.z&Trying to inject parameters into the `z{` instance. This would fail as it doesn't expose all its attributes in the `__init__` signature. The missing arguments are z. HINT: If you wrote the `zA` class, add the `__init__` arguments or allow passing `**kwargs`)r!   r   
ValueErrorhasattrrM   __pl_saved_kwargs__pl_saved_arg_names	__datasetvarsitemsrU   dictinspect	signature__init__
parametersanyr%   updatepopaddgetr   '_dataloader_init_kwargs_resolve_samplersorted	__class__r@   joinr   setkeys)r4   rF   rG   was_wrappedrJ   original_datasetparamshas_variadic_kwargsra   required_argssorted_required_argsrD   missing_args_messagemissing_kwargssorted_missing_kwargsr+   )rf   r_   rK   rb   r,   rI      sx   







	rI   c              
   C   s  |t jk}t| d}t|}|dur|tus|rt|dre|j}|j}|j}|j	}	|rBt
dd||||	\}
}}|
sBtd|j d t
d|||||	\}
}}|
sYtd	|j d
t|g|R i |}nLt|drt|drz|||j|rxdn|jd}W n2 ty } zddl}|dt|}|s td|d}~ww |rtd|j dtd ntd|rt|}dd|dddS |dddS )a.  This function is used to handle the sampler, batch_sampler arguments associated within a DataLoader for its re-
    instantiation.

    If the dataloader is being used for prediction, the sampler will be wrapped into an `_IndexBatchSamplerWrapper`, so
    Lightning can keep track of its indices.

    rc   NrM   	drop_lastFzlTrying to inject `drop_last=False` into batch sampler since you are predicting, however it seems the class `z` does not support it. Your predictions might be incomplete. To mitigate this, expose `drop_last` in the `__init__` method of your custom class.rF   zYTrying to inject a modified sampler into the batch sampler; however, it seems the class `z` does not have an argument called `sampler.` To mitigate this, expose an argument `sampler` in the `__init__` method of your custom class.r1   )r1   r   r   z:.*__init__\(\) (got multiple values)|(missing \d required)a   Lightning can't inject a (distributed) sampler into your batch sampler, because it doesn't subclass PyTorch's `BatchSampler`. To mitigate this, either follow the API of `BatchSampler` and instantiate your custom batch sampler inside the `*_dataloader` hook of your module, or set `Trainer(use_distributed_sampler=False)`. If you choose the latter, you will be responsible for handling the distributed sampling within your batch sampler.z&You are using a custom batch sampler `z` for prediction. Lightning would normally set `drop_last=False` to ensure all samples are returned, but for custom samplers it can't guarantee this. Make sure your sampler is configured correctly to return all indices.)categorya\   Lightning can't inject a (distributed) sampler into your batch sampler, because it doesn't subclass PyTorch's `BatchSampler`. To mitigate this, either follow the API of `BatchSampler` or set `Trainer(use_distributed_sampler=False)`. If you choose the latter, you will be responsible for handling the distributed sampling within your batch sampler.r    )rF   shufflerc   r1   r   )rF   r   rc   )r   
PREDICTINGr'   r?   r   ri   rM   rj   __pl_saved_default_kwargsrk   r   r   __qualname__	TypeErrorr   r1   r   rematchr$   r   r   )r4   rF   rG   is_predictingrc   batch_sampler_clsargskwargsdefault_kwargsrf   successexr   r   r+   r+   r,   ry      s   






ry   c                 C   s   t | drd| jv r| jd S d| jv r| j| jd S t | dr*t| jtr*dS t | ds1dS | j}|d urCt |dr@|j	n|}n| j	}t|t
rMdS t|tS )Nrj   r   ra   FrF   )ri   rj   rk   rM   indexr!   ra   r   rc   rF   r   r   )r4   rc   rF   r+   r+   r,   _is_dataloader_shuffledS  s    






r   )FrH   ):rp   collections.abcr   r   r   r   dataclassesr   typingr   r   r	   r<   #lightning_utilities.core.apply_funcr
   r   torch.utils.datar   r   r   r   r   r   typing_extensionsr   pytorch_lightningpllightning_fabric.utilities.datar   r   r   r   #lightning_fabric.utilities.warningsr   'pytorch_lightning.overrides.distributedr    pytorch_lightning.trainer.statesr   &pytorch_lightning.utilities.exceptionsr   %pytorch_lightning.utilities.rank_zeror   r   r$   r   r-   intr&   r3   objectboolrE   rL   tuplero   rI   ry   r   r+   r+   r+   r,   <module>   sz     "
(




a


j