code: def _krylov_factorization(
      A: TallSkinnyMatrix, V0, p, compute_U=False, compute_V=True
  ):
      r"""Computes matrices :math:`U`, :math:`R`, and :math:`V` satisfying the following properties:
      * :math:`U\in\mathbb{R}^{m\times (p+1)b` and :math:`V\in\mathbb{R}^{n\times (p+1)b` are
        orthonormal matrices (:math:`U^TU = I` and :math:`V^TV = I`)
      * :math:`\mathrm{span}(V) = \mathcal{K}_p(A^TA, V_0)`
      * :math:`UR=AV`, hence :math:`\mathrm{span}(U) = \mathcal{K}_p(AA^T, AV_0)`
      * :math:`V[:, :b] = V_0`
      * :math:`R\in\mathbb{R}^{b\times b}` is upper triangular
      where :math:`\mathcal{K}_p(X, Y)` is the block Krylov subspace
      :math:`\mathrm{span}(Y, XY, \dots, X^pY)`.
  
      Parameters
      ----------
      A_expr
      V0
      p
      compute_U
  
      Returns
      -------
  
      """
      t = A.block_table
      A_expr = A.block_expr
  
      g_list = [V0]
      G_i = V0
      k = hl.eval(V0.shape[1])
  
      for j in range(0, p):
          info(f"krylov_factorization: Beginning iteration {j+1}/{p}")
          G_i = t.aggregate(
              hl.agg.ndarray_sum(A_expr.T @ (A_expr @ G_i)),
              _localize=False,
          )
          G_i = hl.nd.qr(G_i)[0]._persist()
          g_list.append(G_i)
  
      info(
          "krylov_factorization: Iterations complete. Computing local QR"
      )
      V0 = hl.nd.hstack(g_list)
  
      if compute_V:
          V = hl.nd.qr(V0)[0]._persist()
          t = t.annotate(AV=A_expr @ V)
      else:
          V = hl.nd.qr(V0)[0]
          t = t.annotate(AV=A_expr @ V)
          V = None
  
      if compute_U:
          temp_file_name = hl.utils.new_temp_file(
              "_krylov_factorization_intermediate", "ht"
          )
          t = t.checkpoint(temp_file_name)
          AV_local = t.aggregate(
              hl.nd.vstack(hl.agg.collect(t.AV)), _localize=False
          )
          U, R = hl.nd.qr(AV_local)._persist()
      else:
          Rs = t.aggregate(
              hl.nd.vstack(hl.agg.collect(hl.nd.qr(t.AV)[1])),
              _localize=False,
          )
          R = hl.nd.qr(Rs)[1]._persist()
          U = None
  
      return KrylovFactorization(U, R, V, k)
  
imports: from typing import List, Tuple
  import hail
  import hail.expr.aggregators
  from hail.expr.expressions import construct_expr
  from hail.expr import expr_float64, expr_call, raise_unless_entry_indexed, matrix_table_source
  from hail import ir
  from hail.table import Table
  from hail.typecheck import typecheck, oneof, nullable
  from hail.utils import FatalError
  from hail.utils.java import Env, info
  from hail.experimental import mt_to_table_of_ndarray
label_desc: Use image node_id 6 for calling a global function with example usage: _krylov_factorization(A, V0, p, compute_U, compute_V) and returns: KrylovFactorization