def _mesh_shape_iterator(num_machines, max_mesh_shape_dimensions=None):
    """Iterable of mesh shapes that use a certain number of machines.

  Args:
    num_machines: integer, a power of two, the number of machines available.
    max_mesh_shape_dimensions: optional integer, the maximum number of
        dimensions to consider in any layout.

  Yields:
    [int], the dimension sizes of a mesh shape.
  """
    if num_machines == 1:
        yield [1]
        return
    current_product = num_machines
    mesh_shape = [num_machines]
    while True:
        if max_mesh_shape_dimensions is None or len(mesh_shape
            ) <= max_mesh_shape_dimensions:
            yield list(mesh_shape)
        while mesh_shape[-1] == 2:
            current_product //= mesh_shape.pop()
            if not mesh_shape:
                return
        mesh_shape[-1] //= 2
        current_product //= 2
        while current_product < num_machines:
            mesh_shape.append(min(mesh_shape[-1], num_machines //
                current_product))
            current_product *= mesh_shape[-1]
