Batched BiCGSTAB#

gko::batch::solver::Bicgstab<ValueType> is the batched bi-conjugate-gradient stabilised solver. Each batch item runs an independent BiCGSTAB iteration inside its own workgroup, so a batch of \(N\) general (possibly non-symmetric) systems converges in parallel without inter-item synchronisation.

When to use#

Batched BiCGSTAB is the safe default for batches whose items are general: non-symmetric or indefinite. It uses two SpMVs and two preconditioner applies per iteration (about twice the work of CG), so prefer Batched CG when every item in the batch is symmetric positive-definite.

The uniform-batch constraint (same dimensions and sparsity pattern) applies the same way as for CG.

Construction#

namespace b = gko::batch;

auto solver = b::solver::Bicgstab<double>::build()
                  .with_max_iterations(500)
                  .with_tolerance(1e-8)
                  .with_tolerance_type(b::stop::tolerance_type::relative)
                  // optional preconditioner factory:
                  .with_preconditioner(
                      b::preconditioner::Jacobi<double, int>::build().on(exec))
                  .on(exec)
                  ->generate(batched_matrix);

solver->apply(batched_rhs, batched_x);

Factory parameters#

Parameter

Type

Purpose

max_iterations

int

Per-item iteration cap; default 100.

tolerance

double

Stopping threshold on the per-item residual norm; default 1e-11.

tolerance_type

gko::batch::stop::tolerance_type

absolute (default) checks \(\lVert r_k \rVert\); relative checks \(\lVert r_k \rVert / \lVert b \rVert\).

preconditioner

std::shared_ptr<const BatchLinOpFactory>

Preconditioner factory, generated from the batch matrix; the batch identity (gko::batch::matrix::Identity) when unset.

generated_preconditioner

std::shared_ptr<const BatchLinOp>

Pre-built preconditioner; when set it takes precedence over preconditioner.

The same parameter names and defaults apply as for Batched CG; only the algorithm differs.

Stopping rule and breakdown#

BiCGSTAB monitors the implicit residual (the same caveat as CG, see Stopping rule). The algorithm can also break down when the inner \(\omega\) scalar in the stabilisation step gets close to zero; in practice this manifests as a per-item iteration that stalls without reaching the requested tolerance. Run an a-posteriori check on the returned solution if your batch contains near-singular or strongly non-normal items.

Each item in the batch exits the inner loop independently; a converged item is flagged and skipped on subsequent iterations while the others continue.

Per-iteration cost#

BiCGSTAB performs two SpMVs, two preconditioner applies, four dot products, and a handful of AXPY-style updates per iteration. The doubled SpMV / preconditioner cost compared to CG is the price for handling non-symmetric systems with bounded (rather than growing) memory.

The right preconditioning placement (consistent with the single-system Bicgstab) means each preconditioner apply happens before the SpMV that builds the next Krylov direction.

Runtime setters#

BatchSolver exposes reset_tolerance(tol), reset_max_iterations(n) and reset_tolerance_type(t), the same surface as Batched CG. To use a different preconditioner, generate a new solver with with_generated_preconditioner.

Inspecting per-item convergence#

Attach a BatchConvergence logger before apply to retrieve per-item iteration counts and final residual norms after the solve.

See also