Add androidNativeArm32 target support (random-access I/O + eager backend) - #990
michalharakal wants to merge 3 commits into
Conversation
androidNativeArm32's POSIX ssize_t/off_t are Int where every other native target is Long, so its RandomAccessSource can't share native64Main's pread-based implementation without failing Kotlin/Native's metadata compile. Adds Posix32PreadRandomAccessSource (skainet-io-core) as a separate androidNativeArm32-only actual, same contract as the 64-bit one. skainet-io-gguf: adds the androidNativeArm32 target and a matching RandomAccessSourceFactory actual. GgufExportFacade/GGUFWriter (host-side export tooling, depends on skainet-compile-dag which doesn't build for this target either) move from commonMain into a new exportMain source set shared by every other target (jvm/android/native64/js/wasmJs/wasmWasi) so androidNativeArm32 gets tokenizer/GGUF-read support without the export-only dependency it can't resolve. No behavior change for existing targets — verified each one still compiles.
DirectCpuExecutionContext (eager execution) is pure Kotlin — no cinterop kernels in this module (that's skainet-backend-native-cpu, which stays Linux-aarch64-only, a separate concern). skainet-backend-api needed the target + androidNativeArm32Main wired into its native hierarchy; skainet-backend-cpu needed the same plus a platformDefaultCpuOpsFactory actual — identical to the linux one (portable scalar-kernel fallback, no accelerated path yet, same as every other native target without NEON cinterop). Verified every existing target (jvm, android, linux, apple, js, wasmJs, wasmWasi) still compiles.
…net-compile-opt Transitive requirement surfaced by llm-core (SKaiNET-transformers) needing these for OptimizedLLMRuntime's graph tracing/fusion, itself needed by FunctionGemma's eager facade. Pure Kotlin, no cinterop — default hierarchy template wires androidNativeArm32Main automatically, nothing else to do.
|
📖 Documentation Preview The documentation has been built successfully for this PR. Generated Files:
Artifacts:
This comment will be updated automatically when the PR is updated. |
… modules
skainet-io-core, skainet-lang-core, skainet-compile-core, skainet-io-safetensors
and skainet-lang-ksp-annotations already target Android native. The rest of the
chain a device consumer needs does not, so SKaiNET-transformers' gemma-iree fails
to resolve at configuration time:
Could not determine the dependencies of task
':llm-runtime:gemma-iree:compileKotlinAndroidNativeArm32'.
> Could not resolve sk.ainet.core:skainet-compile-dag / -compile-opt /
-io-gguf / -backend-api.
Adds the two targets to skainet-io-gguf, skainet-lang-dag, skainet-compile-dag,
skainet-compile-opt, skainet-backend-api and skainet-backend-cpu.
None of the five hand-declared modules carries posix-typed code, so arm32's
Int-width ssize_t/size_t needs no 64-bit split source set — the reason
skainet-io-core has one does not apply. skainet-backend-api wires the new source
sets onto nativeMain by hand, matching how it declares the rest of its hierarchy.
skainet-backend-cpu opts in through the convention plugin's existing
skainet.targets property and gets a platformDefaultCpuOpsFactory actual. That
actual is a copy of the Linux one rather than a dependsOn(linuxMain): Android
native is Linux-based but bionic, not glibc, and linuxMain is free to grow code
that assumes the latter.
Supersedes most of #990, whose io-core half develop has since landed
independently and whose io-gguf half conflicts with the RandomAccessSourceFactory
consolidation. Its exportMain split is no longer needed either: that existed to
keep export tooling off arm32 because it needs compile-dag, which now has the
target.
Verified: compileKotlinAndroidNativeArm32 and Arm64 green for all six; jvmTest
and repo-wide apiCheck unchanged; and via composite build, transformers'
:llm-runtime:gemma-iree:compileKotlinAndroidNativeArm32 — the task that fails on
SKaiNET-transformers#315 — now succeeds.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YKeDSK4JF295y53Uvez954
|
Superseded by #1239 — recommend closing this one. Checking it against current
What was left is the downstream target list, which #1239 does for all six modules, verified end to end: The diagnosis in this PR's description was right and is what made the smaller change obvious; it is only the implementation that develop has moved past. |
|
Closing in favour of #1239, which merged today and carries what was still needed from here — the androidNative target set across the downstream modules. For anyone finding this later: the diagnosis in the description above was correct and is what made the smaller change obvious. It is only the implementation that develop moved past, in three separate places — the skainet-io-core half landed independently, the RandomAccessSourceFactory consolidation removed the file the io-gguf half wanted to rename, and giving skainet-compile-dag the target made the exportMain split unnecessary. |
Summary
androidNativeArm32as a real target across the dependency chain a downstream consumer (SKaiNET-transformers' eager FunctionGemma port) needs:skainet-io-core,skainet-io-gguf,skainet-lang-dag,skainet-compile-dag,skainet-compile-opt,skainet-backend-api,skainet-backend-cpu.androidNativeArm32's POSIXssize_t/off_tareIntwhere every other native target (includingandroidNativeArm64) isLong— mixing them in one shared native source set fails Kotlin/Native's metadata compile ("numbers with different bit widths"). AddedPosix32PreadRandomAccessSource(skainet-io-core) as a dedicated 32-bit-only actual, same contract as the existing 64-bit one, instead of trying to share it.skainet-io-gguf's host-side export tooling (GgufExportFacade/GGUFWriter, needsskainet-compile-dag) moved fromcommonMaininto a newexportMainsource set shared by every target exceptandroidNativeArm32(model export isn't an on-device concern).skainet-backend-cpu'sDirectCpuExecutionContextis pure Kotlin (no cinterop) — got a portable-fallbackplatformDefaultCpuOpsFactoryactual, identical to the existing Linux one.Test plan
androidNativeArm32target compiles for all 7 touched modules