code: def __iter__(self):
      worker_id, num_workers = 0, 1
      worker_info = torch.utils.data.get_worker_info()
      if worker_info is not None:
          worker_id, num_workers = (
              worker_info.id,
              worker_info.num_workers,
          )
  
      self.consumed_urls = (
          self.consumed_samples
          // (self.data_parallel_size * num_workers)
          // self.chunk_size
          * (self.data_parallel_size * num_workers)
      )
  
      if self.drop_last or self.remaining_urls == 0:
          active_total_urls = self.total_urls - self.remaining_urls
      else:
          active_total_urls = (
              self.total_urls
              + self.data_parallel_size
              - self.remaining_urls
          )
  
      self.epoch.set_value(self.consumed_urls // active_total_urls)
      current_epoch_urls = self.consumed_urls % active_total_urls
  
      # data sharding and random sampling
      if self.data_sharding:
          bucket_size = active_total_urls // self.data_parallel_size
          bucket_offset = current_epoch_urls // self.data_parallel_size
          start_idx = self.data_parallel_rank * bucket_size
  
          g = torch.Generator()
          g.manual_seed(self.epoch.get_value())
          random_idx = torch.randperm(bucket_size, generator=g).tolist()
          idx_range = [
              start_idx + x for x in random_idx[bucket_offset:]
          ]
      else:
          full_bucket_size = active_total_urls
          full_bucket_offset = current_epoch_urls
          g = torch.Generator()
          g.manual_seed(self.epoch.get_value())
          idx_range_total = torch.randperm(
              full_bucket_size, generator=g
          ).tolist()
          idx_range_active = idx_range_total[full_bucket_offset:]
          idx_range = idx_range_active[
              self.data_parallel_rank :: self.data_parallel_size
          ]
  
      # Use additional permutation to replace out-of-range indices when drop_last is False
      additional_random_idx = torch.randperm(
          self.total_urls, generator=g
      ).tolist()
      for n, idx in enumerate(idx_range):
          self.consumed_samples += (
              self.data_parallel_size * self.chunk_size
          )
          if worker_info is not None and n % num_workers != worker_id:
              continue
          if idx < self.total_urls:
              yield dict(url=self.urls[idx])
          else:
              yield dict(
                  url=self.urls[
                      additional_random_idx[idx - self.total_urls]
                  ]
              )
  
file_path: NeMo/nemo/collections/multimodal/data/common/data_samplers.py
imports: from multiprocessing import Value
  import torch
  from nemo.utils import logging
label_desc: Use image node_id 3 for calling the WDSUrlsRandomSampler obj's underlying member method code with example usage: obj.__iter__() without return types