Repository navigation
[Lane 2 · kotlin-core] Precision/Recall/F1 — extract Accuracy's class-matching helpers into a shared internal file #1225
Description
Sub-issue of #1222 (Precision, Recall and F1Score metrics).
Lane: 2 · Kotlin core (preparatory refactor)
Skill needed: Kotlin. No tensor-internals knowledge needed — everything you move already exists and already has tests.
Size: s (~2–3 h)
Blocked by: nothing. Unblocks #1226.
What to do
Accuracy.kt (skainet-lang/skainet-lang-core/src/commonMain/kotlin/sk/ainet/lang/nn/metrics/Accuracy.kt)
carries, as private members, all the class-matching machinery the three new metrics also
need: argmax, argmaxTarget, insertClassIndex, validateIndexTargetShapes,
validatePredictions, normalizeDim, iterateOverSamples, plus the "hard Int32 targets
vs. soft FP32/FP16 targets" dispatch and the binary-threshold branch in
computeWithIndexTargets / computeWithSoftTargets. Copying that three more times is the
duplication git blame will ask about in six months.
- Create
ClassificationSupport.ktin the same package. Move the helpers there as
internaltop-level functions (or oneinternal object ClassificationSupport). Keep
names and signatures; keep error messages, but make the"Accuracy …"prefixes
metric-agnostic (pass the metric name in, or drop it). - Add one
internalentry point that does the per-sample walk once for both target
kinds and hands(predictedClass, targetClass)pairs to a callback, e.g.
internal inline fun forEachPrediction(predictions, targets, dim, threshold, action: (predicted: Int, target: Int) -> Unit).
Accuracy.updatebecomes a ~5-line call to it that counts matches. This is what
ConfusionMatrixAccumulator([Lane 2 · kotlin-core] Precision/Recall/F1 — Averaging enum + internal ConfusionMatrixAccumulator #1226) will call too. Accuracy's public surface must not change: same constructor, sameaccuracy()/
binaryAccuracy()factories, same behaviour. Run
./gradlew :skainet-lang:skainet-lang-core:apiCheck— the API dump must be unchanged
(everything you add isinternal).- Run the existing tests unchanged:
./gradlew :skainet-backends:skainet-backend-cpu:jvmTest --tests "sk.ainet.exec.metrics.*".
Acceptance
-
Accuracy.ktcontains no argmax / index-walking code of its own -
apiCheckpasses with no dump change -
AccuracyTestpasses unmodified - PR title
refactor(metrics): extract classification helpers from Accuracy (#1222)
Notes
Pure refactor — no new behaviour, so no new tests needed beyond the existing ones passing.
If you find Accuracy has a latent bug while you're in there (for example the
threshold branch reads logit index 1 when classCount == 2 but index 0 when
classCount == 1 — check that this is intended), don't fix it here; open a separate
bug and link it on the parent.
Activity
EdinEd commentedon Oct 20, 2026
Hi @michalharakal , I would like to take on this issue.
michalharakal commentedon Oct 20, 2026
Hi @EdinEd , I've assigned this issue to you. Feel free to start working on it. Thanks for contributing!