def METHOD_NAME(psi, src, t):
    t("setup")
    # parameters
    rlen = self.restartlen
    # tensors
    alpha = np.empty((rlen), g.double.complex_dtype)
    # fields
    r, mmpsi = g.copy(src), g.copy(src)
    p = [g.lattice(src) for i in range(rlen + 1)]
    # in QUDA, q is just an "alias" to p with q[k] = p[k+1]
    # don't alias here, but just use slicing
    # initial residual
    r2 = self.calc_res(mat, psi, mmpsi, src, r)
    p[0] @= r
    # source
    ssq = g.norm2(src)
    if ssq == 0.0:
        assert r2 != 0.0  # need either source or psi to not be zero
        ssq = r2
    # target residual
    rsq = self.eps**2.0 * ssq
    for k in range(0, self.maxiter, rlen):
        t("mat")
        for i in range(rlen):
            mat(p[i + 1], p[i])
        t("inner_product")
        ips = g.inner_product(p[1:], p[1:] + [p[0]])  # single reduction
        t("solve")
        rhs = ips[:, -1]  # last column
        A = ips[:, :-1]  # all but last column
        alpha = np.linalg.solve(A, rhs)
        # # check that solution is correct
        # g.message(np.allclose(np.dot(A, alpha), rhs))
        t("update_psi")
        for i in range(rlen):
            g.axpy(psi, alpha[i], p[i], psi)
        if self.maxiter != rlen:
            t("update_residual")
            for i in range(rlen):
                g.axpy(r, -alpha[i], p[i + 1], r)
            t("residual")
            r2 = g.norm2(r)
            t("other")
            self.log_convergence(k, r2, rsq)
        if r2 <= rsq:
            msg = f"converged in {k+rlen} iterations"
            if self.maxiter != rlen:
                msg += f";  computed squared residual {r2:e} / {rsq:e}"
            if self.checkres:
                res = self.calc_res(mat, psi, mmpsi, src, r)
                msg += f";  true squared residual {res:e} / {rsq:e}"
            self.log(msg)
            return
        if self.maxiter != rlen:
            t("restart")
            p[0] @= r
            self.debug("performed restart")
    msg = f"NOT converged in {k+rlen} iterations"
    if self.maxiter != rlen:
        msg += f";  computed squared residual {r2:e} / {rsq:e}"
    if self.checkres:
        res = self.calc_res(mat, psi, mmpsi, src, r)
        msg += f";  true squared residual {res:e} / {rsq:e}"
    self.log(msg)