Blas
The BLAS entry points, in the shapes the standard gives them.
Named for what it is rather than for who supplies it. Every routine here is one CBLAS call with that call's own arguments, and the package says where an implementation comes from; a caller wanting Koblas's own convenience shapes, array operands and boolean flags, wants com.eignex.koblas.dense.DenseBlas instead.
Operands are the storage types themselves: a DenseMatrixRegion is contiguous column-major with a leading dimension equal to its row count, and a DenseVector is a pointer, a length and an increment. How a call reads an operand, its transpose and its stored triangle, travels beside it as a flag rather than inside it, because those describe the call rather than the storage.
The ABI is fixed: double precision, 32-bit BLAS integers matching Kotlin Int, and the unsuffixed CBLAS symbols that carry it. A library whose integers are 64 bits is a different ABI and is rejected at load rather than producing wrong answers on large inputs.
Instances are immutable and safe to share. Scratch used to reach the library is exclusive to one call, so concurrent calls on one instance do not interfere.
Ownership is the same for every call. An operand borrows its array and does not extend its life: the caller keeps it reachable for the call, nothing is retained afterwards, and no foreign pointer outlives the call that made it. An operand copied into native memory lives in that call's arena and is freed with it, because caching a copy of a mutable array across calls would be a correctness bug rather than an optimization. Two operands may share one array where an operation says so, as the triangular solves do for their in-place destination, and where an operation forbids overlap the call requires it rather than discovering it late. Concurrent readers are fine; a write overlapping another call's access is the caller's to order. Structure is declared rather than inferred, so an entry the structure says is absent is never read and an implicit unit diagonal may hold anything.
Properties
directlyImplemented
The operations this library exports directly.
An operation being listed does not authorize a benchmark case on its own: the same operation can still decline a particular set of operands. routeOf answers for a concrete call; this answers for the layer.
libraryPath
The resolved library file, which is the evidence that a named vendor is the one that ran.
threadEvidence
Whether the one compute thread every call runs on was confirmed against this library.
A library that reported more than one thread after being held to one never became a binding at all, so this distinguishes a library that confirmed the requirement from one that cannot be asked. It is evidence for a report to carry, not a setting: there is nothing to change and no thread count to pass.
vendor
version
Functions
asum
Σ|xᵢ|.
axpy
y = alpha · x + y.
copy
y = x.
dot
xᵀ · y.
gemm
C = alpha · op(A) · op(B) + beta · C, transposing each operand as its flag says.
gemmt
C = alpha · op(A) · op(B) + beta · C in the triangle c's structure selects, leaving the other triangle unread and unwritten.
Direct where the vendor exports it and composed from gemm plus a triangle copy where it does not, so the route of a call says which one ran rather than leaving the name to imply the first.
gemv
y = alpha · op(A) · x + beta · y, transposing a when transposeA.
ger
A = alpha · x · yᵀ + A.
iamax
The index of the entry of largest magnitude, or 0 for an empty vector.
BLAS defines its three reductions to return zero for a non-positive increment rather than to walk the vector backwards, so a negatively strided vector is passed with the increment's magnitude and reaches the same entries in the opposite order. For nrm2 and asum the order does not matter. For this one it decides ties: among entries of equal largest magnitude a forward vector reports the first and a backward one reports the last. That is a real difference from a single-pass forward scan, and it is documented rather than papered over because no vendor flag expresses the forward-scan choice.
nrm2
‖x‖₂, computed by the vendor's own overflow-avoiding method.
rot
routeOf
What a call to operation over these operands would do, each list in the order the operation names them.
Both lists matter, because a route describes one concrete call and not an operation in general. An operation asked about with no operands can only be answered in general terms, and the answer would be wrong for a call that returns without reaching BLAS: a dot over an empty vector does no vendor work, and describing it as a direct vendor call is the attribution error this contract exists to prevent. Passing the operands the call will use is what makes the answer specific to it.
Allocates, so callers resolve it before timing rather than inside a timed call.
scal
x = alpha · x.
A negatively strided vector is passed with the increment's magnitude. BLAS defines scal to return without doing anything for a non-positive increment, so keeping the sign would silently leave the vector unscaled; scaling is order-independent, so walking the same entries forwards gives the same result.
swap
symm
C = alpha · A · B + beta · C for symmetric a, or C = alpha · B · A + beta · C when rightSide.
symv
y = alpha · A · x + beta · y for symmetric a, whose structure selects the stored triangle.
syr
A = alpha · x · xᵀ + A in the triangle structure selects.
syr2
A = alpha · (x · yᵀ + y · xᵀ) + A in the triangle structure selects.
syr2k
C = alpha · (op(A) · op(B)ᵀ + op(B) · op(A)ᵀ) + beta · C in the triangle structure selects.
syrk
C = alpha · op(A) · op(A)ᵀ + beta · C in the triangle structure selects.
trmm
B = alpha · op(A) · B, or B = alpha · B · op(A) when rightSide, for triangular a.
trmv
x = op(A) · x; structure carries the triangle and unit diagonal.
trsm
Solves op(A) · X = alpha · B, or X · op(A) = alpha · B when rightSide, in place over b.
trsv
Solves op(A) · x = b in place; structure carries the triangle and unit diagonal.