class_docstr: EM algorithm used to quantize the columns of W to minimize
  
                       ||W - W_hat||^2
  
  Args:
      - W: weight matrix of size (in_features x out_features)
      - n_iter: number of k-means iterations
      - n_centroids: number of centroids (size of codebook)
      - eps: for cluster reassignment when an empty cluster is found
      - max_tentatives for cluster reassignment when an empty cluster is found
      - verbose: print error after each iteration
  
  Remarks:
      - If one cluster is empty, the most populated cluster is split into
        two clusters
      - All the relevant dimensions are specified in the code
docstr: For every centroid m, computes
  
                    ||M - m[None, :]||_2
  
  Remarks:
      - We rely on PyTorch's broadcasting to speed up computations
        and reduce the memory overhead
      - Without chunking, the sizes in the broadcasting are modified as:
        (n_centroids x n_samples x out_features) -> (n_centroids x out_features)
      - The broadcasting computation is automatically chunked so that
        the tensors fit into the memory of the GPU
docstr_tok: ["For","every","centroid","m",",","computes","||M","-","m","[","None",",",":","]","||_2","Remarks",":","-","We","rely","on","PyTorch","'s","broadcasting","to","speed","up","computations","and","reduce","the","memory","overhead","-","Without","chunking",",","the","sizes","in","the","broadcasting","are","modified","as",":","(","n_centroids","x","n_samples","x","out_features",")","-",">","(","n_centroids","x","out_features",")","-","The","broadcasting","computation","is","automatically","chunked","so","that","the","tensors","fit","into","the","memory","of","the","GPU"]
code: def compute_distances(self):
      """
      For every centroid m, computes
  
                        ||M - m[None, :]||_2
  
      Remarks:
          - We rely on PyTorch's broadcasting to speed up computations
            and reduce the memory overhead
          - Without chunking, the sizes in the broadcasting are modified as:
            (n_centroids x n_samples x out_features) -> (n_centroids x out_features)
          - The broadcasting computation is automatically chunked so that
            the tensors fit into the memory of the GPU
      """
  
      nb_centroids_chunks = 1
  
      while True:
          try:
              return torch.cat(
                  [
                      (
                          self.W[None, :, :] - centroids_c[:, :, None]
                      ).norm(p=2, dim=1)
                      for centroids_c in self.centroids.chunk(
                          nb_centroids_chunks, dim=0
                      )
                  ],
                  dim=0,
              )
          except RuntimeError:
              nb_centroids_chunks *= 2
  
file_path: fairseq/fairseq/modules/quantization/pq/em.py
imports: import logging
  import os
  import random
  from collections import Counter
  import torch
label_desc: Use image node_id 5 for calling the EM obj's underlying member method code with example usage: obj.compute_distances() and returns: torch