You need to add an engine dependency alongside multik-core. The core module only provides types and
interfaces — it does not include an implementation.
Add one of the following:
// Recommended — auto-selects the best engine per platform
implementation("org.jetbrains.kotlinx:multik-default:$multikVersion")
// Pure Kotlin only (all platforms, no native dependencies)
implementation("org.jetbrains.kotlinx:multik-kotlin:$multikVersion")Make sure all Multik artifact versions match.
The JVM artifact bundles native libraries for all desktop platforms (Linux x64, macOS x64/arm64, Windows x64) in a single JAR. Platform-specific artifacts are not yet available.
Workaround: If size is critical, use multik-kotlin instead — it is much smaller and has no native
dependencies.
The pre-built native library in multik-openblas requires glibc 2.35+. Older distributions
(e.g., Ubuntu 20.04) do not have it.
Solutions:
- Upgrade to Ubuntu 22.04+ or equivalent.
- Use
multik-kotlininstead. - Build the native library from source against your system's glibc.
multik-default auto-detects and loads the best engine. You can switch at runtime:
mk.setEngine(KEEngineType) // Pure Kotlin engine
mk.setEngine(NativeEngineType) // OpenBLAS native engineDifferent engines may produce slightly different results for decompositions. For example,
linalg.qrreturns a reduced decomposition with the native engine but a full decomposition with the Kotlin engine. {style="note"}
The native engine (OpenBLAS) is lazily loaded on first use — the library is extracted from the JAR and loaded via JNI. Subsequent calls are fast.
Workarounds:
- Perform a small warm-up call during application startup.
- Use
multik-kotlinif startup latency matters more than computation speed.
Yes. Every Multik module publishes an Android artifact (AAR), so add the same dependencies as on other targets.
- Android artifacts require minSdk 28.
- The native engine ships a library for
arm64-v8aonly. On other ABIs (x86_64emulators,armeabi-v7a),multik-defaultuses the Kotlin engine instead. - Depend on
multik-defaultormultik-openblas, not onmultik-openblas-jvm. The-jvmartifact is built for the desktop JVM: it bundles desktop.sofiles that fail Android builds with"libmultik_jni-linuxX64.so is not an ABI".
multik-kotlin supports JVM, Android, JS, Native, and WASM targets.
multik-openblas is available only on JVM, Android, and desktop Native (Linux x64, macOS arm64, Windows x64).
It is not available on iOS, JS, or WASM.
WASM support is experimental. Some operations (e.g., type casting in the multidimensional case) may throw exceptions. {style="warning"}
reshape returns a view whenever the new shape can be addressed with strides over the existing
data — which includes most slices. Writing to the result writes through to the original array.
Fix: Call .deepCopy() first if you need a standalone array:
val slice = array[0..1, 0..1]
val reshaped = slice.deepCopy().reshape(1, 4) // detached from `array`Multik does not support the generic Number type as an element type. When you mix types like 1.0
(Double) and 2 (Int) in mk[1.0, 2], the compiler infers Number, which compiles but fails at
runtime.
Fix: Ensure all elements use the same type:
mk.ndarray(mk[1.0, 2.0]) // all Double — correct
mk.ndarray(mk[1, 2]) // all Int — correct
// mk.ndarray(mk[1.0, 2]) // Number — runtime error!Computing dot on a row extracted from a 2D array (which is a view) may produce wrong results,
especially with the native engine.
Fix: Copy the slice first:
val row = matrix[0].copy() // explicit copy
val result = row dot vector // now correctmk.ndarray(mk[5]) / 2 yields [2], not [2.5]. Use Double or Float arrays for
fractional results.
No. Multik does not support NumPy-style broadcasting. Array-array operations require both operands to have the same shape.
Workaround: Use .map or create a same-shaped array of the scalar value.
No. Element-wise comparisons that return boolean arrays (like array == 0), boolean indexing
(array[mask]), and np.where(condition, x, y) are not yet supported.
Workaround: Use filter, mapIndexed, or manual iteration:
val a = mk.ndarray(mk[1, 2, 3, 4, 5])
a.filter { it > 3 } // [4, 5]Use mk.linalg.dot(a, b) or the infix syntax a dot b. This handles matrix-matrix, matrix-vector,
and vector-vector products. See dot for details.
*is element-wise multiplication, not matrix multiplication. {style="warning"}
.npy format is supported on JVM and Android. It is not available on Native, JS, or WASM targets.
CSV reading exists but has known issues when parsing complex numbers formatted by NumPy. As a workaround, parse the file manually and construct the complex array in code.