Skip to content

Phase A: close Layout property-test gaps, add view-creation benchmark - #114

Merged
Quafadas merged 2 commits into
mainfrom
copilot/layout-follow-ups
Aug 3, 2026
Merged

Phase A: close Layout property-test gaps, add view-creation benchmark#114
Quafadas merged 2 commits into
mainfrom
copilot/layout-follow-ups

Conversation

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Two "(property)" tests in layout.test.scala were single-example assertions rather than generator-driven checks, leaving linearIndex injectivity, in-bounds behavior, and submatrix offset composition untested across the general case. The benchmark suite also had no coverage of view creation (transpose/submatrix) in isolation — every existing benchmark builds matrices in @Setup, so a Layout allocation never shows up as anything but rounding error.

  • Generator-driven Layout tests (vecxt/test/src/layout.test.scala)

    • Hand-rolled generators over small dimension/stride/offset tuples (no scalacheck added to vecxt, per project constraint)
    • linearIndex injectivity: asserts { linearIndex(i, j) } produces exactly numel distinct values for non-broadcast layouts; broadcast (zero-stride) layouts assert the opposite
    • linearIndex in-bounds: every computed index falls in [0, dataLength)
    • Submatrix-of-submatrix offset composition: mirrors MatrixInstance.submatrix's arithmetic (newOffset = offset + rowStart*rowStride + colStart*colStride) and checks it composes correctly across two levels of sub-viewing
    • transpose round-trip generalized from the single hard-coded case to the generated layout set
  • New JMH benchmark (benchmark/src/layoutView.scala)

    • LayoutViewBenchmark measures transpose and submatrix view creation directly, parameterized over matrix size (10/100/1000)

No production code was changed — this is test/benchmark infrastructure only.

Copilot AI linked an issue Aug 3, 2026 that may be closed by this pull request
@Quafadas
Quafadas marked this pull request as ready for review August 3, 2026 10:16
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bytecode audit (Tier 1) — ⚠️ no failures, 1 WARN

JDK 25.0.1 (major 25), OpenJDK 64-Bit Server VM

Vector lanes (DoubleVector.SPECIES_PREFERRED.length()): 8

threshold value provenance
MaxTrivialSize 6 discovered
MaxInlineSize 35 discovered
FreqInlineSize 325 discovered
MaxInlineLevel 15 discovered
InlineSmallCode 2500 discovered
NodeCountInliningCutoff 18000 assumed
HugeMethodLimit 8000 assumed

-XX:HugeMethodLimit= was rejected on the command line: a develop flag compiled out of this product build, so 8000 is taken from the HotSpot source and cannot be confirmed against the running JVM.

