koblas

Top-level

The containers every part of koblas speaks, and the free-function arithmetic over them. The routines themselves live one package down, split by storage: com.eignex.koblas.dense and com.eignex.koblas.sparse. See the README's "BLAS coverage" table for the routine-by-routine mapping to BLAS/LAPACK and the deliberate deviations.

Types

Link copied to clipboard
interface Backend

What every backend reports about itself, whichever half of the seam it implements.

Link copied to clipboard

One replaceable half of a KoblasContext, named so a caller can ask about it.

Link copied to clipboard
@Serializable
@SerialName(value = "DenseMatrix")
class DenseMatrix : MatrixView

Dense column-major matrix backed by a single contiguous DoubleArray of length rows * cols. Element (i, j) lives at data[i + j * rows], so each column is a contiguous run of rows doubles.

Link copied to clipboard
@Serializable
@SerialName(value = "DenseVector")
class DenseVector : VectorView

Dense double-precision vector backed by a flat DoubleArray. The default carrier when the caller already has a dense array or expects most entries to be populated.

Link copied to clipboard
class Givens

A plane rotation: the cosine and sine that rot applies, plus the length it collapsed a pair to.

Link copied to clipboard
class KoblasContext(val vectorKernels: VectorKernels, val blas: Blas, val lapack: Lapack, val sparseVectorKernels: SparseVectorKernels, val sparseBlas: SparseBlas, val sparseLapack: SparseLapack) : LinearAlgebra, Blas, Lapack, SparseLinearAlgebra, SparseBlas, SparseLapack

Every backend koblas will use for a piece of work, in one object you can hold.

Link copied to clipboard
interface MatrixLike

Read-only matrix contract: shape, entry access, materialisation. Anything that only reads a matrix should take this.

Link copied to clipboard
@Serializable
sealed interface MatrixView : MatrixLike

The matrix storages koblas itself defines: DenseMatrix and SparseMatrix, and nothing else ever.

Link copied to clipboard
@Serializable
@SerialName(value = "SparseMatrix")
class SparseMatrix(val rows: Int, val cols: Int, val colPtr: IntArray, val rowIdx: IntArray, val values: DoubleArray) : MatrixView

A sparse matrix in compressed-sparse-column (CSC) form: column j occupies rowIdx[colPtr[j] until colPtr[j + 1]] with the parallel nonzero values in values, row indices strictly ascending within a column — validated by the constructor, since get relies on the ordering. colPtr has length cols + 1 with colPtr[0] == 0 and colPtr[cols] == values.size. CSC is the layout sparse solvers and column-oriented sweeps (matrix–vector products, LU factorization) consume directly — and, since DenseMatrix became column-major, the axis both storages agree is contiguous.

Link copied to clipboard
@Serializable
@SerialName(value = "SparseVector")
class SparseVector : VectorView

Compressed sparse vector: parallel indices/values arrays of equal length, each holding one nonzero entry. Immutable from the caller's perspective; to change the sparsity pattern, rebuild.

Link copied to clipboard
interface VectorLike

Read-only vector contract: length, entry access, materialisation. Anything that only reads a vector should take this.

Link copied to clipboard
@Serializable
sealed interface VectorView : VectorLike

The vector storages koblas itself defines: DenseVector and SparseVector, and nothing else ever.

Link copied to clipboard
class Workspace

Reusable scratch for operations that would otherwise allocate their temporaries on every call.

Properties

Link copied to clipboard

The process-wide default context: an installBackends override when set, else whatever registered itself, else the portable reference implementations.

Link copied to clipboard

What this runtime resolved, for startup logging — e.g. "backend=openblas, kernels=simd(8 lanes)".

Link copied to clipboard

Short human-readable identifier for the vector kernels the current process resolved: "scalar" on any non-JVM target (or a JVM started without --add-modules=jdk.incubator.vector), "simd(4 lanes)" on a JVM with AVX2, "simd(8 lanes)" with AVX-512, and a "+openblas" suffix when a host backend is registered for long runs. Print at startup to verify your runtime picked up what you expected.

Link copied to clipboard
Link copied to clipboard

The slots still running koblas's own portable implementation, in declaration order.

Link copied to clipboard

A failedAt meaning "singular, but this backend cannot say where".

Functions

Link copied to clipboard

Sum of absolute values Sum |v_i| (BLAS dasum). Sparse vectors sum over stored entries only.

Link copied to clipboard
fun axpy(y: DenseVector, alpha: Double, x: VectorLike)

y = y + alpha * x. Dense x uses SIMD; sparse x walks stored entries.

