code: def _kmeans_single_lloyd(
      X,
      n_clusters,
      max_iter=300,
      init="k-means||",
      verbose=False,
      x_squared_norms=None,
      random_state=None,
      tol=1e-4,
      precompute_distances=True,
      oversampling_factor=2,
      init_max_iter=None,
      n_init="auto",
  ):
      centers = k_init(
          X,
          n_clusters,
          init=init,
          oversampling_factor=oversampling_factor,
          random_state=random_state,
          max_iter=init_max_iter,
          n_init=n_init,
      )
      dt = X.dtype
      P = X.shape[1]
      for i in range(max_iter):
          with _timer("Lloyd loop %2d." % i, _logger=logger):
              labels, distances = pairwise_distances_argmin_min(
                  X,
                  centers,
                  metric="euclidean",
                  metric_kwargs={"squared": True},
              )
              labels = labels.astype(np.int32)
              # distances is always float64, but we need it to match X.dtype
              # for centers_dense, but remain float64 for inertia
              r = blockwise(
                  _centers_dense,
                  "ij",
                  X,
                  "ij",
                  labels,
                  "i",
                  n_clusters,
                  None,
                  "i",
                  adjust_chunks={"i": n_clusters, "j": P},
                  dtype=X.dtype,
              )
              new_centers = da.from_delayed(
                  sum(r.to_delayed().flatten()),
                  (n_clusters, P),
                  X.dtype,
              )
              counts = da.bincount(labels, minlength=n_clusters)
              # Require at least one per bucket, to avoid division by 0.
              counts = da.maximum(counts, 1)
              new_centers = new_centers / counts[:, None]
              (new_centers,) = compute(new_centers)
  
              # Convergence check
              shift = squared_norm(centers - new_centers)
  
              logger.info("Shift: %0.4f", shift)
              if shift < tol:
                  break
              centers = new_centers
  
      if shift > 1e-7:
          labels, distances = pairwise_distances_argmin_min(X, centers)
          labels = labels.astype(np.int32)
  
      inertia = distances.sum()
      centers = centers.astype(dt)
  
      return labels, inertia, centers, i + 1
  
imports: import logging
  from multiprocessing import cpu_count
  from numbers import Integral
  import dask.array
  import dask.dataframe
  import numpy
  import pandas
  import sklearn.cluster
  from dask import compute
  from sklearn.base import BaseEstimator, TransformerMixin
  from sklearn.utils.extmath import squared_norm
  from sklearn.utils.validation import check_is_fitted
  from .._compat import blockwise
  from .._utils import draw_seed
  from ..metrics import euclidean_distances, pairwise_distances, pairwise_distances_argmin_min
  from ..utils import _timed, _timer, check_array, row_norms
  from ._compat import _kmeans_plusplus
  import numba
label_desc: Use image node_id 9 for calling a global function with example usage: _kmeans_single_lloyd(X, n_clusters, max_iter, init, verbose, x_squared_norms, random_state, tol, precompute_distances, oversampling_factor, init_max_iter, n_init) and returns: labels,  inertia,  centers,  unknown