Skip to content

Make JVM/Java first class citizen with SKaiNET #400

Closed

Description

@michalharakal
No description provided.

Activity

  1. changed the title [-]Make Java first citizen with SKaiNET[/-] [+]Make JVM/Java first class citizen with SKaiNET[/+] on Apr 2, 2026
  2. michalharakal commented on Apr 13, 2026

    @michalharakal
    ContributorAuthor

    Status update for the upcoming 0.19.0 release

    The Java / JVM consumer story has been surveyed against every surface added since 0.18.0. Here's the current state per-surface and what's landing for the release.

    Already Java-accessible from 0.18.0 and earlier

    The `sk.ainet.java.SKaiNET` facade (in `skainet-backend-cpu/jvmMain`) has been there for a while and is correctly annotated with `@JvmStatic` / `@JvmOverloads`:

    • `SKaiNET.context()`
    • `SKaiNET.tensor(ctx, shape, dtype, float[])`, `tensorFromInts(...)`
    • `SKaiNET.zeros(...)`, `ones(...)`, `full(...)`, `randn(...)`
    • Plus `SequentialModelBuilder`, `Optimizers`, `Losses`, `TrainingLoop`, `TensorJavaOps` under the same package

    `skainet-test-java` exercises `SKaiNETTest`, `ModelBuilderTest`, `TensorJavaOpsTest` — all green on develop.

    0.19.0 additions — Java polish in PR #498

    Four small surfaces added this release that needed JVM-interop annotations so Java call sites look idiomatic rather than going through Kotlin's `INSTANCE` marker or synthetic `…Kt` class names. PR #498 lands five commits covering all of them:

    Surface Before After Commit
    `StableHloConverterFactory` `Factory.INSTANCE.createExtended()` `Factory.createExtended()` `25be9dc7` — `@JvmStatic` on all factory methods
    `TokenizerFactory` `Factory.INSTANCE.fromGguf(...)` `Factory.fromGguf(...)` `1ebd21b4` — `@JvmStatic` on `fromGguf` / `fromTokenizerJson`
    `TensorSpecEncoding.kt` top-level extensions `TensorSpecEncodingKt.getTensorEncoding(spec)` `TensorSpecs.getTensorEncoding(spec)` `76cfea29` — `@file:JvmName("TensorSpecs")`
    BOM constraint for `skainet-backend-api` Missing — no pinned version for the neutral module from #470 Listed alongside `skainet-backend-cpu` `1253b42f`

    A new `ReleaseApiJavaTest` in `skainet-test-java` covers all three factories + the encoding helpers from pure Java, so any future regression in the JVM annotations surfaces at compile time in the Java test source set, not at bytecode-verification time in a downstream consumer's project.

    Java consumer shape after 0.19.0

    A Java app pulling in the 0.19.0 BOM can do the full engine flow idiomatically:

    ```java
    import sk.ainet.java.SKaiNET;
    import sk.ainet.compile.hlo.StableHloConverterFactory;
    import sk.ainet.io.tokenizer.TokenizerFactory;
    import sk.ainet.lang.tensor.ops.TensorSpecs;
    import sk.ainet.lang.tensor.storage.TensorEncoding;

    // Execute tensors on CPU
    var ctx = SKaiNET.context();
    var input = SKaiNET.zeros(ctx, new int[]{1, 3, 224, 224}, DType.fp32());

    // Export via StableHLO (new in 0.19.0)
    var converter = StableHloConverterFactory.createExtended();
    var module = converter.convert(graph, "main");

    // Tokenize for Qwen / LLaMA / Gemma / TinyLlama (new in 0.19.0)
    var tokenizer = TokenizerFactory.fromGguf(ggufFields);
    var ids = tokenizer.encode("Hello, world");

    // Read / write TensorEncoding metadata on graph specs (new in 0.19.0)
    var annotated = TensorSpecs.withTensorEncoding(
    spec, TensorEncoding.Q8_0.INSTANCE);
    ```

    What's still Kotlin-only and likely shouldn't be

    For transparency — the following are NOT Java-facing and no work is planned for the 0.19.0 release window:

    • Tensor / model DSL builders — the receiver-scope builder pattern in `NetworkBuilder`, `ContextDsl`, and the transformer DSL in `SKaiNET-transformers` is idiomatic Kotlin that reads painfully from Java. Java consumers currently use `SequentialModelBuilder` as the explicit alternative.
    • Suspend functions (GGUF / SafeTensors streaming readers, async training loop helpers). Java consumers have to go through `kotlinx.coroutines.BuildersKt` / `runBlocking` bridges. Documented in `how-to/java-llm-inference.adoc` on the Antora site.
    • Type parameters `<T : DType, V>` — the tensor type parameter shows up as `Tensor` in every Java call site. Cosmetic — works fine, looks noisy.

    Release checklist delta

    Before cutting the 0.19.0 tag:

    • Merge Polish Java / JVM consumption surface for 0.19.0 (#400) #498 (this update)
    • Re-run `./gradlew :skainet-test:skainet-test-java:test` to confirm `ReleaseApiJavaTest` is green against the merged state
    • Bump `VERSION_NAME` in `gradle.properties` to `0.19.0`
    • Move `[Unreleased]` → `[0.19.0]` in `CHANGELOG.md`, add a "Java / JVM consumption" subsection documenting the four surfaces above

    The issue stays open until 0.19.0 ships; closing it on release is the right moment since this is a release-window milestone, not a forever-open architectural ticket.

  3. added a commit that references this issue on Apr 21, 2026
  4. michalharakal commented on May 9, 2026

    @michalharakal
    ContributorAuthor

    SKaiNET supports JVM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions