Skip to content

Apple arm64: runtime FEAT_DotProd dispatch for the Q4_K/Q6_K C kernels #958

Description

@michalharakal

Part of the iOS/Apple kernel track of #920 (slice 1 of 3).

The Q4_K and Q6_K C kernels (native/src/q4k_matmul.c, q6k_matmul.c) gate their vdotq_s32 bodies on the compile-time SKAINET_HAVE_DOTPROD (__ARM_FEATURE_DOTPROD), which today comes from the TU-level -march=armv8.2-a+fp16+dotprod set for every aarch64 build. That model cannot ship to iOS:

  • A Kotlin/Native klib embeds one static archive — the Android trick of shipping baseline + v8.2 .so pairs and picking at load time does not translate.
  • Apple A12 (iPhone XS/XR) lacks FEAT_DotProd and is still supported by iOS 18; A13+ and every Apple Silicon Mac have it. Compiling the archive with +dotprod unconditionally would SIGILL supported devices; compiling baseline-only would leave Q4_K/Q6_K — the formats real GGUFs use — on the scalar path everywhere.

Proposal: per-function runtime dispatch, Apple-only, zero effect on Linux:

  1. New skainet_cpu_features.{h,c}: int skainet_cpu_has_dotprod(void) — on __APPLE__ && __aarch64__ a cached sysctlbyname("hw.optional.arm.FEAT_DotProd") probe (key exists since iOS 15/macOS 12; absence → 0 → scalar, always safe); elsewhere a compile-time constant.
  2. skainet_simd.h: SKAINET_DOTPROD_DISPATCH + SKAINET_DOTPROD_TARGET (__attribute__((target("dotprod")))) defined only for Apple arm64 TUs built without __ARM_FEATURE_DOTPROD. Verified against clang: the attribute gates the intrinsic's codegen, and attributed functions are not inlined into baseline callers — the sdot code stays out of the baseline path.
  3. Q4_K/Q6_K: extract the guarded per-block bodies into _dp (attributed) / _generic twins; select once per matmul call via a hoisted use_dp. Granularity is one call per block × output row, so the indirect-call overhead is amortized over the block's arithmetic. On Linux (SKAINET_HAVE_DOTPROD set) the call site stays a direct call that inlines back under -O3 — codegen effectively unchanged.
  4. CMake: aarch64 -march block becomes AND NOT APPLE; Apple builds (including the existing macOS FFM dylib) compile at SDK-default baseline + dispatch. On Apple Silicon the probe returns 1, so the macOS jvmTest CI lane becomes an automatic exerciser of the fast arm.

This is the prerequisite for embedding one universal-per-slice archive into the iosArm64/iosSimulatorArm64/macosArm64 klibs (follow-up issue).

Activity

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