Blas
The level-2 and level-3 BLAS routines, the seam a native BLAS plugs into.
Everything is over flat, contiguous DenseMatrix.data / DoubleArray buffers, so a native backend passes them across the FFI boundary without repacking. Routines keep their standard mnemonics, and every one of them dispatches: a name here means the standard routine with the standard semantics.
Level-1 kernels (dot, axpy, scale) are deliberately absent. They do nanoseconds of work, so a per-call virtual dispatch would cost more than the kernel; they are specialized at compile time instead, and reach a host BLAS through the VectorKernels half where that pays.
Defaults implement every routine in portable Kotlin, so a backend overrides only what it accelerates.
Inheritors
Properties
Relative preference among simultaneously available backends: automatic selection through registerBackend — JVM classpath discovery, native startup registration — picks the highest per half. The portable reference is 0; native-accelerated backends rank above it (koblas-openblas 100, koblas-cblas 90).
Functions
gemm
In-place matrix-matrix accumulate C = alpha · op(A) · op(B) + beta · C (full BLAS dgemm), where op transposes its operand when transposeA / transposeB is set. Shapes must satisfy op(A): m×k, op(B): k×n, C: m×n. Per BLAS convention, beta == 0.0 overwrites c without reading it, and alpha == 0.0 reduces to the beta scale.
Matrix-matrix product A · B into a fresh matrix (restricted gemm with alpha = 1, beta = 0); A.cols must equal B.rows.
gemv
In-place matrix-vector accumulate y = alpha · op(A) · x + beta · y (full BLAS dgemv), where op(A) is Aᵀ when transpose. Per BLAS convention, beta == 0.0 overwrites y without reading it (it may be uninitialized), and alpha == 0.0 reduces to the beta scale.
Matrix-vector product A · x, or Aᵀ · x when transpose, into a fresh result (restricted gemv with alpha = 1, beta = 0).
ger
Rank-one update A = A + alpha · x · yᵀ (BLAS dger).
The free ger accepts VectorView operands and takes a sparse fast path; this form is the dense one a backend can dispatch.
symm
In-place symmetric matrix-matrix accumulate C = alpha · A · B + beta · C, or C = alpha · B · A + beta · C when right (BLAS dsymm). As with symv, only the triangle of the symmetric a selected by lower is read. Shapes: b and c agree, and a is square with dimension B.rows (left) or B.cols (right). Per BLAS convention, beta == 0.0 overwrites c without reading it, and alpha == 0.0 reduces to the beta scale.
symv
In-place symmetric matrix-vector accumulate y = alpha · A · x + beta · y for a symmetric a (BLAS dsymv). Only the triangle selected by lower (diagonal included) is read; the opposite strict triangle may hold anything. Exploits symmetry for roughly half the memory traffic of gemv. Per BLAS convention, beta == 0.0 overwrites y without reading it, and alpha == 0.0 reduces to the beta scale.
syr
Symmetric rank-1 update A += alpha · x · xᵀ (BLAS dsyr), writing the triangle(s) uplo selects.
The simplest of the three symmetric updates, and the one koblas was missing while shipping the hardest: syrk is the rank-k form. A covariance or precision matrix accumulated one observation at a time is exactly this call.
Exactly symmetric under Uplo.FULL by construction, since each pair (i, j) is computed once and written to both positions — a sweep that filled the two triangles independently would not be, because (alpha·x_i)·x_j and (alpha·x_j)·x_i round differently.
syr2
Symmetric rank-2 update A += alpha · (x · yᵀ + y · xᵀ) (BLAS dsyr2), writing the triangle(s) uplo selects.
Symmetric by the same construction syr uses: the term for a pair is formed once, as alpha·(x_i·y_j + y_i·x_j), and written to both positions.
syr2k
Symmetric rank-2k update C = alpha · (op(A) · op(B)ᵀ + op(B) · op(A)ᵀ) + beta · C (BLAS dsyr2k), where op transposes when transpose.
Completes level 3: syrk, symm, gemm, trsm and trmm were all present and this was not.
Each (i, j) term is the pair of dots A[i]·B[j] + B[i]·A[j], formed once and written to both positions, so the result is exactly symmetric under Uplo.FULL for the reason syr explains.
syrk
In-place symmetric rank-k accumulate C = alpha · A·Aᵀ + beta · C, or alpha · Aᵀ·A + beta · C when transpose (BLAS dsyrk). With the default Uplo.FULL the full symmetric result is produced (the alpha term is applied to both triangles, and beta scales all of c); with Uplo.LOWER / Uplo.UPPER the standard dsyrk semantics apply — only the selected triangle is written and beta-scaled, the opposite strict triangle untouched. c must be square with dimension op(A).rows. Per BLAS convention, beta == 0.0 overwrites without reading (within the written region), and alpha == 0.0 reduces to the beta scale.
trmm
Multiply B = op(T) · B, or B = B · op(T) when right (BLAS dtrmm), the counterpart of trsm.
trmv
Multiply x = op(T) · x in place (BLAS dtrmv), the product counterpart of trsv.
trsm
Solve op(T) · X = B in place, or X · op(T) = B when right (BLAS dtrsm): b holds the right-hand sides on entry and the solutions on return. Flags follow trsv. From the left the right-hand sides are the columns of b; from the right, its rows.
trsv
Solve op(T) · x = b in place (BLAS dtrsv), where T is the lower or upper triangle of the square a, op transposes when transpose, and unitDiag takes the diagonal as 1 without reading it. x holds the right-hand side on entry and the solution on return. Only the selected triangle is read, so the rest of a may hold anything.