metric now baseline delta
cheatsheet methods 97
total bytes 51103 46714 +9.4%
distinct library ops 178 177 +0.6%
bytes per op 287.1 263.9 +8.8%
severity check at method detail
WARN C1 cheatsheet.scala:118 CheatsheetTest$.matrixRangeSlicing 6996 bytes, past 68% of HugeMethodLimit=8000 (assumed)
Annotated methods (47)
method annotations bytes budget used loop at
vecxt.NDArrayFloatOps$.compareGeneral @HotPath 195 60% of 325 yes ndarrayFloatOps.scala:67
vecxt.NDArrayFloatOps$.binaryOpGeneral @HotPath 195 60% of 325 yes ndarrayFloatOps.scala:20
vecxt.NDArrayIntOps$.compareGeneral @HotPath 186 57% of 325 yes ndarrayIntOps.scala:67
vecxt.NDArrayIntOps$.binaryOpGeneral @HotPath 186 57% of 325 yes ndarrayIntOps.scala:19
vecxt.NDArrayDoubleOps$.compareGeneral @HotPath 186 57% of 325 yes ndarrayDoubleOps.scala:74
vecxt.NDArrayDoubleOps$.binaryOpGeneral @HotPath 186 57% of 325 yes ndarrayDoubleOps.scala:24
vecxt.doublearrays$.clamp$bang @AllocFree @HotPath 180 55% of 325 yes doublearrays.scala:817
vecxt.floatarrays$.clamp$bang @AllocFree @HotPath 172 53% of 325 yes floatarrays.scala:379
vecxt.NDArrayFloatOps$.compareScalarGeneral @HotPath 165 51% of 325 yes ndarrayFloatOps.scala:94
vecxt.NDArrayFloatOps$.binaryOpInPlaceGeneral @HotPath 162 50% of 325 yes ndarrayFloatOps.scala:119
vecxt.NDArrayDoubleOps$.compareScalarGeneral @HotPath 157 48% of 325 yes ndarrayDoubleOps.scala:102
vecxt.NDArrayIntOps$.compareScalarGeneral @HotPath 156 48% of 325 yes ndarrayIntOps.scala:94
vecxt.NDArrayIntOps$.binaryOpInPlaceGeneral @HotPath 153 47% of 325 yes ndarrayIntOps.scala:119
vecxt.NDArrayDoubleOps$.binaryOpInPlaceGeneral @HotPath 153 47% of 325 yes ndarrayDoubleOps.scala:131
vecxt.NDArrayIntOps$.unaryOpGeneral @HotPath 152 47% of 325 yes ndarrayIntOps.scala:42
vecxt.NDArrayDoubleOps$.unaryOpGeneral @HotPath 152 47% of 325 yes ndarrayDoubleOps.scala:48
vecxt.doublearrays$.fillLinspace @AllocFree @HotPath 133 41% of 325 yes doublearrays.scala:34
vecxt.intarrays$.dot @AllocFree @HotPath 129 40% of 325 yes intarrays.scala:319
vecxt.intarrays$.increments @HotPath 121 37% of 325 yes intarrays.scala:188
vecxt.ndarray$.mkNDArray @Thin 13 37% of 35 no ndarray.scala:178
vecxt.doublearrays$.increments @HotPath 110 34% of 325 yes doublearrays.scala:359
vecxt.floatarrays$.increments @HotPath 97 30% of 325 yes floatarrays.scala:614
vecxt.doublearrays$.$times$times$bang @HotPath 95 29% of 325 yes doublearrays.scala:334
vecxt.doublearrays$.$minus$eq @AllocFree @HotPath 92 28% of 325 yes doublearrays.scala:1008
vecxt.doublearrays$.$plus$eq @AllocFree @HotPath 90 28% of 325 yes doublearrays.scala:943
vecxt.doublearrays$.$times$eq @AllocFree @HotPath 88 27% of 325 yes doublearrays.scala:1080
vecxt.doublearrays$.productSIMD @AllocFree @HotPath 86 26% of 325 yes doublearrays.scala:645
vecxt.floatarrays$.$times$times$bang @HotPath 85 26% of 325 yes floatarrays.scala:276
vecxt.doublearrays$.sumSIMD @AllocFree @HotPath 85 26% of 325 yes doublearrays.scala:622
vecxt.doublearrays$.fma$bang @AllocFree @HotPath 85 26% of 325 yes doublearrays.scala:983
vecxt.intarrays$.$plus$eq @AllocFree @HotPath 84 26% of 325 yes intarrays.scala:496
vecxt.intarrays$.$minus$eq @AllocFree @HotPath 84 26% of 325 yes intarrays.scala:469
vecxt.floatarrays$.$times$eq @AllocFree @HotPath 84 26% of 325 yes floatarrays.scala:836
vecxt.floatarrays$.$plus$eq @AllocFree @HotPath 84 26% of 325 yes floatarrays.scala:734
vecxt.floatarrays$.$minus$eq @AllocFree @HotPath 84 26% of 325 yes floatarrays.scala:774
vecxt.doublearrays.meanAndVariance @Thin 9 26% of 35 no doublearrays.scala
vecxt.doublearrays$.meanAndVariance @Thin 9 26% of 35 no doublearrays.scala:500
vecxt.intarrays$.minSIMD @AllocFree @HotPath 82 25% of 325 yes intarrays.scala:516
vecxt.intarrays$.maxSIMD @AllocFree @HotPath 82 25% of 325 yes intarrays.scala:536
vecxt.floatarrays$.productSIMD @AllocFree @HotPath 82 25% of 325 yes floatarrays.scala:499
vecxt.intarrays$.sumSIMD @AllocFree @HotPath 81 25% of 325 yes intarrays.scala:233
vecxt.floatarrays$.sumSIMD @AllocFree @HotPath 81 25% of 325 yes floatarrays.scala:478
vecxt.floatarrays$.fma$bang @AllocFree @HotPath 80 25% of 325 yes floatarrays.scala:302
vecxt.floatarrays$.$times$eq @AllocFree @HotPath 78 24% of 325 yes floatarrays.scala:888
vecxt.ndarray.shapeArray @Thin 8 23% of 35 no ndarray.scala
vecxt.intarrays$.$minus$eq @AllocFree @HotPath 67 21% of 325 yes intarrays.scala:351
vecxt.floatarrays$.$plus$eq @AllocFree @HotPath 24 7% of 325 no floatarrays.scala:693
Method sizes
band methods
<= 6 (trivial, always inlined) 1409
7-35 (inlinable cold) 2944
36-325 (inlinable when hot) 597
326-8000 (not inlined) 110
> 8000 (NEVER JIT COMPILED) 0
bytes method module at
6996 CheatsheetTest$.matrixRangeSlicing experiments cheatsheet.scala:118
4480 CheatsheetTest$.matrixReverseSlicing experiments cheatsheet.scala:125
4329 CheatsheetTest$.ndArrayBoolean experiments cheatsheet.scala:430
4126 CheatsheetTest$.ndArrayInt experiments cheatsheet.scala:416
3549 CheatsheetTest$.ndArrayFloat experiments cheatsheet.scala:395
3283 CheatsheetTest$.matrixOps experiments cheatsheet.scala:167
3256 CheatsheetTest$.matrixCreation experiments cheatsheet.scala:72
3167 CheatsheetTest$.ndArrayFloatReductions experiments cheatsheet.scala:405
2500 vecxt_re.Tower.show vecxt_re Tower.scala:63
2042 vecxt.JvmDoubleMatrix$.$plus$eq vecxt doublematrix.scala:315
2028 vecxt.JvmFloatMatrix$.floatmatrixAddScalarInPlace vecxt floatmatrix.scala:442
2028 vecxt.JvmFloatMatrix$.floatmatrixSubScalarInPlace vecxt floatmatrix.scala:514
2023 CheatsheetTest$.arrayMath experiments cheatsheet.scala:253
1921 CheatsheetTest$.indexingAndSlicing experiments cheatsheet.scala:98
1594 vecxt.ndarrayOps$.apply vecxt ndarrayOps.scala:434
1504 vecxt.JvmFloatMatrix$.floatmatrixSubVector vecxt floatmatrix.scala:336
1478 CheatsheetTest$.arrayManipulation experiments cheatsheet.scala:305
1403 vecxt.Svd$.pinv vecxt svd.scala:42
1346 vecxt.JvmDoubleMatrix$.$plus$eq vecxt doublematrix.scala:227
1322 vecxt.JvmFloatMatrix$.floatmatrixAddVectorInPlace vecxt floatmatrix.scala:248
1322 vecxt.JvmFloatMatrix$.floatmatrixSubVectorInPlace vecxt floatmatrix.scala:360
1198 CheatsheetTest$.matrixFloat experiments cheatsheet.scala:445
1102 vecxt.DoubleMatrix$.hadamard vecxt doublematrix.scala:169
1093 CheatsheetTest$.matrixInt experiments cheatsheet.scala:461
990 CheatsheetTest$.logicalOps experiments cheatsheet.scala:280
Proposed baseline
{
  "jdkMajor": 25,
  "c9": { "totalBytes": 51103, "distinctOps": 178 },
  "annotated": {
    "vecxt.NDArrayDoubleOps$.binaryOpGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)Lvecxt/ndarray$NDArray;": 186,
    "vecxt.NDArrayDoubleOps$.binaryOpInPlaceGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)V": 153,
    "vecxt.NDArrayDoubleOps$.compareGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)Lvecxt/ndarray$NDArray;": 186,
    "vecxt.NDArrayDoubleOps$.compareScalarGeneral(Lvecxt/ndarray$NDArray;DLscala/Function2;)Lvecxt/ndarray$NDArray;": 157,
    "vecxt.NDArrayDoubleOps$.unaryOpGeneral(Lvecxt/ndarray$NDArray;Lscala/Function1;)Lvecxt/ndarray$NDArray;": 152,
    "vecxt.NDArrayFloatOps$.binaryOpGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)Lvecxt/ndarray$NDArray;": 195,
    "vecxt.NDArrayFloatOps$.binaryOpInPlaceGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)V": 162,
    "vecxt.NDArrayFloatOps$.compareGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)Lvecxt/ndarray$NDArray;": 195,
    "vecxt.NDArrayFloatOps$.compareScalarGeneral(Lvecxt/ndarray$NDArray;FLscala/Function2;)Lvecxt/ndarray$NDArray;": 165,
    "vecxt.NDArrayIntOps$.binaryOpGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)Lvecxt/ndarray$NDArray;": 186,
    "vecxt.NDArrayIntOps$.binaryOpInPlaceGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)V": 153,
    "vecxt.NDArrayIntOps$.compareGeneral(Lvecxt/ndarray$NDArray;Lvecxt/ndarray$NDArray;Lscala/Function2;)Lvecxt/ndarray$NDArray;": 186,
    "vecxt.NDArrayIntOps$.compareScalarGeneral(Lvecxt/ndarray$NDArray;ILscala/Function2;)Lvecxt/ndarray$NDArray;": 156,
    "vecxt.NDArrayIntOps$.unaryOpGeneral(Lvecxt/ndarray$NDArray;Lscala/Function1;)Lvecxt/ndarray$NDArray;": 152,
    "vecxt.doublearrays$.$minus$eq([DD)V": 92,
    "vecxt.doublearrays$.$plus$eq([DD)V": 90,
    "vecxt.doublearrays$.$times$eq([D[D)V": 88,
    "vecxt.doublearrays$.$times$times$bang([DD)V": 95,
    "vecxt.doublearrays$.clamp$bang([DDD)V": 180,
    "vecxt.doublearrays$.fillLinspace([DDD)V": 133,
    "vecxt.doublearrays$.fma$bang([DDD)V": 85,
    "vecxt.doublearrays$.increments([D)[D": 110,
    "vecxt.doublearrays$.meanAndVariance([D)Lscala/Tuple2;": 9,
    "vecxt.doublearrays$.productSIMD([D)D": 86,
    "vecxt.doublearrays$.sumSIMD([D)D": 85,
    "vecxt.doublearrays.meanAndVariance([DLvecxt/VarianceMode;)Lscala/Tuple2;": 9,
    "vecxt.floatarrays$.$minus$eq([FF)V": 84,
    "vecxt.floatarrays$.$plus$eq([FF)V": 84,
    "vecxt.floatarrays$.$plus$eq([F[F)V": 24,
    "vecxt.floatarrays$.$times$eq([FF)V": 78,
    "vecxt.floatarrays$.$times$eq([F[F)V": 84,
    "vecxt.floatarrays$.$times$times$bang([FF)V": 85,
    "vecxt.floatarrays$.clamp$bang([FFF)V": 172,
    "vecxt.floatarrays$.fma$bang([FFF)V": 80,
    "vecxt.floatarrays$.increments([F)[F": 97,
    "vecxt.floatarrays$.productSIMD([F)F": 82,
    "vecxt.floatarrays$.sumSIMD([F)F": 81,
    "vecxt.intarrays$.$minus$eq([II)V": 67,
    "vecxt.intarrays$.$minus$eq([I[I)V": 84,
    "vecxt.intarrays$.$plus$eq([I[I)V": 84,
    "vecxt.intarrays$.dot([I[I)I": 129,
    "vecxt.intarrays$.increments([I)[I": 121,
    "vecxt.intarrays$.maxSIMD([I)I": 82,
    "vecxt.intarrays$.minSIMD([I)I": 82,
    "vecxt.intarrays$.sumSIMD([I)I": 81,
    "vecxt.ndarray$.mkNDArray(Ljava/lang/Object;[I[II)Lvecxt/ndarray$NDArray;": 13,
    "vecxt.ndarray.shapeArray(Lvecxt/ndarray$NDArray;)[I": 8
  }
}

Co-authored-by: Quafadas <24899792+Quafadas@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement follow-up work for layout extraction Phase A: close Layout property-test gaps, add view-creation benchmark Aug 3, 2026
Copilot AI requested a review from Quafadas August 3, 2026 10:25
@Quafadas
Quafadas merged commit 699435a into main Aug 3, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Layout Follow Ups

2 participants