Link copied to clipboard

The backend currently filling slot.

Link copied to clipboard
inline fun <T> Workspace.borrow(size: Int, block: (DoubleArray) -> T): T

Borrows a vector of size for the duration of block, returning it to this afterwards.

Link copied to clipboard
fun copy(src: VectorLike, dst: DenseVector)

dst = src (BLAS dcopy). Dense sources bulk-copy; sparse sources zero-fill then scatter.

Link copied to clipboard
infix fun VectorLike.dot(other: VectorLike): Double

aT * b. Dense×dense routes through the active com.eignex.koblas.dense.VectorKernels; a mixed pair walks the sparse side and gathers from the dense one; anything else is read entry by entry.

Link copied to clipboard
inline fun VectorLike.forEachStored(block: (i: Int, v: Double) -> Unit)

Visit each stored entry of this as (index, value), in ascending index order for any storage. For DenseVector that's every index in 0 until size; for SparseVector that's the entries present in the parallel index/value arrays (which may include numerical zeros); for any other VectorLike it is every index, read through VectorLike.get.

Link copied to clipboard

Matrix-vector product A · x into a fresh dense result (BLAS dgemv with alpha = 1, beta = 0).

Link copied to clipboard
fun ger(alpha: Double, x: VectorLike, y: VectorLike, a: DenseMatrix)

Rank-one update A = A + alpha · x · yᵀ (BLAS dger). Subtract by passing alpha = -1.0.

Link copied to clipboard

Index of the first entry with maximal |v_i| (BLAS idamax), or -1 for a zero-length vector. "First" is by index for either storage: a SparseVector's stored entries are ascending, so its storage order is index order and the two contracts agree. An all-unstored (zero) vector returns index 0, matching the dense zero vector.

Link copied to clipboard

Overrides the context koblas returns, taking precedence over every automatic mechanism — registration and platform discovery alike. Passing null restores automatic selection.

Link copied to clipboard

Whether slot is filled by something other than koblas's own portable implementation.

Link copied to clipboard
fun lapackFailedAt(info: Int): Int

Translates a LAPACK info return into a failedAt position.

Link copied to clipboard

Matrix 1-norm: the maximum absolute column sum (LAPACK dlange with norm 1). This is the anorm input LinearAlgebra.rcond expects, computed on the matrix before factoring, so a solver that estimates conditioning each refactorization calls both.

Link copied to clipboard

Euclidean norm ||v||₂ (BLAS dnrm2). Sparse vectors sum over stored entries only.

Link copied to clipboard

Frobenius norm: sqrt(Sum a_ij²) (LAPACK dlange with norm F).

Link copied to clipboard
fun normInf(a: DenseMatrix, workspace: Workspace? = null): Double

Matrix infinity-norm: the maximum absolute row sum (LAPACK dlange with norm I).

Link copied to clipboard
fun registerBackend(backend: Backend)

Offers backend for automatic selection as every half it implements.

Link copied to clipboard

Throws unless every one of slots is filled by an accelerated backend.

Link copied to clipboard
fun rot(x: DenseVector, y: DenseVector, rotation: Givens)

Apply a plane rotation to a pair of vectors in place (BLAS drot): each (x_i, y_i) becomes (c·x_i + s·y_i, c·y_i − s·x_i).

Link copied to clipboard
fun rotg(a: Double, b: Double): Givens

Generate the plane rotation that zeroes b against a (BLAS drotg).

Link copied to clipboard
fun scale(v: DenseVector, alpha: Double)

v = alpha * v.

Link copied to clipboard

Exchange the contents of a and b (BLAS dswap).

Link copied to clipboard
fun syr(alpha: Double, x: VectorLike, a: DenseMatrix, uplo: Uplo = Uplo.FULL)

Symmetric rank-1 update A += alpha · x · xᵀ (BLAS dsyr); see Blas.syr.

Link copied to clipboard
fun syr2(alpha: Double, x: VectorLike, y: VectorLike, a: DenseMatrix, uplo: Uplo = Uplo.FULL)

Symmetric rank-2 update A += alpha · (x · yᵀ + y · xᵀ) (BLAS dsyr2); see Blas.syr2.

Link copied to clipboard

Fresh transposed matrix Aᵀ. Always materializes; for products against a transposed operand, prefer the transpose flags on LinearAlgebra.gemv / LinearAlgebra.gemm, which read the original storage without copying.

Fresh transposed matrix Aᵀ, still CSC — which makes this the CSC-to-CSR conversion as well.